diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift index fccbf1bf4..3fbdb5ae7 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift @@ -917,19 +917,19 @@ private func jsonToString(_ json: [String: Any]) -> String? { // 处理音乐卡片 private func processMusicCard(_ cardMusic: [String: Any]) { let id = cardMusic["id"] as? Int ?? 0 - let url = cardMusic["url"] as? String ?? "" +// let url = cardMusic["url"] as? String ?? "" let title = cardMusic["name"] as? String ?? "" let artist = cardMusic["sgener"] as? String ?? "" let coverUrl = cardMusic["image"] as? String ?? "" - let ts = cardMusic["ts"] as? Int ?? 0 +// let ts = cardMusic["ts"] as? Int ?? 0 processMusicPlay([ "id": id, - "url": url, +// "url": url, "title": title, "artist": artist, "coverUrl": coverUrl, - "ts": ts +// "ts": ts ]) } @@ -939,19 +939,19 @@ private func jsonToString(_ json: [String: Any]) -> String? { for item in musics { let id = item["id"] as? Int ?? 0 - let url = item["url"] as? String ?? "" +// let url = item["url"] as? String ?? "" let title = item["name"] as? String ?? "" let artist = item["sgener"] as? String ?? "" let coverUrl = item["image"] as? String ?? "" - let ts = item["ts"] as? Int ?? 0 +// let ts = item["ts"] as? Int ?? 0 playlist.append([ "id": id, - "url": url, +// "url": url, "title": title, "artist": artist, "coverUrl": coverUrl, - "ts": ts +// "ts": ts ]) } diff --git a/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift b/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift index 79e54376b..3d13dc7a3 100644 --- a/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift +++ b/local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift @@ -144,9 +144,7 @@ public class MusicService: NSObject { "id": songObj["id"] as? Int64, "name": songObj["name"] as? String, "singer": songObj["singer"] as? String, - "url": songObj["url"] as? String, "image": songObj["image"] as? String, - "ts": songObj["ts"] as? Int64 ]) } @@ -154,17 +152,167 @@ public class MusicService: NSObject { } - public func play(song: [String: Any]) { - guard let urlString = song["url"] as? String, let url = URL(string: urlString) else { return } + // MARK: - 获取歌曲URL + public func getSongUrl(id: Int64, completion: @escaping (Result<[String: Any?], Error>) -> Void) { + guard !serviceUrl.isEmpty, let url = URL(string: "\(serviceUrl)/api/home/music_url") else { + completion(.failure(NSError(domain: "MusicService", code: -1, userInfo: [NSLocalizedDescriptionKey: "Service URL is not configured"]))) + return + } + + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.addValue(userToken, forHTTPHeaderField: "Authorization") + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + request.timeoutInterval = 30.0 + + let body: [String: Any] = [ + "id": id + ] + + do { + request.httpBody = try JSONSerialization.data(withJSONObject: body, options: []) + } catch { + completion(.failure(error)) + return + } + + print("发送获取URL请求: id=\(id)") + + let task = URLSession.shared.dataTask(with: request) { data, response, error in + if let error = error { + print("获取URL请求失败: \(error.localizedDescription)") + completion(.failure(error)) + return + } + + guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + let statusCode = (response as? HTTPURLResponse)?.statusCode ?? -1 + print("获取URL失败,HTTP状态码: \(statusCode)") + completion(.failure(NSError(domain: "MusicService", code: statusCode, userInfo: [NSLocalizedDescriptionKey: "获取URL失败,HTTP状态码: \(statusCode)"]))) + return + } + + guard let data = data else { + print("获取URL响应数据为空") + completion(.failure(NSError(domain: "MusicService", code: -2, userInfo: [NSLocalizedDescriptionKey: "响应数据为空"]))) + return + } + + do { + if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { + let urlData = self.parseUrlFromResponse(jsonResponse: jsonResponse) + print("获取URL成功: \(urlData)") + completion(.success(urlData)) + } else { + completion(.failure(NSError(domain: "MusicService", code: -3, userInfo: [NSLocalizedDescriptionKey: "解析JSON响应失败"]))) + } + } catch { + print("解析获取URL响应时发生异常: \(error.localizedDescription)") + completion(.failure(error)) + } + } + + task.resume() + } + + private func parseUrlFromResponse(jsonResponse: [String: Any]) -> [String: Any?] { + var urlData: [String: Any?] = [:] + guard let data = jsonResponse["data"] as? [String: Any] else { + return urlData + } + + urlData["id"] = data["id"] as? Int64 + urlData["url"] = data["url"] as? String + urlData["ts"] = data["ts"] as? Int64 + + return urlData + } + + public func playPlaylist(songs: [[String: Any]]) { + playlist = songs + currentIndex = 0 + if !playlist.isEmpty { + play(song: playlist[currentIndex]) + } + } + + + public func play(song: [String: Any]) { // 获取歌曲ID - if let id = song["id"] as? NSNumber { - currentIdInternal = id.int64Value + let id: Int64 + if let songId = song["id"] as? NSNumber { + id = songId.int64Value + currentIdInternal = id } else { + id = 0 currentIdInternal = 0 } - print("开始播放: \(urlString), ID: \(currentIdInternal ?? 0)") + print("开始播放play id: \(id)") + + // 检查 URL 和时间戳 + let url = song["url"] as? String + let ts = song["ts"] as? Int64 + let currentTime = Int64(Date().timeIntervalSince1970) // 当前时间戳(秒) + + // 判断是否需要重新获取 URL + let needNewUrl = url?.isEmpty != false || ts == nil || ts! <= currentTime + + if needNewUrl { + print("URL 不存在或已过期,重新获取 URL") + // 调用 getSongUrl 获取新的 URL + getSongUrl(id: id) { [weak self] result in + DispatchQueue.main.async { + switch result { + case .success(let urlData): + if let newUrl = urlData["url"] as? String, !newUrl.isEmpty { + // 更新 song 数据 + var updatedSong = song + updatedSong["url"] = newUrl + updatedSong["ts"] = urlData["ts"] ?? 0 + + // 更新 playlist 中对应的歌曲数据 + self?.updatePlaylistSong(songId: id, updatedSong: updatedSong) + + // 使用新 URL 开始播放 + self?.startPlayback(song: updatedSong, url: newUrl) + } else { + print("获取到的 URL 为空") + } + case .failure(let error): + print("获取 URL 失败: \(error.localizedDescription)") + } + } + } + } else { + // URL 有效,直接播放 + startPlayback(song: song, url: url!) + } + } + + // 新增方法:更新 playlist 中指定 ID 的歌曲数据 + private func updatePlaylistSong(songId: Int64, updatedSong: [String: Any]) { + for i in 0..