Browse Source

上传iOS的qq登陆逻辑

weicu
liwei1dao 1 year ago
parent
commit
6dfb6b56ab
  1. 3
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  2. 5
      local_plugins/agent_service/ios/agent_service/Package.swift
  3. 36
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  4. 12
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift
  5. 6
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift
  6. 4
      local_plugins/chat_api/ios/chat_api/Package.swift
  7. 6
      local_plugins/chat_api/ios/chat_api/Sources/chat_api/MCPClient.swift
  8. 282
      local_plugins/chat_api/ios/chat_api/Sources/chat_api/QQMusicSystemFunctionHandler.swift
  9. 8
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/Info.plist
  10. 0
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/QPlayAutoDefine.h
  11. 187
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/QPlayAutoSDK.h
  12. 188
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/include/QPlayAutoSDK.h
  13. 9
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/module.modulemap
  14. 0
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/libQPlayAutoSDK_arm64.a
  15. 0
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/QPlayAutoDefine.h
  16. 187
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/QPlayAutoSDK.h
  17. 188
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/include/QPlayAutoSDK.h
  18. 9
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/module.modulemap
  19. 0
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/libQPlayAutoSDK_x86_64.a
  20. 238
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/Headers/include/QPlayAutoDefine.h
  21. 188
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/Headers/include/QPlayAutoSDK.h
  22. BIN
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/libQPlayAutoSDK-arm64.a
  23. BIN
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/libQPlayAutoSDK-x86_64.a
  24. BIN
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/libQPlayAutoSDK.a
  25. 8
      local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/module.modulemap
  26. 535
      local_plugins/qq_music/ios/qq_music/Sources/qq_music/QPlayAutoManager.swift
  27. 137
      local_plugins/qq_music/ios/qq_music/Sources/qq_music/QqMusicPlugin.swift
  28. 103
      local_plugins/qq_music/ios/qq_music/Sources/qq_music/include/QPlayAutoDefine.h
  29. 115
      local_plugins/qq_music/ios/qq_music/Sources/qq_music/include/QPlayAutoSDK.h

3
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -830,6 +830,9 @@ object AgentService : CoroutineScope {
if (systemPrompt.isNotEmpty()) {
val mapdata = UserPortrait.getAll().toMutableMap()
mapdata["language"] = language
// 添加当前时间(格式化字符串)
val currentTimeFormatted = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
mapdata["current_time"] = currentTimeFormatted
// Log.d(TAG, "liwei--------- 用户画像: ${mapdata}")
val _systemPrompt = Utils.fillTemplate(systemPrompt, mapdata)
messagesWithSystemPrompt.put(createSystemMessage(_systemPrompt))

5
local_plugins/agent_service/ios/agent_service/Package.swift

@ -16,8 +16,8 @@ let package = Package(
.package(path: "../../../chat_storage/ios/chat_storage"),
.package(path: "../../../location_service/ios/location_service"),
.package(path: "../../../music_service/ios/music_service"),
.package(path: "../../../music_service/ios/user_portrait")
.package(path: "../../../music_service/ios/user_portrait"),
.package(path: "../../../qq_music/ios/qq_music"),
],
targets: [
.target(
@ -32,6 +32,7 @@ let package = Package(
.product(name: "location-service", package: "location_service"),
.product(name: "music-service", package: "music_service"),
.product(name: "user-portrait", package: "user_portrait"),
.product(name: "qq-music", package: "qq_music"),
],
path: "Sources/agent_service",
resources: [

36
local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift

@ -10,6 +10,7 @@ import chat_api
import chat_storage
import music_service
import user_portrait
import qq_music
protocol AgentServiceListener: AnyObject {
func onEvent(eventName: String, data: [String: Any])
@ -497,6 +498,10 @@ audioStream.saveAudioDataTo(data: audioData)
var info = UserPortrait.shared.getAll()
info["language"] = self.language
// Add current time (formatted string)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
info["current_time"] = dateFormatter.string(from: Date())
// 添加调试日志
print("系统提示词模板: \(systemPrompt)")
print("用户画像数据: \(info)")
@ -730,6 +735,8 @@ private func handleJSONDictionary(_ jsonDict: [String: Any], toolName: String) -
processMusicListCard(musics)
} else if let cardNavigation = jsonDict["card_navigation"] as? [String: Any] {
processNavigationCard(cardNavigation)
} else if let cardQQMusiclist = jsonDict["data"] as? [[String: Any]], toolName == "qqmusic_searchandplay_songs" {
processQQMusicPlayList(cardQQMusiclist)
}
let metaStr: String
@ -777,7 +784,31 @@ private func jsonToString(_ json: [String: Any]) -> String? {
return nil
}
}
private func processQQMusicPlayList(_ musics: [[String: Any]]){
// 如果 playlist 中有有效的歌曲,开始播放
if !musics.isEmpty {
// 从songs中提取mid字段构建songMids列表
let songMids = musics.compactMap { song in
song["mid"] as? String
}.filter { !$0.isEmpty }
if !songMids.isEmpty {
// 调用QPlayAutoManager的playSongs方法
QPlayAutoManager.shared.playSongs(mids: songMids, index: 0) { success, errorMessage in
if success {
print("QQ音乐播放列表启动成功,共\(songMids.count)首歌曲")
} else {
print("QQ音乐播放列表启动失败: \(errorMessage ?? "未知错误")")
}
}
} else {
print("音乐列表中没有有效的mid,未启动播放服务")
}
} else {
print("音乐列表为空,未启动播放服务")
}
}
// 处理音乐卡片
private func processMusicCard(_ cardMusic: [String: Any]) {
let id = cardMusic["id"] as? Int ?? 0
@ -831,6 +862,7 @@ private func jsonToString(_ json: [String: Any]) -> String? {
// 实际处理导航逻辑
print("启动导航: 从 \(start) 到 \(end)")
}
// 后台播放单曲
private func processMusicPlay(_ song: [String: Any]) {
sendEvent(name: "music_play", data: song)
@ -843,6 +875,8 @@ private func jsonToString(_ json: [String: Any]) -> String? {
MusicService.shared.playPlaylist(songs: songs)
}
// 添加定位监听
// private func addlocationmonitor(){
// // 通常放在启动后或模块初始化时

12
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureAsrHelper.swift

@ -299,7 +299,7 @@ public class AzureAsrHelper: NSObject {
audioStream?.setAudioConfig(sampleRate: sampleRate, channels: channels)
// 设置录音文件的配置
recordfile?.setAudioConfig(sampleRate: sampleRate, channels: channels)
// recordfile?.setAudioConfig(sampleRate: sampleRate, channels: channels)
print("音频配置设置成功")
return true
@ -720,11 +720,11 @@ public class AzureAsrHelper: NSObject {
)
// 如果已经有推流,重新创建
if pushAudioStream != nil {
let audioStreamFormat = SPXAudioStreamFormat()
audioStreamFormat?.initUsingPCM(withSampleRate: UInt(sampleRate), bitsPerSample: 16, channels: UInt(channels))
pushAudioStream = SPXPushAudioInputStream(audioFormat: audioStreamFormat)
}
// if pushAudioStream != nil {
// let audioStreamFormat = SPXAudioStreamFormat()
// audioStreamFormat?.initUsingPCM(withSampleRate: UInt(sampleRate), bitsPerSample: 16, channels: UInt(channels))
// pushAudioStream = SPXPushAudioInputStream(audioFormat: audioStreamFormat)
// }
print("AudioStream音频配置设置完成")
}

6
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift

@ -272,9 +272,9 @@ import os.log
case "pauseRecord":
azureAsrHelper.pauseRecord()
result(true)
case "resumeRecord":
azureAsrHelper.resumeRecord()
result(true)
// case "resumeRecord":
// azureAsrHelper.resumeRecord()
// result(true)
case "stopRecord":
guard let args = call.arguments as? [String: Any],

4
local_plugins/chat_api/ios/chat_api/Package.swift

@ -16,6 +16,9 @@ let package = Package(
.package(url: "https://github.com/MacPaw/OpenAI.git", from: "0.4.3"),
.package(url: "https://github.com/modelcontextprotocol/swift-sdk.git", from: "0.9.0"),
.package(path: "../../../location_service/ios/location_service"),
.package(path: "../../../qq_music/ios/qq_music"),
],
targets: [
.target(
@ -23,6 +26,7 @@ let package = Package(
dependencies: [
.product(name: "MCP", package: "swift-sdk"),
.product(name: "OpenAI", package: "OpenAI"),
.product(name: "qq-music", package: "qq_music"),
.product(name: "location-service", package: "location_service")
],
exclude: []

6
local_plugins/chat_api/ios/chat_api/Sources/chat_api/MCPClient.swift

@ -434,7 +434,11 @@ public class MCPClient {
do {
let handler = SystemFunctionHandler()
handler.registerAllFunctions(client: self)
} catch {
// 初始化QQ音乐功能
let qqMusicHandler = QQMusicSystemFunctionHandler()
qqMusicHandler.registerAllFunctions(client: self)
} catch {
// 静默处理错误
}
}

282
local_plugins/chat_api/ios/chat_api/Sources/chat_api/QQMusicSystemFunctionHandler.swift

@ -0,0 +1,282 @@
import Foundation
import qq_music
class QQMusicSystemFunctionHandler {
// 添加 registerAllFunctions 方法
func registerAllFunctions(client: MCPClient) {
// 注册QQ音乐搜索和播放功能
client.registerLocalFunction(
name: "qqmusic_searchandplay_songs",
description: "搜索并播放QQ音乐歌曲",
parameters: [
"type": "object",
"properties": [
"keyword": [
"type": "string",
"description": "搜索关键词"
]
],
"required": ["keyword"]
],
handler: QQMusicSearchHandler()
)
// 注册暂停功能
client.registerLocalFunction(
name: "qqmusic_pause",
description: "暂停QQ音乐播放",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicPauseHandler()
)
// 注册恢复播放功能
client.registerLocalFunction(
name: "qqmusic_resume",
description: "恢复QQ音乐播放",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicResumeHandler()
)
// 注册停止功能
client.registerLocalFunction(
name: "qqmusic_stop",
description: "停止QQ音乐播放",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicStopHandler()
)
// 注册下一首功能
client.registerLocalFunction(
name: "qqmusic_next",
description: "播放下一首歌曲",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicNextHandler()
)
// 注册上一首功能
client.registerLocalFunction(
name: "qqmusic_previous",
description: "播放上一首歌曲",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicPreviousHandler()
)
// 注册获取播放状态功能
client.registerLocalFunction(
name: "qqmusic_get_playback_state",
description: "获取QQ音乐播放状态",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicGetPlaybackStateHandler()
)
// 注册获取当前歌曲功能
client.registerLocalFunction(
name: "qqmusic_get_current_song",
description: "获取当前播放的歌曲信息",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicGetCurrentSongHandler()
)
// 注册获取播放时间功能
client.registerLocalFunction(
name: "qqmusic_get_play_time",
description: "获取播放时间信息",
parameters: [
"type": "object",
"properties": [:] as [String: Any],
"required": [] as [String]
],
handler: QQMusicGetPlayTimeHandler()
)
}
}
// MARK: - Private Handler Classes
private class QQMusicSearchHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
guard let keyword = arguments["keyword"] as? String else {
let result: [String: Any] = ["success": false, "error": "Missing keyword parameter"]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
return await withCheckedContinuation { continuation in
// 直接调用QPlayAutoManager的搜索接口
QPlayAutoManager.shared.search(keyword: keyword, searchType: .song) { items in
var result: [String: Any]
if let items = items, !items.isEmpty {
let songs = items.map { item -> [String: Any] in
return [
"mid": item.mid ?? "",
"name": item.name ?? "",
"artist": item.singer?.name ?? "",
"album": item.album ?? "",
"duration": item.duration,
"pic": item.coverUri ?? ""
]
}
result = [
"success": true,
"message": "Found \(items.count) songs and started playing",
"data": songs
]
} else {
result = ["success": false, "error": "No songs found"]
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: result)
let jsonString = String(data: jsonData, encoding: .utf8) ?? "{}"
continuation.resume(returning: jsonString)
} catch {
continuation.resume(returning: "{\"success\": false, \"error\": \"JSON serialization failed\"}")
}
}
}
}
}
private class QQMusicPauseHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
QPlayAutoManager.shared.pause()
let result: [String: Any] = ["success": true, "message": "Music paused"]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicResumeHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
QPlayAutoManager.shared.play()
let result: [String: Any] = ["success": true, "message": "Music resumed"]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicStopHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
QPlayAutoManager.shared.stop()
let result: [String: Any] = ["success": true, "message": "Music stopped"]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicNextHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
QPlayAutoManager.shared.next()
let result: [String: Any] = ["success": true, "message": "Skipped to next song"]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicPreviousHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
QPlayAutoManager.shared.previous()
let result: [String: Any] = ["success": true, "message": "Skipped to previous song"]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicGetPlaybackStateHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
let playState = QPlayAutoManager.shared.currentPlayState
let isConnected = QPlayAutoManager.shared.isConnected
var state = "unknown"
switch playState {
case .playing:
state = "playing"
case .pause:
state = "paused"
case .stop:
state = "stopped"
default:
state = "unknown"
}
let result: [String: Any] = [
"success": true,
"state": state,
"connected": isConnected
]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicGetCurrentSongHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
var result: [String: Any]
if let currentSong = QPlayAutoManager.shared.currentSong {
result = [
"success": true,
"song": [
"id": currentSong.id ?? "",
"name": currentSong.name ?? "",
"artist": currentSong.singer?.name ?? "",
"album": currentSong.album ?? "",
"duration": currentSong.duration
]
]
} else {
result = ["success": false, "error": "No current song"]
}
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}
private class QQMusicGetPlayTimeHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
let currentProgress = QPlayAutoManager.shared.currentProgress
let currentSong = QPlayAutoManager.shared.currentSong
let totalDuration = currentSong?.duration ?? 0
let result: [String: Any] = [
"success": true,
"current_time": currentProgress,
"total_time": totalDuration
]
let jsonData = try JSONSerialization.data(withJSONObject: result)
return String(data: jsonData, encoding: .utf8) ?? "{}"
}
}

8
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/Info.plist

@ -6,13 +6,13 @@
<array>
<dict>
<key>BinaryPath</key>
<string>libQPlayAutoSDK-x86_64.a</string>
<string>libQPlayAutoSDK_x86_64.a</string>
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>ios-x86_64-simulator</string>
<key>LibraryPath</key>
<string>libQPlayAutoSDK-x86_64.a</string>
<string>libQPlayAutoSDK_x86_64.a</string>
<key>SupportedArchitectures</key>
<array>
<string>x86_64</string>
@ -24,13 +24,13 @@
</dict>
<dict>
<key>BinaryPath</key>
<string>libQPlayAutoSDK-arm64.a</string>
<string>libQPlayAutoSDK_arm64.a</string>
<key>HeadersPath</key>
<string>Headers</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libQPlayAutoSDK-arm64.a</string>
<string>libQPlayAutoSDK_arm64.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>

0
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/include/QPlayAutoDefine.h → local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/QPlayAutoDefine.h

187
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/QPlayAutoSDK.h

@ -1,7 +1,188 @@
//
// QPlayAutoSDK.h
// QPlayAutoSDK Umbrella Header
// QPlayAutoSDK
//
// Created by travisli(李鞠佑) on 2018/11/5.
// Copyright © 2018年 腾讯音乐. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "QPlayAutoDefine.h"
#define APP_DEVICE_TYPE (3)
NS_ASSUME_NONNULL_BEGIN
typedef void (^QPlayAutoResultItemsBlock)(NSInteger errorCode,NSArray<QPlayAutoListItem *> *_Nullable items);
typedef void (^QPlayAutoResultParentItemBlock)(NSInteger errorCode,QPlayAutoListItem *parentItem);
extern NSString const * QPlayAutoSDKVersion;
@protocol QPlayAutoSDKDelegate <NSObject>
//连接状态变化回调
- (void)onQPlayAutoConnectStateChanged:(QPlayAutoConnectState)newState;
//播放状态状态变化回调
- (void)onQPlayAutoPlayStateChanged:(QPlayAutoPlayState)playState song:(QPlayAutoListItem *)song position:(NSInteger)position;
//歌曲播放进度
- (void)onQPlayAutoPlayProgressChanged:(QPlayAutoListItem *)song progress:(NSTimeInterval)progress duration:(NSTimeInterval)duration;
//歌曲收藏状态变化
- (void)onSongFavoriteStateChange:(NSString*)songID isFavorite:(BOOL)isFavorite;
//播放状态事件变化
- (void)onPlayModeChange:(QPlayAutoPlayMode)playMode;
//定时关闭事件
- (void)onPlayPausedByTimeoff;
//登陆状态
- (void)onLoginStateDidChanged:(BOOL)isLoginOK;
@end
@interface QPlayAutoSDK : NSObject
/// 注册App
/// @param name 名称
/// @param brand 品牌
/// @param deviceId ?
/// @param scheme 授权成功后Q音跳转合作方的scheme
/// @param appId Q音分配的Id
/// @param secretKey 合作方私钥
/// @param bundleId 合作方包名
+ (void)registerAppWithName:(NSString *)name brand:(NSString *)brand deviceId:(NSString *)deviceId scheme:(NSString *)scheme appId:(NSString *)appId secretKey:(NSString *)secretKey bundleId:(NSString *)bundleId;
/// 播放状态
+ (QPlayAutoPlayMode)currentPlayMode;
/// 当前歌曲
+ (QPlayAutoListItem *_Nullable)currentSong;
/// 当前播放状态
+ (QPlayAutoPlayState)currentPlayState;
/// 当前播放进度
+ (NSTimeInterval)currentProgress;
/// QQ音乐是否登录
+ (BOOL)isLoginOK;
/// 检查QQ音乐是否已安装
+ (BOOL)isQQMusicInstalled;
/// 是否已连接
+ (BOOL)isConnected;
/// 连接中
+ (BOOL)isConnecting;
///QQ音乐设备信息
+ (NSDictionary *)deviceInfo;
+(NSString *)openId;
+(NSString *)openToken;
///是否可以处理回调url
+ (BOOL)canHandleOpenURL:(NSURL *)url;
///处理回调url
+ (BOOL)handleOpenURL:(NSURL *)url;
/// 回调代理
+ (void)setDelegate:(id<QPlayAutoSDKDelegate>) delegate;
/// 拉端连接QPlay
/// - Parameter forceLogin: 是否强制登录
+ (void)connectAndForceLogin:(BOOL)forceLogin;
/// 停止
+ (void)stop;
/// 二次热启动连接(需要联系Q音打开此功能才能使用)
/// - Parameters:
/// - timeout: 超时时间
/// - completion: 回调
+ (void)reconnectWithTimeout:(NSTimeInterval)timeout completion:(QPlayAutoRequestFinishBlock)completion;
/// 跳转QQ音乐登录
/// @param bundleId 合作方bundleId
/// @param callbackUrl 跳转合作方url
+ (BOOL)loginQQMusicWithBundleId:(NSString *)bundleId callbackUrl:(NSString *)callbackUrl;
/// 获取数据
/// @param parent 父
/// @param pageIndex 页码
/// @param pageSize 页大小
/// @param completion 回调
+ (void)getDataItemsFromParent:(QPlayAutoListItem *)parent pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize completion:(QPlayAutoResultParentItemBlock)completion;
/// 设置播放模式
/// @param playMode 播放模式
/// @param block 回调
+ (NSInteger)setPlayMode:(QPlayAutoPlayMode)playMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 设置播放整首还是高潮
/// @param assencceMode 高潮还是整首
/// @param block 回调
+ (NSInteger)setAssenceMode:(QPlayAutoAssenceMode)assencceMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 收藏/取消收藏(歌曲id)
/// @param song 歌曲
/// @param isFavorite 收藏/取消收藏
/// @param completion 回调
+ (void)setFavoriteStateWithSong:(QPlayAutoListItem *)song isFavorite:(BOOL)isFavorite completion:(void (^)(NSInteger errorCode))completion;
/// 播放歌曲
/// @param songList 歌曲列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playAtIndex:(NSArray<QPlayAutoListItem*> *)songList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
/// 通过歌曲Mid列表播放歌曲
/// @param songMidList 歌曲Mid列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playSongMidAtIndex:(NSArray<NSString*> *)songMidList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
///播放下一首
+ (void)playerPlayNextWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放上一首
+ (void)playerPlayPrevWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放暂停
+ (void)playerPlayPause;
///播放恢复
+ (void)playerPlayResumeWithCompletion:(void (^)(NSInteger errorCode))completion;
///Seek到指定位置
+ (void)playerSeek:(NSInteger)position;
/// 搜索歌曲
/// @param keyword 关键词
/// @param type 搜索类型
/// @param firstPage 是否第一页
/// @param completion 回调
+ (NSInteger)search:(NSString *)keyword
type:(QPlayAutoSearchType)type
firstPage:(BOOL)firstPage
completion:(QPlayAutoResultItemsBlock)completion;
/// 相似歌曲
/// @param song 歌曲
/// @param completion 回调
+ (void)requestSimilarWithSong:(QPlayAutoListItem *)song completion:(QPlayAutoResultItemsBlock)completion;
/// 查询歌词
/// @param song 歌曲
/// @param completion 回调
+ (void)requestLyricWithSong:(QPlayAutoListItem *)song completion:(void (^)(NSInteger errorCode,QPlayAutoLyric *_Nullable lyric))completion;
/// 获取特定歌曲列表
/// @param type 列表类型
/// @param completion 回调
+ (void)requestSonglistWithType:(QPlayAutoSongListType)type completion:(QPlayAutoResultItemsBlock)completion;
@end
#import "include/QPlayAutoSDK.h"
#import "include/QPlayAutoDefine.h"
NS_ASSUME_NONNULL_END

188
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/include/QPlayAutoSDK.h

@ -1,188 +0,0 @@
//
// QPlayAutoSDK.h
// QPlayAutoSDK
//
// Created by travisli(李鞠佑) on 2018/11/5.
// Copyright © 2018年 腾讯音乐. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "QPlayAutoDefine.h"
#define APP_DEVICE_TYPE (3)
NS_ASSUME_NONNULL_BEGIN
typedef void (^QPlayAutoResultItemsBlock)(NSInteger errorCode,NSArray<QPlayAutoListItem *> *_Nullable items);
typedef void (^QPlayAutoResultParentItemBlock)(NSInteger errorCode,QPlayAutoListItem *parentItem);
extern NSString const * QPlayAutoSDKVersion;
@protocol QPlayAutoSDKDelegate <NSObject>
//连接状态变化回调
- (void)onQPlayAutoConnectStateChanged:(QPlayAutoConnectState)newState;
//播放状态状态变化回调
- (void)onQPlayAutoPlayStateChanged:(QPlayAutoPlayState)playState song:(QPlayAutoListItem *)song position:(NSInteger)position;
//歌曲播放进度
- (void)onQPlayAutoPlayProgressChanged:(QPlayAutoListItem *)song progress:(NSTimeInterval)progress duration:(NSTimeInterval)duration;
//歌曲收藏状态变化
- (void)onSongFavoriteStateChange:(NSString*)songID isFavorite:(BOOL)isFavorite;
//播放状态事件变化
- (void)onPlayModeChange:(QPlayAutoPlayMode)playMode;
//定时关闭事件
- (void)onPlayPausedByTimeoff;
//登陆状态
- (void)onLoginStateDidChanged:(BOOL)isLoginOK;
@end
@interface QPlayAutoSDK : NSObject
/// 注册App
/// @param name 名称
/// @param brand 品牌
/// @param deviceId ?
/// @param scheme 授权成功后Q音跳转合作方的scheme
/// @param appId Q音分配的Id
/// @param secretKey 合作方私钥
/// @param bundleId 合作方包名
+ (void)registerAppWithName:(NSString *)name brand:(NSString *)brand deviceId:(NSString *)deviceId scheme:(NSString *)scheme appId:(NSString *)appId secretKey:(NSString *)secretKey bundleId:(NSString *)bundleId;
/// 播放状态
+ (QPlayAutoPlayMode)currentPlayMode;
/// 当前歌曲
+ (QPlayAutoListItem *_Nullable)currentSong;
/// 当前播放状态
+ (QPlayAutoPlayState)currentPlayState;
/// 当前播放进度
+ (NSTimeInterval)currentProgress;
/// QQ音乐是否登录
+ (BOOL)isLoginOK;
/// 检查QQ音乐是否已安装
+ (BOOL)isQQMusicInstalled;
/// 是否已连接
+ (BOOL)isConnected;
/// 连接中
+ (BOOL)isConnecting;
///QQ音乐设备信息
+ (NSDictionary *)deviceInfo;
+(NSString *)openId;
+(NSString *)openToken;
///是否可以处理回调url
+ (BOOL)canHandleOpenURL:(NSURL *)url;
///处理回调url
+ (BOOL)handleOpenURL:(NSURL *)url;
/// 回调代理
+ (void)setDelegate:(id<QPlayAutoSDKDelegate>) delegate;
/// 拉端连接QPlay
/// - Parameter forceLogin: 是否强制登录
+ (void)connectAndForceLogin:(BOOL)forceLogin;
/// 停止
+ (void)stop;
/// 二次热启动连接(需要联系Q音打开此功能才能使用)
/// - Parameters:
/// - timeout: 超时时间
/// - completion: 回调
+ (void)reconnectWithTimeout:(NSTimeInterval)timeout completion:(QPlayAutoRequestFinishBlock)completion;
/// 跳转QQ音乐登录
/// @param bundleId 合作方bundleId
/// @param callbackUrl 跳转合作方url
+ (BOOL)loginQQMusicWithBundleId:(NSString *)bundleId callbackUrl:(NSString *)callbackUrl;
/// 获取数据
/// @param parent 父
/// @param pageIndex 页码
/// @param pageSize 页大小
/// @param completion 回调
+ (void)getDataItemsFromParent:(QPlayAutoListItem *)parent pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize completion:(QPlayAutoResultParentItemBlock)completion;
/// 设置播放模式
/// @param playMode 播放模式
/// @param block 回调
+ (NSInteger)setPlayMode:(QPlayAutoPlayMode)playMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 设置播放整首还是高潮
/// @param assencceMode 高潮还是整首
/// @param block 回调
+ (NSInteger)setAssenceMode:(QPlayAutoAssenceMode)assencceMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 收藏/取消收藏(歌曲id)
/// @param song 歌曲
/// @param isFavorite 收藏/取消收藏
/// @param completion 回调
+ (void)setFavoriteStateWithSong:(QPlayAutoListItem *)song isFavorite:(BOOL)isFavorite completion:(void (^)(NSInteger errorCode))completion;
/// 播放歌曲
/// @param songList 歌曲列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playAtIndex:(NSArray<QPlayAutoListItem*> *)songList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
/// 通过歌曲Mid列表播放歌曲
/// @param songMidList 歌曲Mid列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playSongMidAtIndex:(NSArray<NSString*> *)songMidList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
///播放下一首
+ (void)playerPlayNextWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放上一首
+ (void)playerPlayPrevWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放暂停
+ (void)playerPlayPause;
///播放恢复
+ (void)playerPlayResumeWithCompletion:(void (^)(NSInteger errorCode))completion;
///Seek到指定位置
+ (void)playerSeek:(NSInteger)position;
/// 搜索歌曲
/// @param keyword 关键词
/// @param type 搜索类型
/// @param firstPage 是否第一页
/// @param completion 回调
+ (NSInteger)search:(NSString *)keyword
type:(QPlayAutoSearchType)type
firstPage:(BOOL)firstPage
completion:(QPlayAutoResultItemsBlock)completion;
/// 相似歌曲
/// @param song 歌曲
/// @param completion 回调
+ (void)requestSimilarWithSong:(QPlayAutoListItem *)song completion:(QPlayAutoResultItemsBlock)completion;
/// 查询歌词
/// @param song 歌曲
/// @param completion 回调
+ (void)requestLyricWithSong:(QPlayAutoListItem *)song completion:(void (^)(NSInteger errorCode,QPlayAutoLyric *_Nullable lyric))completion;
/// 获取特定歌曲列表
/// @param type 列表类型
/// @param completion 回调
+ (void)requestSonglistWithType:(QPlayAutoSongListType)type completion:(QPlayAutoResultItemsBlock)completion;
@end
NS_ASSUME_NONNULL_END

9
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/Headers/module.modulemap

@ -1,5 +1,8 @@
framework module QPlayAutoSDK {
umbrella header "QPlayAutoSDK.h"
module QPlayAutoSDK {
header "QPlayAutoSDK.h"
header "QPlayAutoDefine.h"
export *
module * { export * }
link "QPlayAutoSDK"
}

0
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/libQPlayAutoSDK-arm64.a → local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-arm64/libQPlayAutoSDK_arm64.a

0
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/include/QPlayAutoDefine.h → local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/QPlayAutoDefine.h

187
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/QPlayAutoSDK.h

@ -1,7 +1,188 @@
//
// QPlayAutoSDK.h
// QPlayAutoSDK Umbrella Header
// QPlayAutoSDK
//
// Created by travisli(李鞠佑) on 2018/11/5.
// Copyright © 2018年 腾讯音乐. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "QPlayAutoDefine.h"
#define APP_DEVICE_TYPE (3)
NS_ASSUME_NONNULL_BEGIN
typedef void (^QPlayAutoResultItemsBlock)(NSInteger errorCode,NSArray<QPlayAutoListItem *> *_Nullable items);
typedef void (^QPlayAutoResultParentItemBlock)(NSInteger errorCode,QPlayAutoListItem *parentItem);
extern NSString const * QPlayAutoSDKVersion;
@protocol QPlayAutoSDKDelegate <NSObject>
//连接状态变化回调
- (void)onQPlayAutoConnectStateChanged:(QPlayAutoConnectState)newState;
//播放状态状态变化回调
- (void)onQPlayAutoPlayStateChanged:(QPlayAutoPlayState)playState song:(QPlayAutoListItem *)song position:(NSInteger)position;
//歌曲播放进度
- (void)onQPlayAutoPlayProgressChanged:(QPlayAutoListItem *)song progress:(NSTimeInterval)progress duration:(NSTimeInterval)duration;
//歌曲收藏状态变化
- (void)onSongFavoriteStateChange:(NSString*)songID isFavorite:(BOOL)isFavorite;
//播放状态事件变化
- (void)onPlayModeChange:(QPlayAutoPlayMode)playMode;
//定时关闭事件
- (void)onPlayPausedByTimeoff;
//登陆状态
- (void)onLoginStateDidChanged:(BOOL)isLoginOK;
@end
@interface QPlayAutoSDK : NSObject
/// 注册App
/// @param name 名称
/// @param brand 品牌
/// @param deviceId ?
/// @param scheme 授权成功后Q音跳转合作方的scheme
/// @param appId Q音分配的Id
/// @param secretKey 合作方私钥
/// @param bundleId 合作方包名
+ (void)registerAppWithName:(NSString *)name brand:(NSString *)brand deviceId:(NSString *)deviceId scheme:(NSString *)scheme appId:(NSString *)appId secretKey:(NSString *)secretKey bundleId:(NSString *)bundleId;
/// 播放状态
+ (QPlayAutoPlayMode)currentPlayMode;
/// 当前歌曲
+ (QPlayAutoListItem *_Nullable)currentSong;
/// 当前播放状态
+ (QPlayAutoPlayState)currentPlayState;
/// 当前播放进度
+ (NSTimeInterval)currentProgress;
/// QQ音乐是否登录
+ (BOOL)isLoginOK;
/// 检查QQ音乐是否已安装
+ (BOOL)isQQMusicInstalled;
/// 是否已连接
+ (BOOL)isConnected;
/// 连接中
+ (BOOL)isConnecting;
///QQ音乐设备信息
+ (NSDictionary *)deviceInfo;
+(NSString *)openId;
+(NSString *)openToken;
///是否可以处理回调url
+ (BOOL)canHandleOpenURL:(NSURL *)url;
///处理回调url
+ (BOOL)handleOpenURL:(NSURL *)url;
/// 回调代理
+ (void)setDelegate:(id<QPlayAutoSDKDelegate>) delegate;
/// 拉端连接QPlay
/// - Parameter forceLogin: 是否强制登录
+ (void)connectAndForceLogin:(BOOL)forceLogin;
/// 停止
+ (void)stop;
/// 二次热启动连接(需要联系Q音打开此功能才能使用)
/// - Parameters:
/// - timeout: 超时时间
/// - completion: 回调
+ (void)reconnectWithTimeout:(NSTimeInterval)timeout completion:(QPlayAutoRequestFinishBlock)completion;
/// 跳转QQ音乐登录
/// @param bundleId 合作方bundleId
/// @param callbackUrl 跳转合作方url
+ (BOOL)loginQQMusicWithBundleId:(NSString *)bundleId callbackUrl:(NSString *)callbackUrl;
/// 获取数据
/// @param parent 父
/// @param pageIndex 页码
/// @param pageSize 页大小
/// @param completion 回调
+ (void)getDataItemsFromParent:(QPlayAutoListItem *)parent pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize completion:(QPlayAutoResultParentItemBlock)completion;
/// 设置播放模式
/// @param playMode 播放模式
/// @param block 回调
+ (NSInteger)setPlayMode:(QPlayAutoPlayMode)playMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 设置播放整首还是高潮
/// @param assencceMode 高潮还是整首
/// @param block 回调
+ (NSInteger)setAssenceMode:(QPlayAutoAssenceMode)assencceMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 收藏/取消收藏(歌曲id)
/// @param song 歌曲
/// @param isFavorite 收藏/取消收藏
/// @param completion 回调
+ (void)setFavoriteStateWithSong:(QPlayAutoListItem *)song isFavorite:(BOOL)isFavorite completion:(void (^)(NSInteger errorCode))completion;
/// 播放歌曲
/// @param songList 歌曲列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playAtIndex:(NSArray<QPlayAutoListItem*> *)songList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
/// 通过歌曲Mid列表播放歌曲
/// @param songMidList 歌曲Mid列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playSongMidAtIndex:(NSArray<NSString*> *)songMidList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
///播放下一首
+ (void)playerPlayNextWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放上一首
+ (void)playerPlayPrevWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放暂停
+ (void)playerPlayPause;
///播放恢复
+ (void)playerPlayResumeWithCompletion:(void (^)(NSInteger errorCode))completion;
///Seek到指定位置
+ (void)playerSeek:(NSInteger)position;
/// 搜索歌曲
/// @param keyword 关键词
/// @param type 搜索类型
/// @param firstPage 是否第一页
/// @param completion 回调
+ (NSInteger)search:(NSString *)keyword
type:(QPlayAutoSearchType)type
firstPage:(BOOL)firstPage
completion:(QPlayAutoResultItemsBlock)completion;
/// 相似歌曲
/// @param song 歌曲
/// @param completion 回调
+ (void)requestSimilarWithSong:(QPlayAutoListItem *)song completion:(QPlayAutoResultItemsBlock)completion;
/// 查询歌词
/// @param song 歌曲
/// @param completion 回调
+ (void)requestLyricWithSong:(QPlayAutoListItem *)song completion:(void (^)(NSInteger errorCode,QPlayAutoLyric *_Nullable lyric))completion;
/// 获取特定歌曲列表
/// @param type 列表类型
/// @param completion 回调
+ (void)requestSonglistWithType:(QPlayAutoSongListType)type completion:(QPlayAutoResultItemsBlock)completion;
@end
#import "include/QPlayAutoSDK.h"
#import "include/QPlayAutoDefine.h"
NS_ASSUME_NONNULL_END

188
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/include/QPlayAutoSDK.h

@ -1,188 +0,0 @@
//
// QPlayAutoSDK.h
// QPlayAutoSDK
//
// Created by travisli(李鞠佑) on 2018/11/5.
// Copyright © 2018年 腾讯音乐. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "QPlayAutoDefine.h"
#define APP_DEVICE_TYPE (3)
NS_ASSUME_NONNULL_BEGIN
typedef void (^QPlayAutoResultItemsBlock)(NSInteger errorCode,NSArray<QPlayAutoListItem *> *_Nullable items);
typedef void (^QPlayAutoResultParentItemBlock)(NSInteger errorCode,QPlayAutoListItem *parentItem);
extern NSString const * QPlayAutoSDKVersion;
@protocol QPlayAutoSDKDelegate <NSObject>
//连接状态变化回调
- (void)onQPlayAutoConnectStateChanged:(QPlayAutoConnectState)newState;
//播放状态状态变化回调
- (void)onQPlayAutoPlayStateChanged:(QPlayAutoPlayState)playState song:(QPlayAutoListItem *)song position:(NSInteger)position;
//歌曲播放进度
- (void)onQPlayAutoPlayProgressChanged:(QPlayAutoListItem *)song progress:(NSTimeInterval)progress duration:(NSTimeInterval)duration;
//歌曲收藏状态变化
- (void)onSongFavoriteStateChange:(NSString*)songID isFavorite:(BOOL)isFavorite;
//播放状态事件变化
- (void)onPlayModeChange:(QPlayAutoPlayMode)playMode;
//定时关闭事件
- (void)onPlayPausedByTimeoff;
//登陆状态
- (void)onLoginStateDidChanged:(BOOL)isLoginOK;
@end
@interface QPlayAutoSDK : NSObject
/// 注册App
/// @param name 名称
/// @param brand 品牌
/// @param deviceId ?
/// @param scheme 授权成功后Q音跳转合作方的scheme
/// @param appId Q音分配的Id
/// @param secretKey 合作方私钥
/// @param bundleId 合作方包名
+ (void)registerAppWithName:(NSString *)name brand:(NSString *)brand deviceId:(NSString *)deviceId scheme:(NSString *)scheme appId:(NSString *)appId secretKey:(NSString *)secretKey bundleId:(NSString *)bundleId;
/// 播放状态
+ (QPlayAutoPlayMode)currentPlayMode;
/// 当前歌曲
+ (QPlayAutoListItem *_Nullable)currentSong;
/// 当前播放状态
+ (QPlayAutoPlayState)currentPlayState;
/// 当前播放进度
+ (NSTimeInterval)currentProgress;
/// QQ音乐是否登录
+ (BOOL)isLoginOK;
/// 检查QQ音乐是否已安装
+ (BOOL)isQQMusicInstalled;
/// 是否已连接
+ (BOOL)isConnected;
/// 连接中
+ (BOOL)isConnecting;
///QQ音乐设备信息
+ (NSDictionary *)deviceInfo;
+(NSString *)openId;
+(NSString *)openToken;
///是否可以处理回调url
+ (BOOL)canHandleOpenURL:(NSURL *)url;
///处理回调url
+ (BOOL)handleOpenURL:(NSURL *)url;
/// 回调代理
+ (void)setDelegate:(id<QPlayAutoSDKDelegate>) delegate;
/// 拉端连接QPlay
/// - Parameter forceLogin: 是否强制登录
+ (void)connectAndForceLogin:(BOOL)forceLogin;
/// 停止
+ (void)stop;
/// 二次热启动连接(需要联系Q音打开此功能才能使用)
/// - Parameters:
/// - timeout: 超时时间
/// - completion: 回调
+ (void)reconnectWithTimeout:(NSTimeInterval)timeout completion:(QPlayAutoRequestFinishBlock)completion;
/// 跳转QQ音乐登录
/// @param bundleId 合作方bundleId
/// @param callbackUrl 跳转合作方url
+ (BOOL)loginQQMusicWithBundleId:(NSString *)bundleId callbackUrl:(NSString *)callbackUrl;
/// 获取数据
/// @param parent 父
/// @param pageIndex 页码
/// @param pageSize 页大小
/// @param completion 回调
+ (void)getDataItemsFromParent:(QPlayAutoListItem *)parent pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize completion:(QPlayAutoResultParentItemBlock)completion;
/// 设置播放模式
/// @param playMode 播放模式
/// @param block 回调
+ (NSInteger)setPlayMode:(QPlayAutoPlayMode)playMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 设置播放整首还是高潮
/// @param assencceMode 高潮还是整首
/// @param block 回调
+ (NSInteger)setAssenceMode:(QPlayAutoAssenceMode)assencceMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 收藏/取消收藏(歌曲id)
/// @param song 歌曲
/// @param isFavorite 收藏/取消收藏
/// @param completion 回调
+ (void)setFavoriteStateWithSong:(QPlayAutoListItem *)song isFavorite:(BOOL)isFavorite completion:(void (^)(NSInteger errorCode))completion;
/// 播放歌曲
/// @param songList 歌曲列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playAtIndex:(NSArray<QPlayAutoListItem*> *)songList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
/// 通过歌曲Mid列表播放歌曲
/// @param songMidList 歌曲Mid列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playSongMidAtIndex:(NSArray<NSString*> *)songMidList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
///播放下一首
+ (void)playerPlayNextWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放上一首
+ (void)playerPlayPrevWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放暂停
+ (void)playerPlayPause;
///播放恢复
+ (void)playerPlayResumeWithCompletion:(void (^)(NSInteger errorCode))completion;
///Seek到指定位置
+ (void)playerSeek:(NSInteger)position;
/// 搜索歌曲
/// @param keyword 关键词
/// @param type 搜索类型
/// @param firstPage 是否第一页
/// @param completion 回调
+ (NSInteger)search:(NSString *)keyword
type:(QPlayAutoSearchType)type
firstPage:(BOOL)firstPage
completion:(QPlayAutoResultItemsBlock)completion;
/// 相似歌曲
/// @param song 歌曲
/// @param completion 回调
+ (void)requestSimilarWithSong:(QPlayAutoListItem *)song completion:(QPlayAutoResultItemsBlock)completion;
/// 查询歌词
/// @param song 歌曲
/// @param completion 回调
+ (void)requestLyricWithSong:(QPlayAutoListItem *)song completion:(void (^)(NSInteger errorCode,QPlayAutoLyric *_Nullable lyric))completion;
/// 获取特定歌曲列表
/// @param type 列表类型
/// @param completion 回调
+ (void)requestSonglistWithType:(QPlayAutoSongListType)type completion:(QPlayAutoResultItemsBlock)completion;
@end
NS_ASSUME_NONNULL_END

9
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/Headers/module.modulemap

@ -1,5 +1,8 @@
framework module QPlayAutoSDK {
umbrella header "QPlayAutoSDK.h"
module QPlayAutoSDK {
header "QPlayAutoSDK.h"
header "QPlayAutoDefine.h"
export *
module * { export * }
link "QPlayAutoSDK"
}

0
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/libQPlayAutoSDK-x86_64.a → local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK.xcframework/ios-x86_64-simulator/libQPlayAutoSDK_x86_64.a

238
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/Headers/include/QPlayAutoDefine.h

@ -1,238 +0,0 @@
//
// QPlayAutoDefine.h
// QPlayAutoSDK
//
// Created by travisli(李鞠佑) on 2018/11/17.
// Copyright © 2018年 腾讯音乐. All rights reserved.
//
#ifndef QPlayAutoDefine_h
#define QPlayAutoDefine_h
extern NSString *const kQPlayAutoItemRootID;
extern NSString *const kQPlayAutoArgument_Count;
extern NSString *const kQPlayAutoArgument_PageIndex;
extern NSString *const kQPlayAutoArgument_ParentID;
extern NSString *const kQPlayAutoArgument_Lists;
extern NSString *const kQPlayAutoArgument_PlayMode;
extern NSString *const kQPlayAutoArgument_IsFav;
extern NSString *const kQPlayAutoArgument_Position;
extern NSString *const kQPlayAutoArgument_Song;
extern NSString *const kQPlayAutoArgument_SongID;
extern NSString *const kQPlayAutoArgument_State;
extern NSString *const kQPlayAutoArgument_Error;
/*
QPlayAuto错误
*/
typedef NS_ENUM(NSUInteger, QPlayAutoError)
{
QPlayAuto_OK=0, //成功
QPlayAuto_QueryAutoFailed=100, //查询车机信息失败
QPlayAuto_QueryMobileFailed=101, //查询移动设备失败
QPlayAuto_QuerySongsFailed_WithoutID=102, //查询歌单数据失败,父 ID 不存在
QPlayAuto_QuerySongsFailed_NoNetwork=103, //查询歌单数据失败,移动设备网络不通,无法下载数据
QPlayAuto_QuerySongsFailed_Unknow=104, //查询歌单数据失败,原因未知
QPlayAuto_SongIDError=105, //歌曲 ID 不存在
QPlayAuto_ReadError=106, //读取数据错误
QPlayAuto_ParamError=107, //参数错误
QPlayAuto_SystemError=108, //系统调用错误
QPlayAuto_CopyRightError=109, //无法播放,没有版权
QPlayAuto_LoginError=110, //无法读取,没有登录
QPlayAuto_PcmRepeat=111, //PCM 请求重复
QPlayAuto_NoPermission=112, //没有权限
QPlayAuto_NeedBuy = 113, //无法播放(数字专辑)
QPlayAuto_NotSupportFormat=114, //无法播放(不支持格式)
QPlayAuto_NeedAuth=115, //需要授权
QPlayAuto_NeedVIP = 116, //无法播放(需要购买VIP)
QPlayAuto_TryListen = 117, //试听歌曲,购买听完整版
QPlayAuto_TrafficAlert = 118, //无法播放(流量弹窗阻断)
QPlayAuto_OnlyWifi = 119, //无法播放(仅Wifi弹窗阻断)
QPlayAuto_AlreadyConnected=120, //已经连接车机
QPlayAuto_SeekError = 121, //拖拽进度错误
QPlayAuto_NoListenRight = 122, //无法播放(无版权)
QPlayAuto_SongNotMatch=123, //歌曲不匹配
QPlayAuto_Disconnect=124, //连接已断开
};
/**
QPlayAuto连接状态
*/
typedef NS_ENUM(NSUInteger, QPlayAutoConnectState)
{
QPlayAutoConnectState_Connected = 0, //连接成功
QPlayAutoConnectState_Disconnect = 1, //断开连接
QPlayAutoConnectState_Failed = -1, //连接失败
QPlayAutoConnectState_Cancel = -2, //连接取消
};
/*
QPlayAutoListItem类型
*/
typedef NS_ENUM(NSUInteger, QPlayAutoListItemType)
{
QPlayAutoListItemType_Song = 1, //歌曲
QPlayAutoListItemType_Normal = 2, //普通目录
QPlayAutoListItemType_Radio = 3, //电台
QPlayAutoListItemType_Folder = 4, //歌单
QPlayAutoListItemType_Album = 5, //专辑
};
typedef NS_ENUM(NSUInteger, QPlayAutoSongListType)
{
QPlayAutoSongListType_Daily = 108, //每日30首
};
/**
QPlayAuto播放状态
*/
typedef NS_ENUM(NSUInteger, QPlayAutoPlayState)
{
QPlayAutoPlayState_Stop=0, //停止
QPlayAutoPlayState_Playing=1, //播放
QPlayAutoPlayState_Pause=2 //暂停
};
typedef NS_ENUM(NSInteger, QPlayAutoAssenceMode)
{
QPlayAutoAssenceMode_Full = 0, // 默认整首播放
QPlayAutoAssenceMode_Part = 1, // 仅播放精华片段
};
/**
QPlayAuto播放模式
*/
typedef NS_ENUM(NSUInteger, QPlayAutoPlayMode)
{
QPlayAutoPlayMode_SequenceCircle=0, //列表循环
QPlayAutoPlayMode_SingleCircle=1, //单曲循环
QPlayAutoPlayMode_RandomCircle=2 //随机播放
};
/**
QPlayAuto搜索类型
*/
typedef NS_ENUM(NSInteger, QPlayAutoSearchType)
{
QPlayAutoSearchType_Song = 0, //歌曲
QPlayAutoSearchType_Album = 2, //专辑
QPlayAutoSearchType_Folder = 3, //歌单
QPlayAutoSearchType_Composite = 100, //综合
};
typedef NS_ENUM(NSInteger, QPlayAutoVipState)
{
QPlayAutoVipState_Normal = 0,
QPlayAutoVipState_VIP = 1,
QPlayAutoVipState_SVIP = 2,
};
/**
第三方App信息
*/
@interface QPlayAutoAppInfo : NSObject<NSCoding>
@property (nonatomic,strong) NSString *deviceId; //AppId
@property (nonatomic,assign) NSInteger deviceType;
@property (nonatomic,strong) NSString *scheme; //跳转scheme
@property (nonatomic,strong) NSString *brand; //品牌
@property (nonatomic,strong) NSString *name; //名称
@property (nonatomic,strong) NSString *appId; //名称
@property (nonatomic,strong) NSString *secretKey; //私钥
@property (nonatomic,strong) NSString *bundleId; //bundleId
@property (nonatomic,assign) NSInteger qmCommandPort; //Q音接收命令端口
@property (nonatomic,strong) NSString *qmHost; //Q音接收命令IP
@property (nonatomic,strong) NSDate *lastConnectDate;//上次连接的日期
@end
@interface QPlayAutoSinger : NSObject
@property (nonatomic,strong) NSString *ID; //ID
@property (nonatomic,strong) NSString *Mid; //Mid
@property (nonatomic,strong) NSString *name; //名称
@end
/*
QPlayAuto列表项(歌单、电台、排行榜、歌曲、etc)
*/
@interface QPlayAutoListItem: NSObject
@property (nonatomic,strong) NSString *ID; //ID
@property (nonatomic,strong) NSString *Name; //名称
@property (nonatomic,strong) NSString *SubName; //副标题
@property (nonatomic,strong) QPlayAutoSinger *singer; //歌手
@property (nonatomic,strong) NSString *Album; //专辑
@property (nonatomic,strong) NSString *Mid;
@property (nonatomic,assign) QPlayAutoVipState vipState;
@property (nonatomic,assign) QPlayAutoListItemType Type;
@property (nonatomic,assign) NSInteger Duration; //时长
@property (nonatomic,strong) NSString *CoverUri; //封面Uri
@property (nonatomic,assign) NSInteger totalCount; //总数
@property (nonatomic,assign) BOOL isFav; //是否收藏
@property (nonatomic,assign) BOOL isOrigin; //是否原唱
@property (nonatomic,assign) BOOL isNoAudioSource; //无音源
@property (nonatomic,strong) NSMutableArray<QPlayAutoListItem*> *items; //子列表
@property (nonatomic,weak) QPlayAutoListItem *parentItem; //父节点
@property (nonatomic,assign) BOOL isTryListen; //是否试听歌曲
@property (nonatomic,readonly) BOOL isSong; //歌曲
@property (nonatomic,readonly) BOOL isFolder;//歌单
@property (nonatomic,readonly) BOOL isAlbum; //专辑
@property (nonatomic,readonly) BOOL isRadio; //电台
@property (nonatomic,readonly) BOOL isDirectory; //普通目录
@property (nonatomic,readonly) BOOL isVIP; //VIP歌曲
@property (nonatomic,readonly) BOOL isSVIP; //SVIP歌曲
- (instancetype)initWithDictionary:(NSDictionary*)dict;
- (instancetype)initSongWithId:(NSString *)identifier isFav:(BOOL)isFav;
- (instancetype)initWithId:(NSString *)identifier type:(QPlayAutoListItemType)type;
//是否是根节点
- (BOOL)isRoot;
//是否有更多
- (BOOL)hasMore;
- (QPlayAutoListItem*)findItemWithID:(NSString*)ID;
@end
/**
QPlayAuto请求回调
@param success 是否成功
@param dict 结果Dictionary
*/
typedef void (^QPlayAutoRequestFinishBlock)(BOOL success, NSDictionary *dict);
@interface QPlayAutoRequestBase : NSObject
/** 请求类型 */
@property (nonatomic, assign) int type;
@end
@interface QPlayAutoSentence : NSObject <NSCoding>
@property (nonatomic, assign) NSInteger startTime;
@property (nonatomic, assign) NSInteger duration;
@property (nonatomic, strong) NSString *text;
@property (nonatomic, readonly) NSString *startTimeText;
@property (nonatomic, readonly) NSString *endTimeText;
@end
@interface QPlayAutoLyric : NSObject <NSCoding>
@property(nonatomic,assign) BOOL isTxtType;//歌词是不是纯文本的歌词,没有时间标记
@property(nonatomic,strong) NSString *songId;
@property(nonatomic,strong) NSString *songName;
@property(nonatomic,strong) NSString *singerName;
@property(nonatomic,strong) NSString *albumName;
@property(nonatomic,readonly) NSString *text;//所有歌词文本
@property(nonatomic,strong) NSArray<QPlayAutoSentence *> *sentences;
- (NSString *)sentenceAtTime:(NSTimeInterval)time;
@end
#endif /* QPlayAutoDefine_h */

188
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/Headers/include/QPlayAutoSDK.h

@ -1,188 +0,0 @@
//
// QPlayAutoSDK.h
// QPlayAutoSDK
//
// Created by travisli(李鞠佑) on 2018/11/5.
// Copyright © 2018年 腾讯音乐. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "QPlayAutoDefine.h"
#define APP_DEVICE_TYPE (3)
NS_ASSUME_NONNULL_BEGIN
typedef void (^QPlayAutoResultItemsBlock)(NSInteger errorCode,NSArray<QPlayAutoListItem *> *_Nullable items);
typedef void (^QPlayAutoResultParentItemBlock)(NSInteger errorCode,QPlayAutoListItem *parentItem);
extern NSString const * QPlayAutoSDKVersion;
@protocol QPlayAutoSDKDelegate <NSObject>
//连接状态变化回调
- (void)onQPlayAutoConnectStateChanged:(QPlayAutoConnectState)newState;
//播放状态状态变化回调
- (void)onQPlayAutoPlayStateChanged:(QPlayAutoPlayState)playState song:(QPlayAutoListItem *)song position:(NSInteger)position;
//歌曲播放进度
- (void)onQPlayAutoPlayProgressChanged:(QPlayAutoListItem *)song progress:(NSTimeInterval)progress duration:(NSTimeInterval)duration;
//歌曲收藏状态变化
- (void)onSongFavoriteStateChange:(NSString*)songID isFavorite:(BOOL)isFavorite;
//播放状态事件变化
- (void)onPlayModeChange:(QPlayAutoPlayMode)playMode;
//定时关闭事件
- (void)onPlayPausedByTimeoff;
//登陆状态
- (void)onLoginStateDidChanged:(BOOL)isLoginOK;
@end
@interface QPlayAutoSDK : NSObject
/// 注册App
/// @param name 名称
/// @param brand 品牌
/// @param deviceId ?
/// @param scheme 授权成功后Q音跳转合作方的scheme
/// @param appId Q音分配的Id
/// @param secretKey 合作方私钥
/// @param bundleId 合作方包名
+ (void)registerAppWithName:(NSString *)name brand:(NSString *)brand deviceId:(NSString *)deviceId scheme:(NSString *)scheme appId:(NSString *)appId secretKey:(NSString *)secretKey bundleId:(NSString *)bundleId;
/// 播放状态
+ (QPlayAutoPlayMode)currentPlayMode;
/// 当前歌曲
+ (QPlayAutoListItem *_Nullable)currentSong;
/// 当前播放状态
+ (QPlayAutoPlayState)currentPlayState;
/// 当前播放进度
+ (NSTimeInterval)currentProgress;
/// QQ音乐是否登录
+ (BOOL)isLoginOK;
/// 检查QQ音乐是否已安装
+ (BOOL)isQQMusicInstalled;
/// 是否已连接
+ (BOOL)isConnected;
/// 连接中
+ (BOOL)isConnecting;
///QQ音乐设备信息
+ (NSDictionary *)deviceInfo;
+(NSString *)openId;
+(NSString *)openToken;
///是否可以处理回调url
+ (BOOL)canHandleOpenURL:(NSURL *)url;
///处理回调url
+ (BOOL)handleOpenURL:(NSURL *)url;
/// 回调代理
+ (void)setDelegate:(id<QPlayAutoSDKDelegate>) delegate;
/// 拉端连接QPlay
/// - Parameter forceLogin: 是否强制登录
+ (void)connectAndForceLogin:(BOOL)forceLogin;
/// 停止
+ (void)stop;
/// 二次热启动连接(需要联系Q音打开此功能才能使用)
/// - Parameters:
/// - timeout: 超时时间
/// - completion: 回调
+ (void)reconnectWithTimeout:(NSTimeInterval)timeout completion:(QPlayAutoRequestFinishBlock)completion;
/// 跳转QQ音乐登录
/// @param bundleId 合作方bundleId
/// @param callbackUrl 跳转合作方url
+ (BOOL)loginQQMusicWithBundleId:(NSString *)bundleId callbackUrl:(NSString *)callbackUrl;
/// 获取数据
/// @param parent 父
/// @param pageIndex 页码
/// @param pageSize 页大小
/// @param completion 回调
+ (void)getDataItemsFromParent:(QPlayAutoListItem *)parent pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize completion:(QPlayAutoResultParentItemBlock)completion;
/// 设置播放模式
/// @param playMode 播放模式
/// @param block 回调
+ (NSInteger)setPlayMode:(QPlayAutoPlayMode)playMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 设置播放整首还是高潮
/// @param assencceMode 高潮还是整首
/// @param block 回调
+ (NSInteger)setAssenceMode:(QPlayAutoAssenceMode)assencceMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 收藏/取消收藏(歌曲id)
/// @param song 歌曲
/// @param isFavorite 收藏/取消收藏
/// @param completion 回调
+ (void)setFavoriteStateWithSong:(QPlayAutoListItem *)song isFavorite:(BOOL)isFavorite completion:(void (^)(NSInteger errorCode))completion;
/// 播放歌曲
/// @param songList 歌曲列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playAtIndex:(NSArray<QPlayAutoListItem*> *)songList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
/// 通过歌曲Mid列表播放歌曲
/// @param songMidList 歌曲Mid列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playSongMidAtIndex:(NSArray<NSString*> *)songMidList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
///播放下一首
+ (void)playerPlayNextWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放上一首
+ (void)playerPlayPrevWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放暂停
+ (void)playerPlayPause;
///播放恢复
+ (void)playerPlayResumeWithCompletion:(void (^)(NSInteger errorCode))completion;
///Seek到指定位置
+ (void)playerSeek:(NSInteger)position;
/// 搜索歌曲
/// @param keyword 关键词
/// @param type 搜索类型
/// @param firstPage 是否第一页
/// @param completion 回调
+ (NSInteger)search:(NSString *)keyword
type:(QPlayAutoSearchType)type
firstPage:(BOOL)firstPage
completion:(QPlayAutoResultItemsBlock)completion;
/// 相似歌曲
/// @param song 歌曲
/// @param completion 回调
+ (void)requestSimilarWithSong:(QPlayAutoListItem *)song completion:(QPlayAutoResultItemsBlock)completion;
/// 查询歌词
/// @param song 歌曲
/// @param completion 回调
+ (void)requestLyricWithSong:(QPlayAutoListItem *)song completion:(void (^)(NSInteger errorCode,QPlayAutoLyric *_Nullable lyric))completion;
/// 获取特定歌曲列表
/// @param type 列表类型
/// @param completion 回调
+ (void)requestSonglistWithType:(QPlayAutoSongListType)type completion:(QPlayAutoResultItemsBlock)completion;
@end
NS_ASSUME_NONNULL_END

BIN
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/libQPlayAutoSDK-arm64.a

Binary file not shown.

BIN
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/libQPlayAutoSDK-x86_64.a

Binary file not shown.

BIN
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/libQPlayAutoSDK.a

Binary file not shown.

8
local_plugins/qq_music/ios/qq_music/Frameworks/QPlayAutoSDK/module.modulemap

@ -1,8 +0,0 @@
module QPlayAutoSDK {
header "Headers/include/QPlayAutoSDK.h"
header "Headers/include/QPlayAutoDefine.h"
export *
link "QPlayAutoSDK"
}

535
local_plugins/qq_music/ios/qq_music/Sources/qq_music/QPlayAutoManager.swift

@ -7,10 +7,180 @@ import QPlayAutoSDK
@objc public static let shared = QPlayAutoManager()
private var delegates: [WeakDelegate] = []
private var isAppRegistered = false
// 添加登录状态维护
private var _isLoginOK = false
private var loginCompletionHandlers: [(Bool) -> Void] = []
// 添加token存储相关常量
private static let STORED_OPEN_ID_KEY = "QQMusic_OpenID"
private static let STORED_OPEN_TOKEN_KEY = "QQMusic_OpenToken"
private static let STORED_LOGIN_TIME_KEY = "QQMusic_LoginTime"
private static let TOKEN_EXPIRE_TIME: TimeInterval = 30 * 24 * 60 * 60 // 30天过期
// QQ音乐配置常量
private static let OPENID_APPID = "2000000921"
private static let OPENID_APP_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALWuTayxg0296yfm\n" +
"h8WhunybY1BEFt9fB4qb3TGvB0vkd+oKDoBdiTevtgwSL47h4O0ISNTQqqmVOvk1\n" +
"EQMGcLESBEdHquPX2uOplwmmVWx1un9NYB4JKaHmUkCXOIoiCgmEY052zFY2T+a0\n" +
"RfFiaUTc0wRMynquE8Qp18i23IUBAgMBAAECgYBf/s1D5jd+qE7MMl6i6iVjGaeM\n" +
"Da4YMFoHvvtM+TJdw0Yo/09SPBn4tnr2PdWrJWZ3V91DtU23dQZIDuYCNzDrOkVr\n" +
"93W5Pkqprdbde6qRhWm1VTZVN7h85DStGBzovSxQ6DQNHZFzIriJkfGDjPopmIil\n" +
"awQvMPlS3lLYkzHwAQJBAOWBlshEMHXeqXekjJExwX7YSy2oabWXtllCFbcPprAY\n" +
"MiM8cdNsEhnhrsmdBN4crqTQKJq/ATaYFhzASuIiZ2ECQQDKp17+A3u6q7RZ3Vmb\n" +
"khvAATQpVK5loCOzuyPU7/UGU49AO1DIaPwDvaUqL6PuF9eFrcRHA5AFbBjOgYNn\n" +
"piGhAkEAr5gMo0D4ytYHVxDAs74by071hgNajaN70qLrNlp1MDny8l6mwBnpZ3/y\n" +
"WTMXrFDJljPlPTByXzDRikHdiVLFQQJATMOTpxK4tqA+A+BmBhkVa+jI0nMiUJqV\n" +
"i4py60EuBoR2efU+B3xFIkGfI9jB9vmPCTMma2P9FSC6UNccaJG0oQJBAJYb6Ch9\n" +
"yowGPpY1CShaR+TfauUreJBd4PSpu8mFlYUssp2AXYcJM51RMzrZKXvTTOvwkStc\n" +
"NRCBcPVAYcVUnXo=\n" +
"-----END PRIVATE KEY-----"
private override init() {
super.init()
QPlayAutoSDK.setDelegate(self)
// Register for app lifecycle notifications
NotificationCenter.default.addObserver(
self,
selector: #selector(appWillTerminate),
name: UIApplication.willTerminateNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(appDidEnterBackground),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
registerAppWithDefaultConfig()
// 启用自动登录
tryAutoLoginWithStoredToken()
}
@objc private func appWillTerminate() {
stop()
}
@objc private func appDidEnterBackground() {
// Optionally stop SDK when app goes to background
// stop()
}
// MARK: - Token存储和自动登录
/// 尝试使用保存的token自动登录
private func tryAutoLoginWithStoredToken() {
guard let storedOpenId = UserDefaults.standard.string(forKey: Self.STORED_OPEN_ID_KEY),
let storedOpenToken = UserDefaults.standard.string(forKey: Self.STORED_OPEN_TOKEN_KEY),
let loginTime = UserDefaults.standard.object(forKey: Self.STORED_LOGIN_TIME_KEY) as? Date else {
print("QPlayAutoManager: 没有找到保存的token")
return
}
// 检查token是否过期
let currentTime = Date()
if currentTime.timeIntervalSince(loginTime) > Self.TOKEN_EXPIRE_TIME {
print("QPlayAutoManager: 保存的token已过期,清除本地存储")
clearStoredToken()
return
}
print("QPlayAutoManager: 找到有效的保存token,尝试自动登录")
print("QPlayAutoManager: OpenID: \(storedOpenId)")
print("QPlayAutoManager: OpenToken: \(storedOpenToken.prefix(20))...")
// 这里可以尝试使用保存的token进行连接
// 注意:QPlayAutoSDK可能需要重新连接来验证token有效性
connect(forceLogin: false)
}
/// 保存登录token
private func saveLoginToken() {
let openId = QPlayAutoSDK.openId()
let openToken = QPlayAutoSDK.openToken()
guard !openId.isEmpty, !openToken.isEmpty else {
print("QPlayAutoManager: 无法获取token信息")
return
}
UserDefaults.standard.set(openId, forKey: Self.STORED_OPEN_ID_KEY)
UserDefaults.standard.set(openToken, forKey: Self.STORED_OPEN_TOKEN_KEY)
UserDefaults.standard.set(Date(), forKey: Self.STORED_LOGIN_TIME_KEY)
UserDefaults.standard.synchronize()
print("QPlayAutoManager: Token已保存到本地存储")
print("QPlayAutoManager: OpenID: \(openId)")
print("QPlayAutoManager: OpenToken: \(openToken.prefix(20))...")
}
/// 清除保存的token
private func clearStoredToken() {
UserDefaults.standard.removeObject(forKey: Self.STORED_OPEN_ID_KEY)
UserDefaults.standard.removeObject(forKey: Self.STORED_OPEN_TOKEN_KEY)
UserDefaults.standard.removeObject(forKey: Self.STORED_LOGIN_TIME_KEY)
UserDefaults.standard.synchronize()
print("QPlayAutoManager: 已清除本地保存的token")
}
/// 获取保存的token信息
@objc public func getStoredTokenInfo() -> [String: Any]? {
guard let openId = UserDefaults.standard.string(forKey: Self.STORED_OPEN_ID_KEY),
let openToken = UserDefaults.standard.string(forKey: Self.STORED_OPEN_TOKEN_KEY),
let loginTime = UserDefaults.standard.object(forKey: Self.STORED_LOGIN_TIME_KEY) as? Date else {
return nil
}
return [
"openId": openId,
"openToken": openToken,
"loginTime": loginTime,
"isExpired": Date().timeIntervalSince(loginTime) > Self.TOKEN_EXPIRE_TIME
]
}
/// 手动清除token(用于登出)
@objc public func logout() {
clearStoredToken()
_isLoginOK = false
QPlayAutoSDK.stop()
print("QPlayAutoManager: 用户已登出,token已清除")
}
private func registerAppWithDefaultConfig() {
guard !isAppRegistered else {
print("QPlayAutoManager: App already registered, skipping")
return
}
// 确保完全停止之前的实例,避免端口占用
QPlayAutoSDK.stop()
// 添加短暂延迟确保资源完全释放
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let deviceId = UIDevice.current.identifierForVendor?.uuidString ?? "unknown_device"
let bundleId = Bundle.main.bundleIdentifier ?? "com.saitong.voitrans"
QPlayAutoSDK.registerApp(
withName: "VoiTrans",
brand: "SaiTong",
deviceId: deviceId,
scheme: "qqmusic",
appId: Self.OPENID_APPID,
secretKey: Self.OPENID_APP_PRIVATE_KEY,
bundleId: bundleId
)
self.isAppRegistered = true
print("QPlayAutoManager: App registered successfully")
}
}
// MARK: - Delegate Management
@ -50,12 +220,36 @@ import QPlayAutoSDK
// MARK: - Connection Management
@objc public func connect(forceLogin: Bool = false) {
guard isAppRegistered else {
print("QPlayAutoManager: App not registered, registering first")
registerAppWithDefaultConfig()
return // 添加这个return语句
}
// Add retry mechanism for socket errors
connectWithRetry(forceLogin: forceLogin, retryCount: 3)
}
private func connectWithRetry(forceLogin: Bool, retryCount: Int) {
guard retryCount > 0 else {
print("QPlayAutoManager: Connection failed after all retries")
return
}
QPlayAutoSDK.connectAndForceLogin(forceLogin)
// If connection fails due to socket error, retry after cleanup
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
if !self.isConnected {
print("QPlayAutoManager: Connection failed, retrying... (\(retryCount - 1) attempts left)")
QPlayAutoSDK.stop()
self.connectWithRetry(forceLogin: forceLogin, retryCount: retryCount - 1)
}
}
}
@objc public func reconnect(timeout: TimeInterval, completion: @escaping (Bool, [String: Any]?) -> Void) {
QPlayAutoSDK.reconnect(withTimeout: timeout) { (success, dict) in
// 修复:直接使用Bool类型,不进行Int比较
completion(success, dict as? [String: Any])
}
}
@ -64,40 +258,261 @@ import QPlayAutoSDK
QPlayAutoSDK.stop()
}
// MARK: - 登录状态管理
// 在第206行之前添加新的方法
private func ensureQQMusicInstalledAndLoginAndExecute(
_ operation: @escaping () -> Void,
onQQMusicNotInstalled: (() -> Void)? = nil,
onLoginFailed: (() -> Void)? = nil
) {
// 首先检查QQ音乐是否已安装
guard isQQMusicInstalled else {
print("QPlayAutoManager: QQ音乐未安装,无法执行操作")
onQQMusicNotInstalled?()
return
}
// QQ音乐已安装,继续检查登录状态
ensureLoginAndExecute(operation, onLoginFailed: onLoginFailed)
}
// 修改现有的ensureLoginAndExecute方法(第206行开始)
private func ensureLoginAndExecute(_ operation: @escaping () -> Void, onLoginFailed: (() -> Void)? = nil) {
if isLoginOK {
// 已登录,直接执行操作
operation()
} else {
// 未登录,先登录
print("QPlayAutoManager: 未登录,正在尝试登录...")
performLogin { [weak self] success in
if success {
print("QPlayAutoManager: 登录成功,执行操作")
operation()
} else {
print("QPlayAutoManager: 登录失败,无法执行操作")
onLoginFailed?()
}
}
}
}
private func performLogin(completion: @escaping (Bool) -> Void) {
// 如果正在登录中,将回调添加到队列
loginCompletionHandlers.append(completion)
// 如果已经有登录请求在处理,直接返回
if loginCompletionHandlers.count > 1 {
return
}
// 强制登录
connect(forceLogin: true)
// 设置超时检查
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { [weak self] in
self?.checkLoginTimeout()
}
}
private func checkLoginTimeout() {
if !loginCompletionHandlers.isEmpty && !isLoginOK {
print("QPlayAutoManager: 登录超时")
notifyLoginCompletion(false)
}
}
private func notifyLoginCompletion(_ success: Bool) {
let handlers = loginCompletionHandlers
loginCompletionHandlers.removeAll()
for handler in handlers {
handler(success)
}
}
// MARK: - 播放控制
@objc public func play() {
// 使用新的方法名
QPlayAutoSDK.playerPlayResume { errorCode in
print("Resume play result: \(errorCode)")
ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playerPlayResume { errorCode in
print("Resume play result: \(errorCode)")
}
} onQQMusicNotInstalled: {
print("QPlayAutoManager: 播放失败 - QQ音乐未安装")
} onLoginFailed: {
print("QPlayAutoManager: 播放失败 - 登录失败")
}
}
@objc public func play(songId: String) {
// 播放特定歌曲需要先搜索或使用歌曲列表
// 这里提供一个简化的实现
QPlayAutoSDK.playerPlayResume { errorCode in
print("Play song result: \(errorCode)")
ensureQQMusicInstalledAndLoginAndExecute {
// 使用正确的方法播放指定歌曲
QPlayAutoSDK.playSongMid(atIndex: [songId], play: 0) { errorCode in
print("Play song result: \(errorCode)")
}
} onQQMusicNotInstalled: {
print("QPlayAutoManager: 播放歌曲失败 - QQ音乐未安装")
} onLoginFailed: {
print("QPlayAutoManager: 播放歌曲失败 - 登录失败")
}
}
@objc public func pause() {
QPlayAutoSDK.playerPlayPause()
@objc public func playSongs(mids: [String], index: Int = 0, completion: @escaping (Bool, String?) -> Void) {
guard !mids.isEmpty else {
completion(false, "歌曲列表为空")
return
}
guard index >= 0 && index < mids.count else {
completion(false, "播放索引超出范围")
return
}
ensureLoginAndExecute {
QPlayAutoSDK.playSongMid(atIndex: mids, play: index) { errorCode in
if errorCode == 0 {
completion(true, nil)
print("QQ音乐播放列表启动成功,共\(mids.count)首歌曲")
} else {
let errorMessage = "QQ音乐播放列表启动失败,错误码: \(errorCode)"
completion(false, errorMessage)
print(errorMessage)
}
}
} onLoginFailed: {
completion(false, "登录失败,无法播放歌曲列表")
}
}
@objc public func next() {
QPlayAutoSDK.playerPlayNext { errorCode in
print("Next song result: \(errorCode)")
ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playerPlayNext { errorCode in
print("Next song result: \(errorCode)")
}
} onQQMusicNotInstalled: {
print("QPlayAutoManager: 下一首失败 - QQ音乐未安装")
} onLoginFailed: {
print("QPlayAutoManager: 下一首失败 - 登录失败")
}
}
@objc public func previous() {
QPlayAutoSDK.playerPlayPrev { errorCode in
print("Previous song result: \(errorCode)")
ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playerPlayPrev { errorCode in
print("Previous song result: \(errorCode)")
}
} onQQMusicNotInstalled: {
print("QPlayAutoManager: 上一首失败 - QQ音乐未安装")
} onLoginFailed: {
print("QPlayAutoManager: 上一首失败 - 登录失败")
}
}
@objc public func pause() {
ensureLoginAndExecute {
QPlayAutoSDK.playerPlayPause()
} onLoginFailed: {
print("QPlayAutoManager: 暂停失败 - 登录失败")
}
}
@objc public func seek(to position: TimeInterval) {
QPlayAutoSDK.playerSeek(Int(position))
ensureLoginAndExecute {
QPlayAutoSDK.playerSeek(Int(position))
} onLoginFailed: {
print("QPlayAutoManager: 跳转播放位置失败 - 登录失败")
}
}
// MARK: - 扩展功能方法(需要添加登录检查)
/// 设置播放模式
@objc public func setPlayMode(_ playMode: QPlayAutoPlayMode, completion: @escaping (Bool) -> Void) {
ensureLoginAndExecute {
QPlayAutoSDK.setPlayMode(playMode) { (success, dict) in
completion(success)
}
} onLoginFailed: {
print("QPlayAutoManager: 设置播放模式失败 - 登录失败")
completion(false)
}
}
/// 收藏/取消收藏歌曲
@objc public func setFavoriteState(song: QPlayAutoListItem, isFavorite: Bool, completion: @escaping (Bool) -> Void) {
ensureLoginAndExecute {
QPlayAutoSDK.setFavoriteStateWithSong(song, isFavorite: isFavorite) { errorCode in
completion(errorCode == 0)
}
} onLoginFailed: {
print("QPlayAutoManager: 设置收藏状态失败 - 登录失败")
completion(false)
}
}
/// 获取相似歌曲
@objc public func requestSimilarSongs(song: QPlayAutoListItem, completion: @escaping ([QPlayAutoListItem]?, Error?) -> Void) {
ensureLoginAndExecute {
QPlayAutoSDK.requestSimilar(withSong: song) { errorCode, items in
if errorCode == 0 {
completion(items, nil)
} else {
let error = NSError(domain: "QPlayAutoManager", code: Int(errorCode), userInfo: [NSLocalizedDescriptionKey: "请求相似歌曲失败"])
completion(nil, error)
}
}
} onLoginFailed: {
print("QPlayAutoManager: 请求相似歌曲失败 - 登录失败")
let error = NSError(domain: "QPlayAutoManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "QQ音乐未安装"])
completion(nil, error)
}
}
/// 获取歌词
@objc public func requestLyric(song: QPlayAutoListItem, completion: @escaping (QPlayAutoLyric?, Error?) -> Void) {
ensureLoginAndExecute {
QPlayAutoSDK.requestLyric(withSong: song) { errorCode, lyric in
if errorCode == 0 {
completion(lyric, nil)
} else {
let error = NSError(domain: "QPlayAutoManager", code: Int(errorCode), userInfo: [NSLocalizedDescriptionKey: "请求歌词失败"])
completion(nil, error)
}
}
} onLoginFailed: {
print("QPlayAutoManager: 请求歌词失败 - 登录失败")
let error = NSError(domain: "QPlayAutoManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "QQ音乐未安装"])
completion(nil, error)
}
}
/// 获取歌曲列表
@objc public func requestSonglist(type: QPlayAutoSongListType, completion: @escaping ([QPlayAutoListItem]?, Error?) -> Void) {
ensureLoginAndExecute {
QPlayAutoSDK.requestSonglist(with: type) { errorCode, items in
if errorCode == 0 {
completion(items, nil)
} else {
let error = NSError(domain: "QPlayAutoManager", code: Int(errorCode), userInfo: [NSLocalizedDescriptionKey: "请求歌单失败"])
completion(nil, error)
}
}
} onLoginFailed: {
print("QPlayAutoManager: 请求歌单失败 - 登录失败")
let error = NSError(domain: "QPlayAutoManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "QQ音乐未安装"])
completion(nil, error)
}
}
/// 播放指定歌曲列表
@objc public func playAtIndex(songList: [QPlayAutoListItem], playIndex: Int, completion: @escaping (Bool) -> Void) {
ensureLoginAndExecute {
QPlayAutoSDK.play(atIndex: songList, play: playIndex) { errorCode in
completion(errorCode == 0)
}
} onLoginFailed: {
print("QPlayAutoManager: 播放指定索引歌曲失败 - QQ音乐未安装")
completion(false)
}
}
// MARK: - 状态查询
@ -137,7 +552,6 @@ import QPlayAutoSDK
return QPlayAutoSDK.deviceInfo() as? [String: Any] ?? [:]
}
// Add missing properties
@objc public var openId: String? {
return QPlayAutoSDK.openId()
}
@ -149,21 +563,56 @@ import QPlayAutoSDK
// MARK: - URL Handling
@objc public func canHandleOpenURL(url: String) -> Bool {
guard let nsurl = URL(string: url) else { return false }
// 检查QQ音乐是否安装
guard isQQMusicInstalled else {
print("QPlayAutoManager: QQ音乐未安装,无法处理URL")
return false
}
// 检查登录状态
guard isLoginOK else {
print("QPlayAutoManager: 未登录,无法处理URL")
return false
}
return QPlayAutoSDK.canHandleOpen(nsurl)
}
@objc public func handleOpenURL(_ url: URL) -> Bool {
return QPlayAutoSDK.handleOpen(url)
// 检查QQ音乐是否安装
guard isQQMusicInstalled else {
print("QPlayAutoManager: QQ音乐未安装,无法处理URL")
return false
}
// 检查登录状态
guard isLoginOK else {
print("QPlayAutoManager: 未登录,无法处理URL")
return false
}
do {
return QPlayAutoSDK.handleOpen(url)
} catch {
print("QPlayAutoManager: 处理URL时发生错误: \(error)")
return false
}
}
// MARK: - Search and Content
// MARK: - Search and Content(添加登录检查)
@objc public func search(
keyword: String,
searchType: QPlayAutoSearchType,
completion: @escaping ([QPlayAutoListItem]?) -> Void
) {
QPlayAutoSDK.search(keyword, type: searchType, firstPage: true) { (error, items) in
completion(items)
ensureLoginAndExecute {
QPlayAutoSDK.search(keyword, type: searchType, firstPage: true) { (error, items) in
completion(items)
}
} onLoginFailed: {
print("QPlayAutoManager: 搜索失败 - 登录失败")
completion(nil)
}
}
@ -171,20 +620,27 @@ import QPlayAutoSDK
playlistId: String,
completion: @escaping ([QPlayAutoListItem]?) -> Void
) {
// Create a QPlayAutoListItem object
// with the playlistId to use as parentItem
let parentItem = QPlayAutoListItem()
parentItem.id = playlistId
QPlayAutoSDK.getDataItems(fromParent: parentItem, pageIndex: 0, pageSize: 50) { (error, items) in
// 修复:确保items是正确的类型
if error == 0 {
completion(items as? [QPlayAutoListItem])
} else {
completion(nil)
ensureLoginAndExecute {
let parentItem = QPlayAutoListItem()
parentItem.id = playlistId
QPlayAutoSDK.getDataItems(fromParent: parentItem, pageIndex: 0, pageSize: 50) { (error, items) in
if error == 0 {
completion(items as? [QPlayAutoListItem])
} else {
completion(nil)
}
}
} onLoginFailed: {
print("QPlayAutoManager: 获取播放列表失败 - 登录失败")
completion(nil)
}
}
// 添加公开的登录方法
@objc public func login(completion: @escaping (Bool) -> Void) {
performLogin(completion: completion)
}
}
// MARK: - QPlayAutoSDKDelegate
@ -233,8 +689,21 @@ extension QPlayAutoManager: QPlayAutoSDKDelegate {
}
public func onLoginStateDidChanged(_ isLoginOK: Bool) {
print("QPlayAutoManager: Login state changed to \(isLoginOK)")
_isLoginOK = isLoginOK
// 登录成功时保存token
if isLoginOK {
saveLoginToken()
notifyLoginCompletion(true)
} else {
// 登录失败时清除可能无效的token
clearStoredToken()
}
// 通知所有代理
cleanupDelegates()
for weakDelegate in delegates {
delegates.forEach { weakDelegate in
weakDelegate.delegate?.onLoginStateDidChanged?(isLoginOK)
}
}
@ -258,4 +727,4 @@ private class WeakDelegate {
init(_ delegate: QPlayAutoManagerDelegate) {
self.delegate = delegate
}
}
}

137
local_plugins/qq_music/ios/qq_music/Sources/qq_music/QqMusicPlugin.swift

@ -149,8 +149,8 @@ public class QqMusicPlugin: NSObject, FlutterPlugin {
// 新增:登录功能
private func handleLogin(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let isLoginOK = QPlayAutoManager.shared.isLoginOK
if isLoginOK {
// 如果已经登录,直接返回登录信息
if QPlayAutoManager.shared.isLoginOK {
let openId = QPlayAutoManager.shared.openId ?? ""
let openToken = QPlayAutoManager.shared.openToken ?? ""
result([
@ -159,8 +159,25 @@ public class QqMusicPlugin: NSObject, FlutterPlugin {
"openToken": openToken,
"expireTime": ""
])
} else {
result(FlutterError(code: "LOGIN_FAILED", message: "User not logged in", details: nil))
return
}
// 如果未登录,主动执行登录
QPlayAutoManager.shared.login { success in
DispatchQueue.main.async {
if success {
let openId = QPlayAutoManager.shared.openId ?? ""
let openToken = QPlayAutoManager.shared.openToken ?? ""
result([
"success": true,
"openId": openId,
"openToken": openToken,
"expireTime": ""
])
} else {
result(FlutterError(code: "LOGIN_FAILED", message: "登录失败", details: nil))
}
}
}
}
@ -173,22 +190,27 @@ public class QqMusicPlugin: NSObject, FlutterPlugin {
}
let searchType = args["searchType"] as? Int ?? 0
print("开始搜索歌曲,关键词: \(keyword), 类型: \(searchType)")
QPlayAutoManager.shared.search(keyword: keyword, searchType: QPlayAutoSearchType(rawValue: searchType) ?? .song) { items in
if let items = items {
let songs = items.map { item -> [String: Any] in
return [
"id": item.id ?? "",
"name": item.name ?? "",
"artist": item.singer?.name ?? "",
"album": item.album ?? "",
"duration": item.duration,
"mid": item.id ?? ""
]
DispatchQueue.main.async {
if let items = items {
print("搜索成功,找到 \(items.count) 首歌曲")
let songs = items.map { item -> [String: Any] in
return [
"id": item.id ?? "",
"name": item.name ?? "",
"artist": item.singer?.name ?? "",
"album": item.album ?? "",
"duration": item.duration,
"mid": item.id ?? ""
]
}
result(["success": true, "songs": songs])
} else {
print("搜索失败,未找到歌曲")
result(FlutterError(code: "SEARCH_FAILED", message: "Search failed", details: nil))
}
result(["success": true, "songs": songs])
} else {
result(FlutterError(code: "SEARCH_FAILED", message: "Search failed", details: nil))
}
}
}
@ -204,12 +226,13 @@ public class QqMusicPlugin: NSObject, FlutterPlugin {
let index = args["index"] as? Int ?? 0
if index < songMids.count {
let songId = songMids[index]
QPlayAutoManager.shared.play(songId: songId)
result(["success": true])
} else {
result(FlutterError(code: "PLAY_FAILED", message: "Invalid index", details: nil))
// 使用 playSongs 方法播放整个列表
QPlayAutoManager.shared.playSongs(mids: songMids, index: index) { success, errorMessage in
if success {
result(["success": true])
} else {
result(FlutterError(code: "PLAY_FAILED", message: errorMessage ?? "播放失败", details: nil))
}
}
}
@ -405,18 +428,60 @@ public class QqMusicPlugin: NSObject, FlutterPlugin {
// 第405-409行 - handleSyncCurrentPlayInfo方法
private func handleSyncCurrentPlayInfo(result: @escaping FlutterResult) {
if let song = QPlayAutoManager.shared.currentSong {
let playInfo: [String: Any] = [
"id": song.id ?? "",
"name": song.name ?? "",
"artist": song.singer?.name ?? "",
"album": song.album ?? "",
"duration": song.duration
]
result(["success": true, "data": playInfo])
} else {
result(FlutterError(code: "NO_CURRENT_SONG", message: "No current song playing", details: nil))
}
// 构建同步数据
var syncData: [String: Any] = [:]
// 获取当前歌曲信息
if let song = QPlayAutoManager.shared.currentSong {
let currentSong: [String: Any] = [
"id": song.id ?? "",
"mid": song.mid ?? "",
"name": song.name ?? "",
"singer": song.singer?.name ?? "",
"album": song.album ?? "",
"duration": song.duration,
"pic": song.coverUri ?? ""
]
syncData["currentSong"] = currentSong
} else {
syncData["currentSong"] = nil
}
// 获取播放状态 - 使用正确的枚举成员名称
let playState = QPlayAutoManager.shared.currentPlayState
let isPlaying: Bool
let playStateValue: Int
switch playState {
case .playing:
isPlaying = true
playStateValue = 1
case .pause:
isPlaying = false
playStateValue = 2
case .stop:
isPlaying = false
playStateValue = 0
default:
isPlaying = false
playStateValue = 0
}
syncData["isPlaying"] = isPlaying
syncData["playState"] = playStateValue
// 获取播放时间
let currentProgress = QPlayAutoManager.shared.currentProgress
let currentTime = Int64(currentProgress) // 转换为秒
let totalTime = Int64(QPlayAutoManager.shared.currentSong?.duration ?? 0)
syncData["currentTime"] = currentTime
syncData["totalTime"] = totalTime
// 添加同步时间戳
syncData["syncTimestamp"] = Int64(Date().timeIntervalSince1970 * 1000) // 毫秒时间戳
result(["success": true, "data": syncData])
}
// 第492-496行 - 重复的handleGetPlaylistContent方法(需要删除)
@ -469,4 +534,4 @@ extension QqMusicPlugin: QPlayAutoManagerDelegate {
public func onLoginStateDidChanged(_ isLogin: Bool) {
eventSink?(["type": "loginStateChanged", "isLogin": isLogin])
}
}
}

103
local_plugins/qq_music/ios/qq_music/Sources/qq_music/include/QPlayAutoDefine.h

@ -78,6 +78,12 @@ typedef NS_ENUM(NSUInteger, QPlayAutoListItemType)
QPlayAutoListItemType_Album = 5, //专辑
};
typedef NS_ENUM(NSUInteger, QPlayAutoSongListType)
{
QPlayAutoSongListType_Daily = 108, //每日30首
};
/**
QPlayAuto播放状态
*/
@ -88,6 +94,12 @@ typedef NS_ENUM(NSUInteger, QPlayAutoPlayState)
QPlayAutoPlayState_Pause=2 //暂停
};
typedef NS_ENUM(NSInteger, QPlayAutoAssenceMode)
{
QPlayAutoAssenceMode_Full = 0, // 默认整首播放
QPlayAutoAssenceMode_Part = 1, // 仅播放精华片段
};
/**
QPlayAuto播放模式
*/
@ -121,74 +133,86 @@ typedef NS_ENUM(NSInteger, QPlayAutoVipState)
*/
@interface QPlayAutoAppInfo : NSObject<NSCoding>
@property (nonatomic,strong) NSString *deviceId;
@property (nonatomic,strong) NSString *deviceId; //AppId
@property (nonatomic,assign) NSInteger deviceType;
@property (nonatomic,strong) NSString *scheme;
@property (nonatomic,strong) NSString *brand;
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSString *appId;
@property (nonatomic,strong) NSString *secretKey;
@property (nonatomic,strong) NSString *bundleId;
@property (nonatomic,assign) NSInteger qmCommandPort;
@property (nonatomic,strong) NSString *qmHost;
@property (nonatomic,strong) NSDate *lastConnectDate;
@property (nonatomic,strong) NSString *scheme; //跳转scheme
@property (nonatomic,strong) NSString *brand; //品牌
@property (nonatomic,strong) NSString *name; //名称
@property (nonatomic,strong) NSString *appId; //名称
@property (nonatomic,strong) NSString *secretKey; //私钥
@property (nonatomic,strong) NSString *bundleId; //bundleId
@property (nonatomic,assign) NSInteger qmCommandPort; //Q音接收命令端口
@property (nonatomic,strong) NSString *qmHost; //Q音接收命令IP
@property (nonatomic,strong) NSDate *lastConnectDate;//上次连接的日期
@end
@interface QPlayAutoSinger : NSObject
@property (nonatomic,strong) NSString *ID;
@property (nonatomic,strong) NSString *Mid;
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSString *ID; //ID
@property (nonatomic,strong) NSString *Mid; //Mid
@property (nonatomic,strong) NSString *name; //名称
@end
/*
QPlayAuto列表项(歌单、电台、排行榜、歌曲、etc)
*/
@interface QPlayAutoListItem: NSObject
@property (nonatomic,strong) NSString *ID;
@property (nonatomic,strong) NSString *Name;
@property (nonatomic,strong) NSString *SubName;
@property (nonatomic,strong) QPlayAutoSinger *singer;
@property (nonatomic,strong) NSString *Album;
@property (nonatomic,strong) NSString *ID; //ID
@property (nonatomic,strong) NSString *Name; //名称
@property (nonatomic,strong) NSString *SubName; //副标题
@property (nonatomic,strong) QPlayAutoSinger *singer; //歌手
@property (nonatomic,strong) NSString *Album; //专辑
@property (nonatomic,strong) NSString *Mid;
@property (nonatomic,assign) QPlayAutoVipState vipState;
@property (nonatomic,assign) QPlayAutoListItemType Type;
@property (nonatomic,assign) NSInteger Duration;
@property (nonatomic,strong) NSString *CoverUri;
@property (nonatomic,assign) NSInteger totalCount;
@property (nonatomic,assign) BOOL isFav;
@property (nonatomic,assign) BOOL isOrigin;
@property (nonatomic,assign) BOOL isNoAudioSource;
@property (nonatomic,strong) NSMutableArray<QPlayAutoListItem*> *items;
@property (nonatomic,weak) QPlayAutoListItem *parentItem;
@property (nonatomic,assign) BOOL isTryListen;
@property (nonatomic,readonly) BOOL isSong;
@property (nonatomic,readonly) BOOL isFolder;
@property (nonatomic,readonly) BOOL isAlbum;
@property (nonatomic,readonly) BOOL isRadio;
@property (nonatomic,readonly) BOOL isDirectory;
@property (nonatomic,readonly) BOOL isVIP;
@property (nonatomic,readonly) BOOL isSVIP;
@property (nonatomic,assign) NSInteger Duration; //时长
@property (nonatomic,strong) NSString *CoverUri; //封面Uri
@property (nonatomic,assign) NSInteger totalCount; //总数
@property (nonatomic,assign) BOOL isFav; //是否收藏
@property (nonatomic,assign) BOOL isOrigin; //是否原唱
@property (nonatomic,assign) BOOL isNoAudioSource; //无音源
@property (nonatomic,strong) NSMutableArray<QPlayAutoListItem*> *items; //子列表
@property (nonatomic,weak) QPlayAutoListItem *parentItem; //父节点
@property (nonatomic,assign) BOOL isTryListen; //是否试听歌曲
@property (nonatomic,readonly) BOOL isSong; //歌曲
@property (nonatomic,readonly) BOOL isFolder;//歌单
@property (nonatomic,readonly) BOOL isAlbum; //专辑
@property (nonatomic,readonly) BOOL isRadio; //电台
@property (nonatomic,readonly) BOOL isDirectory; //普通目录
@property (nonatomic,readonly) BOOL isVIP; //VIP歌曲
@property (nonatomic,readonly) BOOL isSVIP; //SVIP歌曲
- (instancetype)initWithDictionary:(NSDictionary*)dict;
- (instancetype)initSongWithId:(NSString *)identifier isFav:(BOOL)isFav;
- (instancetype)initWithId:(NSString *)identifier type:(QPlayAutoListItemType)type;
//是否是根节点
- (BOOL)isRoot;
//是否有更多
- (BOOL)hasMore;
- (QPlayAutoListItem*)findItemWithID:(NSString*)ID;
@end
/**
QPlayAuto请求回调
@param success 是否成功
@param dict 结果Dictionary
*/
typedef void (^QPlayAutoRequestFinishBlock)(BOOL success, NSDictionary *dict);
@interface QPlayAutoRequestBase : NSObject
/** 请求类型 */
@property (nonatomic, assign) int type;
@end
@interface QPlayAutoSentence : NSObject <NSCoding>
@ -200,14 +224,15 @@ typedef void (^QPlayAutoRequestFinishBlock)(BOOL success, NSDictionary *dict);
@end
@interface QPlayAutoLyric : NSObject <NSCoding>
@property(nonatomic,assign) BOOL isTxtType;
@property(nonatomic,assign) BOOL isTxtType;//歌词是不是纯文本的歌词,没有时间标记
@property(nonatomic,strong) NSString *songId;
@property(nonatomic,strong) NSString *songName;
@property(nonatomic,strong) NSString *singerName;
@property(nonatomic,strong) NSString *albumName;
@property(nonatomic,readonly) NSString *text;
@property(nonatomic,readonly) NSString *text;//所有歌词文本
@property(nonatomic,strong) NSArray<QPlayAutoSentence *> *sentences;
- (NSString *)sentenceAtTime:(NSTimeInterval)time;
@end
#endif /* QPlayAutoDefine_h */
#endif /* QPlayAutoDefine_h */

115
local_plugins/qq_music/ios/qq_music/Sources/qq_music/include/QPlayAutoSDK.h

@ -36,9 +36,18 @@ extern NSString const * QPlayAutoSDKVersion;
- (void)onLoginStateDidChanged:(BOOL)isLoginOK;
@end
@interface QPlayAutoSDK : NSObject
/// 注册App
/// @param name 名称
/// @param brand 品牌
/// @param deviceId ?
/// @param scheme 授权成功后Q音跳转合作方的scheme
/// @param appId Q音分配的Id
/// @param secretKey 合作方私钥
/// @param bundleId 合作方包名
+ (void)registerAppWithName:(NSString *)name brand:(NSString *)brand deviceId:(NSString *)deviceId scheme:(NSString *)scheme appId:(NSString *)appId secretKey:(NSString *)secretKey bundleId:(NSString *)bundleId;
/// 播放状态
@ -63,6 +72,7 @@ extern NSString const * QPlayAutoSDKVersion;
+(NSString *)openId;
+(NSString *)openToken;
///是否可以处理回调url
+ (BOOL)canHandleOpenURL:(NSURL *)url;
///处理回调url
@ -71,27 +81,108 @@ extern NSString const * QPlayAutoSDKVersion;
/// 回调代理
+ (void)setDelegate:(id<QPlayAutoSDKDelegate>) delegate;
/// 拉端连接QPlay
/// - Parameter forceLogin: 是否强制登录
+ (void)connectAndForceLogin:(BOOL)forceLogin;
/// 停止
+ (void)stop;
/// 二次热启动连接
/// 二次热启动连接(需要联系Q音打开此功能才能使用)
/// - Parameters:
/// - timeout: 超时时间
/// - completion: 回调
+ (void)reconnectWithTimeout:(NSTimeInterval)timeout completion:(QPlayAutoRequestFinishBlock)completion;
/// 播放控制
+ (void)play;
+ (void)pause;
+ (void)next;
+ (void)previous;
+ (void)seekToTime:(NSTimeInterval)time;
/// 跳转QQ音乐登录
/// @param bundleId 合作方bundleId
/// @param callbackUrl 跳转合作方url
+ (BOOL)loginQQMusicWithBundleId:(NSString *)bundleId callbackUrl:(NSString *)callbackUrl;
/// 获取数据
/// @param parent 父
/// @param pageIndex 页码
/// @param pageSize 页大小
/// @param completion 回调
+ (void)getDataItemsFromParent:(QPlayAutoListItem *)parent pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize completion:(QPlayAutoResultParentItemBlock)completion;
/// 设置播放模式
/// @param playMode 播放模式
/// @param block 回调
+ (NSInteger)setPlayMode:(QPlayAutoPlayMode)playMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 设置播放整首还是高潮
/// @param assencceMode 高潮还是整首
/// @param block 回调
+ (NSInteger)setAssenceMode:(QPlayAutoAssenceMode)assencceMode callback:(QPlayAutoRequestFinishBlock _Nullable )block;
/// 收藏/取消收藏(歌曲id)
/// @param song 歌曲
/// @param isFavorite 收藏/取消收藏
/// @param completion 回调
+ (void)setFavoriteStateWithSong:(QPlayAutoListItem *)song isFavorite:(BOOL)isFavorite completion:(void (^)(NSInteger errorCode))completion;
/// 播放歌曲
/// @param songList 歌曲列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playAtIndex:(NSArray<QPlayAutoListItem*> *)songList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
/// 通过歌曲Mid列表播放歌曲
/// @param songMidList 歌曲Mid列表
/// @param playIndex 播放索引
/// @param completion 回调
+ (void)playSongMidAtIndex:(NSArray<NSString*> *)songMidList playIndex:(NSInteger)playIndex completion:(void (^)(NSInteger errorCode))completion;
///播放下一首
+ (void)playerPlayNextWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放上一首
+ (void)playerPlayPrevWithCompletion:(void (^)(NSInteger errorCode))completion;
///播放暂停
+ (void)playerPlayPause;
///播放恢复
+ (void)playerPlayResumeWithCompletion:(void (^)(NSInteger errorCode))completion;
///Seek到指定位置
+ (void)playerSeek:(NSInteger)position;
/// 搜索歌曲
/// @param keyword 关键词
/// @param type 搜索类型
/// @param firstPage 是否第一页
/// @param completion 回调
+ (NSInteger)search:(NSString *)keyword
type:(QPlayAutoSearchType)type
firstPage:(BOOL)firstPage
completion:(QPlayAutoResultItemsBlock)completion;
/// 相似歌曲
/// @param song 歌曲
/// @param completion 回调
+ (void)requestSimilarWithSong:(QPlayAutoListItem *)song completion:(QPlayAutoResultItemsBlock)completion;
/// 查询歌词
/// @param song 歌曲
/// @param completion 回调
+ (void)requestLyricWithSong:(QPlayAutoListItem *)song completion:(void (^)(NSInteger errorCode,QPlayAutoLyric *_Nullable lyric))completion;
/// 搜索
+ (void)searchWithKeyword:(NSString *)keyword type:(QPlayAutoSearchType)type pageIndex:(NSInteger)pageIndex completion:(QPlayAutoResultItemsBlock)completion;
/// 获取歌单内容
+ (void)getItemsWithParentItem:(QPlayAutoListItem *)parentItem pageIndex:(NSInteger)pageIndex completion:(QPlayAutoResultItemsBlock)completion;
/// 获取特定歌曲列表
/// @param type 列表类型
/// @param completion 回调
+ (void)requestSonglistWithType:(QPlayAutoSongListType)type completion:(QPlayAutoResultItemsBlock)completion;
@end
NS_ASSUME_NONNULL_END
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save