跳到主要内容

音乐控制(TSMusic)

TSMusic 模块提供手表设备的音乐管理与播放控制能力,涵盖音乐文件的推送、查询、单首删除与全部删除,以及播放控制(播放、暂停、切歌)和音量调节等操作。所有回调均在主线程执行。


前提条件​

  • 已完成 SDK 初始化并与手表设备建立连接。
  • 调用音乐文件管理相关方法(fetchMusicStorageSpace:、fetchAllMusics:、pushMusic:progress:success:failure:、deleteMusic:completion:、deleteAllMusicsWithCompletion:)前,须通过 isSupportMusicPush 确认设备支持音乐推送。
  • 调用播放控制与音量相关方法前,须通过 isSupportMusicControl 确认设备支持音乐播放控制。
  • 推送音乐时,TSMusicModel 的 filePath 必须指向一个本地可读的有效文件。
  • 删除音乐时优先使用 title;title 为空时使用 filePath.lastPathComponent,解析结果必须是带扩展名的完整设备文件名。

数据模型​

TSMusicModel​

表示手表设备上的音乐信息及播放状态。

属性名类型说明
filePathNSString *音乐文件的本地路径,推送音乐时必须为有效路径
titleNSString *音乐标题;在设备文件管理场景中为带扩展名的完整设备文件名,最大长度 64 字节
artistNSString *艺术家或表演者名称,用于在手表设备上显示,最大长度 64 字节
durationNSTimeInterval音乐总时长,单位为秒,用于计算播放进度和显示剩余时间
currentTimeNSTimeInterval当前播放位置,单位为秒,范围为 0 到 duration
playbackStatusTSMusicPlaybackStatus当前播放状态,默认为 TSMusicPlaybackStatusStopped

辅助方法:

方法说明
resolvedFileName优先返回 title,为空时返回 filePath.lastPathComponent;不判断文件是否真实存在
hasReadableLocalFile判断 filePath 是否指向存在且可读的本地普通文件;不校验格式或 Provider 特有限制

枚举与常量​

TSMusicPlaybackStatus — 音乐播放状态​

枚举值原始值说明
TSMusicPlaybackStatusStopped0音乐已停止
TSMusicPlaybackStatusPlaying1音乐正在播放
TSMusicPlaybackStatusPaused2音乐已暂停

回调类型​

回调类型签名说明
TSMusicListBlockvoid (^)(NSArray<TSMusicModel *> *musics, NSError *error)音乐列表回调,获取失败时 musics 为空数组,error 携带错误信息;成功时 error 为 nil
TSFileTransferProgressBlockvoid (^)(TSFileTransferStatus status, NSInteger progress)文件传输进度回调,progress 取值 0~100,status 表示当前传输阶段
TSFileTransferSuccessBlockvoid (^)(void)文件传输成功回调,推送完成时触发
TSFileTransferFailureBlockvoid (^)(NSError *error)文件传输失败回调,推送失败或被取消时触发
TSCompletionBlockvoid (^)(BOOL success, NSError *error)通用完成回调,success 表示操作是否成功,失败时 error 携带错误信息

接口方法​

检查设备是否支持音乐推送​

- (BOOL)isSupportMusicPush;

返回值: BOOL,设备支持音乐推送返回 YES,否则返回 NO。

代码示例:

if ([self.musicInterface isSupportMusicPush]) {
TSLog(@"设备支持音乐推送,可调用相关接口");
} else {
TSLog(@"设备不支持音乐推送");
}

检查设备是否支持音乐播放控制​

- (BOOL)isSupportMusicControl;

返回值: BOOL,设备支持音乐播放控制返回 YES,否则返回 NO。

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
TSLog(@"设备支持音乐播放控制,可调用播放/暂停/切歌/音量接口");
} else {
TSLog(@"设备不支持音乐播放控制");
}

获取设备上所有音乐列表​

- (void)fetchAllMusics:(nonnull TSMusicListBlock)completion;

参数:

参数名类型说明
completionTSMusicListBlock完成回调,返回设备上所有音乐模型数组;获取失败或无音乐时返回空数组

代码示例:

if ([self.musicInterface isSupportMusicPush]) {
[self.musicInterface fetchAllMusics:^(NSArray<TSMusicModel *> *musics, NSError *error) {
if (error) {
TSLog(@"获取音乐列表失败:%@", error.localizedDescription);
return;
}
TSLog(@"设备上共有 %lu 首音乐", (unsigned long)musics.count);
for (TSMusicModel *music in musics) {
TSLog(@"标题:%@,艺术家:%@,时长:%.0f 秒",
music.title, music.artist, music.duration);
}
}];
}

向设备推送音乐​

- (void)pushMusic:(TSMusicModel *)music
progress:(nullable TSFileTransferProgressBlock)progress
success:(nullable TSFileTransferSuccessBlock)success
failure:(nullable TSFileTransferFailureBlock)failure;

参数:

参数名类型说明
musicTSMusicModel *要推送的音乐模型,filePath 必须指向本地有效且可读的音乐文件
progressTSFileTransferProgressBlock进度回调,推送过程中多次触发,返回当前进度(0~100)及传输状态
successTSFileTransferSuccessBlock成功回调,推送完成时触发
failureTSFileTransferFailureBlock失败回调,推送失败或被取消时触发,携带错误信息

代码示例:

if (![self.musicInterface isSupportMusicPush]) {
TSLog(@"设备不支持音乐推送");
return;
}

TSMusicModel *music = [[TSMusicModel alloc] init];
music.title = @"我的歌曲";
music.artist = @"未知艺术家";
music.filePath = @"/path/to/local/music.mp3";
music.duration = 240.0;

[self.musicInterface pushMusic:music
progress:^(TSFileTransferStatus status, NSInteger progress) {
TSLog(@"推送进度:%ld%%,传输状态:%ld", (long)progress, (long)status);
} success:^{
TSLog(@"音乐推送成功");
} failure:^(NSError *error) {
TSLog(@"音乐推送失败:%@", error.localizedDescription);
}];

取消正在推送的音乐​

- (void)cancelPushMusic:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示取消是否成功,失败时 error 携带错误信息

代码示例:

[self.musicInterface cancelPushMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"音乐推送已成功取消");
} else {
TSLog(@"取消推送失败:%@", error.localizedDescription);
}
}];

从设备删除指定音乐​

- (void)deleteMusic:(TSMusicModel *)music completion:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
musicTSMusicModel *要删除的音乐模型;优先使用 title,为空时使用 filePath.lastPathComponent
completionTSCompletionBlock完成回调,success 表示删除是否成功,失败时 error 携带错误信息

代码示例:

// 以 fetchAllMusics: 返回的第一首音乐为例
[self.musicInterface fetchAllMusics:^(NSArray<TSMusicModel *> *musics, NSError *error) {
if (error || musics.count == 0) {
TSLog(@"获取音乐列表失败或列表为空");
return;
}
TSMusicModel *musicToDelete = musics.firstObject;
[self.musicInterface deleteMusic:musicToDelete completion:^(BOOL success, NSError *deleteError) {
if (success) {
TSLog(@"音乐《%@》删除成功", musicToDelete.title);
} else {
TSLog(@"删除失败:%@", deleteError.localizedDescription);
}
}];
}];

删除设备上的全部音乐​

- (void)deleteAllMusicsWithCompletion:(nullable TSCompletionBlock)completion;

该方法仅删除 TSMusicInterface 管理的音乐曲目,不删除录音或其他媒体文件。设备音乐列表已为空时仍返回成功。非空回调保证在主线程且仅执行一次;传入 nil 仅表示忽略结果,删除操作仍会执行。

如果已有音乐推送或删除任务正在执行,本次请求会返回忙错误,且不会加入或取消现有任务。删除失败时可能已有部分音乐被删除,应重新调用 fetchAllMusics: 刷新设备状态后再展示结果或重试。

参数:

参数名类型说明
completionTSCompletionBlock完成回调;仅当操作后不存在该接口管理的音乐曲目时 success 为 YES

代码示例:

if ([self.musicInterface isSupportMusicPush]) {
[self.musicInterface deleteAllMusicsWithCompletion:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"全部音乐删除成功");
} else {
TSLog(@"删除未全部完成:%@,请刷新音乐列表", error.localizedDescription);
}
}];
}

控制设备开始播放音乐​

- (void)playMusic:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示播放指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface playMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"播放指令发送成功");
} else {
TSLog(@"播放指令发送失败:%@", error.localizedDescription);
}
}];
}

控制设备暂停播放音乐​

- (void)pauseMusic:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示暂停指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface pauseMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"暂停指令发送成功");
} else {
TSLog(@"暂停指令发送失败:%@", error.localizedDescription);
}
}];
}

控制设备播放下一首音乐​

- (void)playNextMusic:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示下一首指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface playNextMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"下一首指令发送成功");
} else {
TSLog(@"下一首指令发送失败:%@", error.localizedDescription);
}
}];
}

控制设备播放上一首音乐​

- (void)playPreviousMusic:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示上一首指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface playPreviousMusic:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"上一首指令发送成功");
} else {
TSLog(@"上一首指令发送失败:%@", error.localizedDescription);
}
}];
}

提高设备音量一档​

- (void)increaseVolume:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示增加音量指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface increaseVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"音量提高成功");
} else {
TSLog(@"音量提高失败:%@", error.localizedDescription);
}
}];
}

降低设备音量一档​

- (void)decreaseVolume:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示降低音量指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface decreaseVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"音量降低成功");
} else {
TSLog(@"音量降低失败:%@", error.localizedDescription);
}
}];
}

设备静音​

- (void)muteVolume:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示静音指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface muteVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"设备已静音,当前音量值已保留");
} else {
TSLog(@"静音失败:%@", error.localizedDescription);
}
}];
}

取消设备静音​

- (void)unmuteVolume:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
completionTSCompletionBlock完成回调,success 表示取消静音指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
[self.musicInterface unmuteVolume:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"静音已取消,音量已恢复至静音前水平");
} else {
TSLog(@"取消静音失败:%@", error.localizedDescription);
}
}];
}

设置设备具体音量值​

- (void)setVolume:(NSInteger)volume completion:(nullable TSCompletionBlock)completion;

参数:

参数名类型说明
volumeNSInteger目标音量值,取值范围 [0, 100],超出范围的值将被截断
completionTSCompletionBlock完成回调,success 表示设置音量指令是否执行成功,失败时 error 携带错误信息

代码示例:

if ([self.musicInterface isSupportMusicControl]) {
NSInteger targetVolume = 60;
[self.musicInterface setVolume:targetVolume completion:^(BOOL success, NSError *error) {
if (success) {
TSLog(@"音量已成功设置为 %ld", (long)targetVolume);
} else {
TSLog(@"设置音量失败:%@", error.localizedDescription);
}
}];
}

注意事项​

  1. 调用任何音乐文件管理接口(fetchMusicStorageSpace:、fetchAllMusics:、pushMusic:progress:success:failure:、deleteMusic:completion:、deleteAllMusicsWithCompletion:)前,必须先通过 isSupportMusicPush 检查设备能力,不支持时调用这些接口将无效。
  2. 调用任何播放控制或音量接口前,必须先通过 isSupportMusicControl 检查设备能力,不支持时调用这些接口将无效。
  3. 推送音乐时,TSMusicModel 的 filePath 必须指向一个本地存在且可读的有效音乐文件,否则推送将直接失败。
  4. 同一时间只能有一个音乐推送任务处于活动状态;若需开启新的推送,请先调用 cancelPushMusic: 取消当前任务。
  5. 取消推送(cancelPushMusic:)会自动清理传输产生的临时文件,取消操作本身可能需要一定时间完成,期间请勿重复发起新的推送。
  6. 删除音乐时使用 resolvedFileName 取得带扩展名的完整设备文件名;若设备上未找到对应音乐,操作将失败并返回相应错误。
  7. deleteAllMusicsWithCompletion: 仅删除音乐曲目;空列表按成功处理。失败时设备上可能只剩部分音乐,须通过 fetchAllMusics: 刷新实际状态。
  8. 音量值通过 setVolume:completion: 设置时,取值范围为 0~100,超出范围的值将被自动截断;increaseVolume: 和 decreaseVolume: 的实际调节档位由设备固件决定。
  9. 执行 muteVolume: 后设备会保留当前音量值,调用 unmuteVolume: 可恢复至静音前的音量水平。
  10. 所有接口的回调均在主线程执行,可直接在回调中进行 UI 更新操作。