273 lines
18 KiB
Swift
273 lines
18 KiB
Swift
//
|
||
// MPPositive_JsonNext.swift
|
||
// MusicPlayer
|
||
//
|
||
// Created by Mr.Zhou on 2024/5/9.
|
||
//
|
||
|
||
import Foundation
|
||
///Next接口,可以获取该首歌曲所在歌单/歌词id/相关内容id
|
||
struct JsonNext: Codable {
|
||
///全部内容
|
||
let contents:Contents?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case contents = "contents"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
contents = try values.decodeIfPresent(Contents.self, forKey: .contents)
|
||
}
|
||
//MARK: - 全部内容
|
||
struct Contents: Codable {
|
||
let singleColumnMusicWatchNextResultsRenderer:SingleColumnMusicWatchNextResultsRenderer?
|
||
enum CodingKeys: String, CodingKey {
|
||
case singleColumnMusicWatchNextResultsRenderer = "singleColumnMusicWatchNextResultsRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
singleColumnMusicWatchNextResultsRenderer = try values.decodeIfPresent(SingleColumnMusicWatchNextResultsRenderer.self, forKey: .singleColumnMusicWatchNextResultsRenderer)
|
||
}
|
||
struct SingleColumnMusicWatchNextResultsRenderer: Codable {
|
||
let tabbedRenderer:TabbedRenderer?
|
||
enum CodingKeys: String, CodingKey {
|
||
case tabbedRenderer = "tabbedRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
tabbedRenderer = try values.decodeIfPresent(TabbedRenderer.self, forKey: .tabbedRenderer)
|
||
}
|
||
struct TabbedRenderer:Codable {
|
||
let watchNextTabbedResultsRenderer:WatchNextTabbedResultsRenderer?
|
||
enum CodingKeys: String, CodingKey {
|
||
case watchNextTabbedResultsRenderer = "watchNextTabbedResultsRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
watchNextTabbedResultsRenderer = try values.decodeIfPresent(WatchNextTabbedResultsRenderer.self, forKey: .watchNextTabbedResultsRenderer)
|
||
}
|
||
//MARK: - 展示内容
|
||
struct WatchNextTabbedResultsRenderer: Codable {
|
||
///由三部分构成-由位数决定,0位是接下来播放(歌单数据)、1位是歌词(未必有,没有的话由相关内容接替)、2位是相关内容
|
||
let tabs:[Tab]?
|
||
enum CodingKeys: String, CodingKey {
|
||
case tabs = "tabs"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs)
|
||
}
|
||
struct Tab: Codable {
|
||
///根据位数不同展示内容不同
|
||
let tabRenderer:TabRenderer?
|
||
enum CodingKeys: String, CodingKey {
|
||
case tabRenderer = "tabRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer)
|
||
}
|
||
struct TabRenderer: Codable {
|
||
///歌单内容
|
||
let content:Content?
|
||
///歌词/相关内容
|
||
let endpoint:Endpoint?
|
||
enum CodingKeys: String, CodingKey {
|
||
case content = "content"
|
||
case endpoint = "endpoint"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
content = try values.decodeIfPresent(Content.self, forKey: .content)
|
||
endpoint = try values.decodeIfPresent(Endpoint.self, forKey: .endpoint)
|
||
}
|
||
///歌单内容
|
||
struct Content: Codable {
|
||
let musicQueueRenderer:MusicQueueRenderer?
|
||
enum CodingKeys: String, CodingKey {
|
||
case musicQueueRenderer = "musicQueueRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
musicQueueRenderer = try values.decodeIfPresent(MusicQueueRenderer.self, forKey: .musicQueueRenderer)
|
||
}
|
||
struct MusicQueueRenderer: Codable {
|
||
let content:Content?
|
||
enum CodingKeys: String, CodingKey {
|
||
case content = "content"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
content = try values.decodeIfPresent(Content.self, forKey: .content)
|
||
}
|
||
struct Content: Codable {
|
||
let playlistPanelRenderer:PlaylistPanelRenderer?
|
||
enum CodingKeys: String, CodingKey {
|
||
case playlistPanelRenderer = "playlistPanelRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
playlistPanelRenderer = try values.decodeIfPresent(PlaylistPanelRenderer.self, forKey: .playlistPanelRenderer)
|
||
}
|
||
struct PlaylistPanelRenderer: Codable {
|
||
let contents:[Content]?
|
||
enum CodingKeys: String, CodingKey {
|
||
case contents = "contents"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
contents = try values.decodeIfPresent([Content].self, forKey: .contents)
|
||
}
|
||
struct Content: Codable {
|
||
let playlistPanelVideoRenderer:PlaylistPanelVideoRenderer?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case playlistPanelVideoRenderer = "playlistPanelVideoRenderer"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
playlistPanelVideoRenderer = try values.decodeIfPresent(PlaylistPanelVideoRenderer.self, forKey: .playlistPanelVideoRenderer)
|
||
}
|
||
struct PlaylistPanelVideoRenderer: Codable {
|
||
///单曲标题
|
||
let title:Title?
|
||
///长文本标题(作者/播放次数/点赞次数)
|
||
let longBylineText:LongBylineText?
|
||
///预览图片
|
||
let thumbnail:Thumbnail?
|
||
///单曲长度文本(分秒)
|
||
let lengthText:LengthText?
|
||
///单曲Id
|
||
let videoId:String?
|
||
///短书名文本(作者)
|
||
let shortBylineText:ShortBylineText?
|
||
enum CodingKeys: String, CodingKey {
|
||
case title = "title"
|
||
case longBylineText = "longBylineText"
|
||
case thumbnail = "thumbnail"
|
||
case lengthText = "lengthText"
|
||
case videoId = "videoId"
|
||
case shortBylineText = "shortBylineText"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
title = try values.decodeIfPresent(Title.self, forKey: .title)
|
||
longBylineText = try values.decodeIfPresent(LongBylineText.self, forKey: .longBylineText)
|
||
thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
|
||
lengthText = try values.decodeIfPresent(LengthText.self, forKey: .lengthText)
|
||
videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
|
||
shortBylineText = try values.decodeIfPresent(ShortBylineText.self, forKey: .shortBylineText)
|
||
}
|
||
|
||
struct Title: Codable {
|
||
let runs:[Run]?
|
||
enum CodingKeys: String, CodingKey {
|
||
case runs = "runs"
|
||
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
runs = try values.decodeIfPresent([Run].self, forKey: .runs)
|
||
}
|
||
}
|
||
struct LongBylineText: Codable {
|
||
let runs:[Run]?
|
||
enum CodingKeys: String, CodingKey {
|
||
case runs = "runs"
|
||
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
runs = try values.decodeIfPresent([Run].self, forKey: .runs)
|
||
}
|
||
}
|
||
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)
|
||
}
|
||
}
|
||
}
|
||
struct LengthText: Codable{
|
||
let runs:[Run]?
|
||
enum CodingKeys: String, CodingKey {
|
||
case runs = "runs"
|
||
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
runs = try values.decodeIfPresent([Run].self, forKey: .runs)
|
||
}
|
||
}
|
||
struct ShortBylineText: Codable {
|
||
let runs:[Run]?
|
||
enum CodingKeys: String, CodingKey {
|
||
case runs = "runs"
|
||
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
runs = try values.decodeIfPresent([Run].self, forKey: .runs)
|
||
}
|
||
}
|
||
///文本内容
|
||
struct Run:Codable {
|
||
let text:String?
|
||
enum CodingKeys: String, CodingKey {
|
||
case text = "text"
|
||
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
text = try values.decodeIfPresent(String.self, forKey: .text)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///歌词/相关内容
|
||
struct Endpoint: Codable {
|
||
let browseEndpoint:BrowseEndpoint?
|
||
enum CodingKeys: String, CodingKey {
|
||
case browseEndpoint = "browseEndpoint"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
|
||
}
|
||
struct BrowseEndpoint: Codable {
|
||
let browseId:String?
|
||
enum CodingKeys: String, CodingKey {
|
||
case browseId = "browseId"
|
||
}
|
||
init(from decoder: Decoder) throws {
|
||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||
browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|