// // MPPositive_JsonPlayer.swift // MusicPlayer // // Created by Mr.Zhou on 2024/4/30. // import Foundation ///播放器结构体(含有关键资源地址) struct JsonPlayer: Codable { ///资源路径块 let streamingData:StreamingData? ///单曲/视频信息块 let videoDetails:VideoDetails? enum CodingKeys: String, CodingKey { case streamingData = "streamingData" case videoDetails = "videoDetails" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) streamingData = try values.decodeIfPresent(StreamingData.self, forKey: .streamingData) videoDetails = try values.decodeIfPresent(VideoDetails.self, forKey: .videoDetails) } //MARK: - 资源路径(各等级资源) struct StreamingData: Codable { ///允许访问的时间值 let expiresInSeconds:String? ///资源标准格式 let formats:[Format]? ///更多资源格式 let adaptiveFormats:[Format]? enum CodingKeys: String, CodingKey { case expiresInSeconds = "expiresInSeconds" case formats = "formats" case adaptiveFormats = "adaptiveFormats" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) expiresInSeconds = try values.decodeIfPresent(String.self, forKey: .expiresInSeconds) formats = try values.decodeIfPresent([Format].self, forKey: .formats) adaptiveFormats = try values.decodeIfPresent([Format].self, forKey: .adaptiveFormats) } ///资源格式 struct Format: Codable { ///格式标签 let itag: Int? ///格式编码 let mimeType:String? ///格式名 let qualityLabel:String? ///资源地址(双加密) let signatureCipher:String? enum CodingKeys: String, CodingKey { case itag = "itag" case mimeType = "mimeType" case qualityLabel = "qualityLabel" case signatureCipher = "signatureCipher" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) itag = try values.decodeIfPresent(Int.self, forKey: .itag) mimeType = try values.decodeIfPresent(String.self, forKey: .mimeType) qualityLabel = try values.decodeIfPresent(String.self, forKey: .qualityLabel) signatureCipher = try values.decodeIfPresent(String.self, forKey: .signatureCipher) } } } //MARK: - 单曲/视频信息详情 struct VideoDetails: Codable { ///单曲/视频videoId let videoId:String? ///标题 let title:String? ///封面资源 let thumbnail:Thumbnail? ///歌手 let author:String? enum CodingKeys: String, CodingKey { case videoId = "videoId" case title = "title" case thumbnail = "thumbnail" case author = "author" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) videoId = try values.decodeIfPresent(String.self, forKey: .videoId) title = try values.decodeIfPresent(String.self, forKey: .title) thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail) author = try values.decodeIfPresent(String.self, forKey: .author) } ///封面资源 struct Thumbnail: Codable { ///封面库(一般取最后一位,图最大最清晰) let thumbnails:[Thumbnails]? enum CodingKeys: String, CodingKey { case thumbnails = "thumbnails" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails) } struct Thumbnails: Codable { ///封面路径 let url:String? enum CodingKeys: String, CodingKey { case url = "url" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) url = try values.decodeIfPresent(String.self, forKey: .url) } } } } }