|
|
@@ -907,7 +907,7 @@ export struct LocalMusic {
|
|
|
// 设置解码前图片数据内存缓存上限为100MB (100MB=100*1024*1024B=104857600B)
|
|
|
app.setImageRawDataCacheSize(104857600);
|
|
|
Logger.info('onecold onPageShow currentBreakpoint= ' + this.currentBreakpoint)
|
|
|
-
|
|
|
+
|
|
|
// 修复音频中断后的状态同步问题
|
|
|
this.syncPlaybackStateOnShow();
|
|
|
}
|
|
|
@@ -919,9 +919,9 @@ export struct LocalMusic {
|
|
|
try {
|
|
|
const currentState = this.unifiedPlayerService.getCurrentState();
|
|
|
const actualPlaying = this.unifiedPlayerService.getActualPlayingState();
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI(`onPageShow state sync - StateModel: isPlaying=${currentState.isPlaying}, isPaused=${currentState.isPaused}, Actual: ${actualPlaying}`);
|
|
|
-
|
|
|
+
|
|
|
// 如果状态不一致,强制同步
|
|
|
if (currentState.isPlaying !== actualPlaying) {
|
|
|
LogUtils.getInstance().LOGI(`State inconsistency detected, forcing sync`);
|
|
|
@@ -1059,7 +1059,7 @@ export struct LocalMusic {
|
|
|
if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
this.isFirstStartPlay = true
|
|
|
this.sonDataSource.pushArrayData(this.songList)
|
|
|
-
|
|
|
+
|
|
|
// 不要强制设置为第一首歌曲,保持从UnifiedPlayerService恢复的状态
|
|
|
// 只有在完全没有当前歌曲且没有有效索引时才设置默认值
|
|
|
if (this.currentSong === undefined && this.curIndex < 0 && this.songList.length > 0) {
|
|
|
@@ -1072,7 +1072,7 @@ export struct LocalMusic {
|
|
|
this.currentSong = this.songList[this.curIndex]
|
|
|
LogUtils.getInstance().LOGI(`LocalMusic: mkDownLoadDir - Restored current song from index ${this.curIndex}: ${this.currentSong.name}`);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (this.currentSong) {
|
|
|
this.videoUrl = this.currentSong.filePath
|
|
|
this.name = this.currentSong.name
|
|
|
@@ -1482,7 +1482,7 @@ export struct LocalMusic {
|
|
|
try {
|
|
|
// 获取当前目录的最新文件列表(包含最新的封面信息)
|
|
|
const currentFileList = this.getCurFileList();
|
|
|
-
|
|
|
+
|
|
|
// 如果当前文件列表为空,直接返回
|
|
|
if (ArrayUtil.isEmpty(currentFileList)) {
|
|
|
return;
|
|
|
@@ -1493,8 +1493,8 @@ export struct LocalMusic {
|
|
|
this.songList.forEach((song, index) => {
|
|
|
// 在当前文件列表中查找对应的歌曲
|
|
|
const matchedSong = currentFileList.find(file => file.filePath === song.filePath);
|
|
|
- if (matchedSong && StrUtil.isNotEmpty(matchedSong.pixelMapPath) &&
|
|
|
- matchedSong.pixelMapPath !== song.pixelMapPath) {
|
|
|
+ if (matchedSong && StrUtil.isNotEmpty(matchedSong.pixelMapPath) &&
|
|
|
+ matchedSong.pixelMapPath !== song.pixelMapPath) {
|
|
|
// 更新播放列表中的封面信息
|
|
|
this.songList[index].pixelMapPath = matchedSong.pixelMapPath;
|
|
|
hasUpdates = true;
|
|
|
@@ -2695,7 +2695,7 @@ export struct LocalMusic {
|
|
|
} else {
|
|
|
ToastUtil.showToast('取消收藏成功');
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 先更新收藏列表和其他UI
|
|
|
this.deleteCache(this.currentPath)
|
|
|
this.getFavList(false)
|
|
|
@@ -2706,7 +2706,7 @@ export struct LocalMusic {
|
|
|
workerInstance.postMessage({ code: 2, data: this.context });
|
|
|
workerInstance.postMessage({ code: 3, data: this.context });
|
|
|
workerInstance.postMessage({ code: 4, data: this.context });
|
|
|
-
|
|
|
+
|
|
|
// 刷新UnifiedPlayerService的收藏状态,这会自动更新AVSession
|
|
|
await this.unifiedPlayerService.refreshFavoriteStatus();
|
|
|
}
|
|
|
@@ -4817,6 +4817,19 @@ export struct LocalMusic {
|
|
|
// this.stop();
|
|
|
// }
|
|
|
|
|
|
+ // 检查是否正在投播
|
|
|
+ if (this.isCurrentlyCasting()) {
|
|
|
+ // 更新当前歌曲信息
|
|
|
+ this.curIndex = index as number;
|
|
|
+ this.currentSong = item;
|
|
|
+ this.videoUrl = this.currentSong.filePath;
|
|
|
+ this.artist = this.currentSong.artist;
|
|
|
+ this.name = this.currentSong.name;
|
|
|
+ this.cover = this.currentSong.pixelMapPath;
|
|
|
+ this.changeCasting();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if (isFromSonPlayList) { //点击来自右下角的播放列表
|
|
|
this.currentSong = item
|
|
|
if (index !== undefined) {
|
|
|
@@ -4849,6 +4862,7 @@ export struct LocalMusic {
|
|
|
// 重置时间显示状态,防止新歌曲时间显示被上一首歌曲的时间"卡住"
|
|
|
this.oldSeconds = 0;
|
|
|
this.currentTime = "00:00";
|
|
|
+ this.currentTime = "00:00";
|
|
|
this.lastSongPath = this.currentSong.filePath;
|
|
|
this.justSwitched = true; // 标记歌曲刚刚切换
|
|
|
|
|
|
@@ -9695,8 +9709,8 @@ export struct LocalMusic {
|
|
|
}
|
|
|
|
|
|
// 检查是否有远程设备可用
|
|
|
- const remoteDevices = outputDevice.devices.filter(device =>
|
|
|
- device.castCategory === avSession.AVCastCategory.CATEGORY_REMOTE
|
|
|
+ const remoteDevices = outputDevice.devices.filter(device =>
|
|
|
+ device.castCategory === avSession.AVCastCategory.CATEGORY_REMOTE
|
|
|
);
|
|
|
|
|
|
return remoteDevices.length > 0;
|
|
|
@@ -9742,7 +9756,7 @@ export struct LocalMusic {
|
|
|
private async handleCastingPlayNext(): Promise<void> {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('投播状态下切换下一首');
|
|
|
-
|
|
|
+
|
|
|
// 计算下一首的索引
|
|
|
let nextIndex = this.curIndex;
|
|
|
if (this.playType === 1) { // 单曲循环
|
|
|
@@ -9782,7 +9796,7 @@ export struct LocalMusic {
|
|
|
private async handleCastingPlayPrevious(): Promise<void> {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('投播状态下切换上一首');
|
|
|
-
|
|
|
+
|
|
|
// 计算上一首的索引
|
|
|
let prevIndex = this.curIndex;
|
|
|
if (this.playType === 1) { // 单曲循环
|
|
|
@@ -9847,7 +9861,7 @@ export struct LocalMusic {
|
|
|
private async checkAndRestoreCastingState(): Promise<void> {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('检查当前投播状态...');
|
|
|
-
|
|
|
+
|
|
|
const session = this.avSessionController.getAvSession();
|
|
|
if (!session) {
|
|
|
LogUtils.getInstance().LOGI('AVSession不可用,跳过投播状态检查');
|
|
|
@@ -9867,27 +9881,27 @@ export struct LocalMusic {
|
|
|
// 检查是否为远程设备(投播状态)
|
|
|
if (currentDevice.castCategory === avSession.AVCastCategory.CATEGORY_REMOTE) {
|
|
|
LogUtils.getInstance().LOGI('检测到投播状态,恢复投播控制器');
|
|
|
-
|
|
|
+
|
|
|
// 恢复投播状态
|
|
|
this.currentCastDevice = currentDevice;
|
|
|
this.isCasting = true;
|
|
|
-
|
|
|
+
|
|
|
// 获取投播控制器
|
|
|
this.castController = await session.getAVCastController();
|
|
|
if (this.castController) {
|
|
|
// 设置投播监听器
|
|
|
this.setPlaybackStateChangeListener();
|
|
|
-
|
|
|
+
|
|
|
// 查询当前播放状态
|
|
|
const playbackState = await this.castController.getAVPlaybackState();
|
|
|
if (playbackState) {
|
|
|
this.playbackStateChangeListener(playbackState);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 同步投播状态到AppStorage
|
|
|
let refToIsCasting: AbstractProperty<boolean> | undefined = AppStorage.ref('isCasting');
|
|
|
refToIsCasting?.set(true);
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('投播状态恢复成功');
|
|
|
ToastUtil.showToast('已连接到投播设备');
|
|
|
} else {
|
|
|
@@ -9896,7 +9910,7 @@ export struct LocalMusic {
|
|
|
} else {
|
|
|
LogUtils.getInstance().LOGI('当前为本地播放状态');
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`检查投播状态失败: ${error}`);
|
|
|
}
|
|
|
@@ -10004,7 +10018,7 @@ export struct LocalMusic {
|
|
|
// 检查UnifiedPlayerService是否已经有播放列表
|
|
|
const servicePlaylist = this.unifiedPlayerService.getPlaylist();
|
|
|
const serviceIndex = this.unifiedPlayerService.getCurrentIndex();
|
|
|
-
|
|
|
+
|
|
|
if (ArrayUtil.isEmpty(servicePlaylist)) {
|
|
|
// 如果服务没有播放列表,使用LocalMusic的播放列表
|
|
|
this.unifiedPlayerService.setPlaylist(this.songList, this.curIndex);
|
|
|
@@ -10016,7 +10030,7 @@ export struct LocalMusic {
|
|
|
this.curIndex = serviceIndex;
|
|
|
this.currentSong = serviceSong;
|
|
|
this.sonDataSource.pushArrayData(this.songList);
|
|
|
-
|
|
|
+
|
|
|
// 更新UI显示
|
|
|
this.videoUrl = serviceSong.filePath;
|
|
|
this.name = serviceSong.name;
|
|
|
@@ -10139,10 +10153,10 @@ export struct LocalMusic {
|
|
|
const caller = stack.split('\n')[2] || 'Unknown caller';
|
|
|
|
|
|
this.unifiedPlayerService.setPlaylist(this.songList, this.curIndex);
|
|
|
-
|
|
|
+
|
|
|
// 同步播放模式到UnifiedPlayerService
|
|
|
this.unifiedPlayerService.setPlayMode(this.playType);
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI(`LocalMusic: Playlist and play mode synced to UnifiedPlayerService - ${this.songList.length} songs, mode: ${this.playType}, caller: ${caller.trim()}`);
|
|
|
|
|
|
// 如果同步的是小播放列表,记录更多信息
|
|
|
@@ -10582,21 +10596,21 @@ export struct LocalMusic {
|
|
|
console.log('heanup setAvSessionListener error: avSessionController is null');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 注意:基础播控监听器(play, pause, playNext, playPrevious, seek等)
|
|
|
// 已经在UnifiedPlayerService中设置,这里不再重复设置,避免冲突
|
|
|
-
|
|
|
+
|
|
|
// 只设置LocalMusic特有的监听器
|
|
|
this.avSessionController.getAvSession()?.on('fastForward', this.sessionFastForwardCallback);
|
|
|
this.avSessionController.getAvSession()?.on('rewind', this.sessionRewindCallback);
|
|
|
this.avSessionController.getAvSession()?.on('setLoopMode', this.sessionSetLoopModeCallback);
|
|
|
this.avSessionController.getAvSession()?.on('toggleFavorite', this.sessionToggleFavoriteCallback);
|
|
|
-
|
|
|
+
|
|
|
// 设置投播设备变化监听器(这是投播功能的核心)
|
|
|
this.avSessionController.getAvSession()?.on('outputDeviceChange', this.sessionOutputDeviceChange);
|
|
|
-
|
|
|
+
|
|
|
console.log('heanup setAvSessionListener 完成 - 已跳过基础播控监听器(由UnifiedPlayerService处理)');
|
|
|
-
|
|
|
+
|
|
|
// 检查当前是否已经在投播状态
|
|
|
await this.checkAndRestoreCastingState();
|
|
|
}
|
|
|
@@ -10675,22 +10689,22 @@ export struct LocalMusic {
|
|
|
private sessionOutputDeviceChange = async (connectState: avSession.ConnectionState,
|
|
|
device: avSession.OutputDeviceInfo) => {
|
|
|
let currentDevice: avSession.DeviceInfo = device?.devices?.[0];
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI(`投播设备状态变化: ${connectState}, 设备类型: ${currentDevice?.castCategory}, 协议: ${currentDevice?.supportedProtocols}`);
|
|
|
-
|
|
|
+
|
|
|
if (currentDevice.castCategory === avSession.AVCastCategory.CATEGORY_REMOTE &&
|
|
|
connectState === avSession.ConnectionState.STATE_CONNECTED) {
|
|
|
// 设备连接成功,开始投播
|
|
|
this.currentCastDevice = currentDevice;
|
|
|
await this.startCasting();
|
|
|
-
|
|
|
+
|
|
|
// 检查设备支持的协议类型
|
|
|
if (currentDevice.supportedProtocols === avSession.ProtocolType.TYPE_CAST_PLUS_STREAM) {
|
|
|
LogUtils.getInstance().LOGI('设备支持Cast+投播协议');
|
|
|
} else if (currentDevice.supportedProtocols === avSession.ProtocolType.TYPE_DLNA) {
|
|
|
LogUtils.getInstance().LOGI('设备支持DLNA投播协议');
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 检查DRM支持能力
|
|
|
if (currentDevice.supportedDrmCapabilities?.includes('3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c')) {
|
|
|
LogUtils.getInstance().LOGI('设备支持chinaDRM');
|
|
|
@@ -10713,7 +10727,7 @@ export struct LocalMusic {
|
|
|
private async startCasting() {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('开始投播流程');
|
|
|
-
|
|
|
+
|
|
|
// 获取投播控制器
|
|
|
this.castController = await this.avSessionController.getAvSession()?.getAVCastController();
|
|
|
if (!this.castController) {
|
|
|
@@ -10721,36 +10735,36 @@ export struct LocalMusic {
|
|
|
ToastUtil.showToast('投播初始化失败');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('投播控制器获取成功');
|
|
|
-
|
|
|
+
|
|
|
// 设置投播状态监听
|
|
|
this.setPlaybackStateChangeListener();
|
|
|
-
|
|
|
+
|
|
|
// 暂停本地播放
|
|
|
this.pause();
|
|
|
-
|
|
|
+
|
|
|
// 初始化投播资源
|
|
|
this.initQueueItem();
|
|
|
-
|
|
|
+
|
|
|
// 准备并开始投播
|
|
|
await this.prepare();
|
|
|
-
|
|
|
+
|
|
|
// 更新投播状态
|
|
|
this.isCasting = true;
|
|
|
this.isCastPlaying = true;
|
|
|
this.castSeek = true;
|
|
|
-
|
|
|
+
|
|
|
// 同步到AppStorage
|
|
|
let refToIsCasting: AbstractProperty<boolean> | undefined = AppStorage.ref('isCasting');
|
|
|
refToIsCasting?.set(true);
|
|
|
-
|
|
|
+
|
|
|
// 申请长时任务,避免投播时应用被冻结
|
|
|
this.startCastingBackgroundTask();
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('投播启动成功');
|
|
|
ToastUtil.showToast('投播已开始');
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`投播启动失败: ${error}`);
|
|
|
ToastUtil.showToast(`投播启动失败: ${error}`);
|
|
|
@@ -10761,32 +10775,32 @@ export struct LocalMusic {
|
|
|
async changeCasting() {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('投播资源切换开始');
|
|
|
-
|
|
|
+
|
|
|
// 确保投播控制器可用
|
|
|
if (!this.castController) {
|
|
|
this.castController = await this.avSessionController.getAvSession()?.getAVCastController();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (!this.castController) {
|
|
|
LogUtils.getInstance().LOGI('投播控制器不可用,无法切换资源');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 初始化新的投播资源
|
|
|
this.initQueueItem();
|
|
|
-
|
|
|
+
|
|
|
// 准备并开始播放新资源
|
|
|
await this.prepare();
|
|
|
-
|
|
|
+
|
|
|
// 确保监听器已设置
|
|
|
this.setPlaybackStateChangeListener();
|
|
|
-
|
|
|
+
|
|
|
// 更新播放状态
|
|
|
this.isCastPlaying = true;
|
|
|
this.castSeek = true;
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI(`投播资源切换成功: ${this.currentSong?.name}`);
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`投播资源切换失败: ${error}`);
|
|
|
ToastUtil.showToast(`切换投播资源失败: ${error}`);
|
|
|
@@ -10796,33 +10810,33 @@ export struct LocalMusic {
|
|
|
public endCasting() {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('结束投播流程');
|
|
|
-
|
|
|
+
|
|
|
// 停止投播
|
|
|
this.avSessionController.getAvSession()?.stopCasting();
|
|
|
-
|
|
|
+
|
|
|
// 清理投播控制器监听
|
|
|
this.stopCast();
|
|
|
-
|
|
|
+
|
|
|
// 更新投播状态
|
|
|
this.isCasting = false;
|
|
|
this.isCastPlaying = false;
|
|
|
this.castSeek = false;
|
|
|
-
|
|
|
+
|
|
|
// 同步到AppStorage
|
|
|
let refToIsCasting: AbstractProperty<boolean> | undefined = AppStorage.ref('isCasting');
|
|
|
refToIsCasting?.set(false);
|
|
|
-
|
|
|
+
|
|
|
// 停止长时任务
|
|
|
this.stopCastingBackgroundTask();
|
|
|
-
|
|
|
+
|
|
|
// 恢复本地播放(可选)
|
|
|
// 建议保存投播断开时的进度,用于本地播放继续
|
|
|
const lastCastPosition = this.currentTime2 * 1000; // 投播的当前进度
|
|
|
-
|
|
|
+
|
|
|
// 暂停本地播放器,让用户手动选择是否继续播放
|
|
|
this.pause();
|
|
|
this.setIsPlaying(false);
|
|
|
-
|
|
|
+
|
|
|
// 如果需要自动恢复本地播放,可以取消注释以下代码
|
|
|
// if (lastCastPosition > 0) {
|
|
|
// this.seekTo(lastCastPosition.toString());
|
|
|
@@ -10830,10 +10844,10 @@ export struct LocalMusic {
|
|
|
// this.startPlayOrResumePlay();
|
|
|
// }, 500);
|
|
|
// }
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('投播结束成功');
|
|
|
ToastUtil.showToast('投播已结束');
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`结束投播失败: ${error}`);
|
|
|
ToastUtil.showToast(`结束投播失败: ${error}`);
|
|
|
@@ -10849,26 +10863,26 @@ export struct LocalMusic {
|
|
|
LogUtils.getInstance().LOGI('投播控制器为空,无法设置监听器');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
try {
|
|
|
// 监听播放状态变化
|
|
|
this.castController.on('playbackStateChange', 'all', this.playbackStateChangeListener);
|
|
|
-
|
|
|
+
|
|
|
// 监听播放完毕事件
|
|
|
this.castController.on('endOfStream', this.reloadCasting);
|
|
|
-
|
|
|
+
|
|
|
// 监听播控中心的上下一首切换
|
|
|
this.castController.on('playNext', this.playNextCallback);
|
|
|
this.castController.on('playPrevious', this.playPreviousCallback);
|
|
|
-
|
|
|
+
|
|
|
// 监听进度调节完成事件
|
|
|
this.castController.on('seekDone', this.seekDoneCallback);
|
|
|
-
|
|
|
+
|
|
|
// 监听错误事件
|
|
|
this.castController.on('error', this.castErrorCallback);
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('投播状态监听器设置完成');
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`设置投播监听器失败: ${error}`);
|
|
|
}
|
|
|
@@ -10919,7 +10933,7 @@ export struct LocalMusic {
|
|
|
private playbackStateChangeListener = (playbackState: avSession.AVPlaybackState) => {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI(`投播状态变化: ${playbackState.state}, 进度: ${playbackState?.position?.elapsedTime}ms`);
|
|
|
-
|
|
|
+
|
|
|
// 处理播放时长变化
|
|
|
const duration = playbackState?.extras?.duration;
|
|
|
if (typeof duration === 'number') {
|
|
|
@@ -10938,13 +10952,13 @@ export struct LocalMusic {
|
|
|
this.CONTROL_PlayStatus = PlayStatus.PLAY;
|
|
|
this.setIsPlaying(true);
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case avSession.PlaybackState.PLAYBACK_STATE_PAUSE:
|
|
|
this.isCastPlaying = false;
|
|
|
this.CONTROL_PlayStatus = PlayStatus.PAUSE;
|
|
|
this.setIsPlaying(false);
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case avSession.PlaybackState.PLAYBACK_STATE_STOP:
|
|
|
case avSession.PlaybackState.PLAYBACK_STATE_PREPARE:
|
|
|
case avSession.PlaybackState.PLAYBACK_STATE_INITIAL:
|
|
|
@@ -10952,21 +10966,21 @@ export struct LocalMusic {
|
|
|
this.CONTROL_PlayStatus = PlayStatus.INIT;
|
|
|
this.setIsPlaying(false);
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
default:
|
|
|
LogUtils.getInstance().LOGI(`未处理的投播状态: ${playbackState.state}`);
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 处理音量变化
|
|
|
if (playbackState?.volume !== undefined) {
|
|
|
LogUtils.getInstance().LOGI(`投播音量变化: ${playbackState.volume}`);
|
|
|
// 可以在这里同步音量到UI
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 更新UI显示
|
|
|
this.playChange();
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`处理投播状态变化失败: ${error}`);
|
|
|
}
|
|
|
@@ -10974,7 +10988,7 @@ export struct LocalMusic {
|
|
|
private reloadCasting = async () => {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('投播内容播放完毕,处理后续操作');
|
|
|
-
|
|
|
+
|
|
|
// 根据播放模式决定后续操作
|
|
|
switch (this.playType) {
|
|
|
case 0: // 顺序播放
|
|
|
@@ -10988,14 +11002,14 @@ export struct LocalMusic {
|
|
|
this.endCasting();
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case 1: // 单曲循环
|
|
|
LogUtils.getInstance().LOGI('单曲循环,重新播放当前歌曲');
|
|
|
this.initQueueItem();
|
|
|
await this.prepare();
|
|
|
this.isCastPlaying = true;
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case 2: // 列表循环
|
|
|
if (this.curIndex < this.songList.length - 1) {
|
|
|
// 播放下一首
|
|
|
@@ -11009,18 +11023,18 @@ export struct LocalMusic {
|
|
|
this.isCastPlaying = true;
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case 3: // 随机播放
|
|
|
LogUtils.getInstance().LOGI('随机播放下一首');
|
|
|
this.playNext();
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
default:
|
|
|
LogUtils.getInstance().LOGI('未知播放模式,停止投播');
|
|
|
this.endCasting();
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`处理投播完毕事件失败: ${error}`);
|
|
|
ToastUtil.showToast(`投播切换失败: ${error}`);
|
|
|
@@ -11030,19 +11044,19 @@ export struct LocalMusic {
|
|
|
LogUtils.getInstance().LOGI('投播设备请求播放下一首');
|
|
|
this.playNext();
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
public playPreviousCallback = (): void => {
|
|
|
LogUtils.getInstance().LOGI('投播设备请求播放上一首');
|
|
|
this.playPrevious();
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
// 进度调节完成回调
|
|
|
private seekDoneCallback = (position: number): void => {
|
|
|
LogUtils.getInstance().LOGI(`投播进度调节完成: ${position}ms`);
|
|
|
// 更新本地进度显示
|
|
|
this.positionChange(position);
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
// 投播错误回调
|
|
|
private castErrorCallback = (error: BusinessError): void => {
|
|
|
LogUtils.getInstance().LOGI(`投播错误: ${error.message || error}`);
|
|
|
@@ -11050,18 +11064,18 @@ export struct LocalMusic {
|
|
|
// 可以选择自动结束投播或重试
|
|
|
// this.endCasting();
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
// DRM许可证请求回调
|
|
|
private keyRequestCallback: avSession.KeyRequestCallback = async (assetId: string, requestData: Uint8Array) => {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI(`DRM许可证请求: ${assetId}`);
|
|
|
-
|
|
|
+
|
|
|
// 根据assetId获取对应的DRM url(需要根据实际情况配置)
|
|
|
let drmUrl: string = 'http://license.xxx.xxx.com:8080/drmproxy/getLicense';
|
|
|
-
|
|
|
+
|
|
|
// 从服务器获取许可证
|
|
|
let licenseResponseData = await this.getLicense(drmUrl, requestData);
|
|
|
-
|
|
|
+
|
|
|
if (licenseResponseData) {
|
|
|
// 处理DRM许可证响应
|
|
|
await this.castController?.processMediaKeyResponse(assetId, licenseResponseData);
|
|
|
@@ -11070,7 +11084,7 @@ export struct LocalMusic {
|
|
|
LogUtils.getInstance().LOGI('获取DRM许可证失败');
|
|
|
ToastUtil.showToast('DRM许可证获取失败');
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`DRM许可证处理失败: ${error}`);
|
|
|
ToastUtil.showToast(`DRM许可证处理失败: ${error}`);
|
|
|
@@ -11083,17 +11097,17 @@ export struct LocalMusic {
|
|
|
LogUtils.getInstance().LOGI('投播控制器或资源项为空,无法准备播放');
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('准备投播资源...');
|
|
|
-
|
|
|
+
|
|
|
// 准备播放,进行资源加载和缓冲,不会触发真正的播放
|
|
|
await this.castController.prepare(this.castItem);
|
|
|
LogUtils.getInstance().LOGI('投播资源准备完成');
|
|
|
-
|
|
|
+
|
|
|
// 启动播放,真正触发对端播放
|
|
|
await this.castController.start(this.castItem);
|
|
|
LogUtils.getInstance().LOGI('投播播放启动成功');
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
|
LogUtils.getInstance().LOGI(`投播准备或启动失败: ${errorMessage}`);
|
|
|
@@ -11111,13 +11125,13 @@ export struct LocalMusic {
|
|
|
}
|
|
|
|
|
|
LogUtils.getInstance().LOGI(`初始化投播资源: ${item.name}`);
|
|
|
-
|
|
|
+
|
|
|
let uri = fileUri.getUriFromPath(item.filePath);
|
|
|
let file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
|
|
|
|
|
|
// 获取当前播放进度,用于投播时同步进度
|
|
|
const currentPosition = this.unifiedPlayerService.getCurrentPosition();
|
|
|
-
|
|
|
+
|
|
|
this.castItem = {
|
|
|
itemId: this.curIndex,
|
|
|
description: {
|
|
|
@@ -11144,9 +11158,9 @@ export struct LocalMusic {
|
|
|
// drmScheme: '3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c',
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI(`投播资源初始化完成 - 标题: ${item.name}, 进度: ${currentPosition}ms, 时长: ${this.duration}ms`);
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`初始化投播资源失败: ${error}`);
|
|
|
ToastUtil.showToast(`初始化投播资源失败: ${error}`);
|
|
|
@@ -11156,7 +11170,7 @@ export struct LocalMusic {
|
|
|
async stopCast() {
|
|
|
try {
|
|
|
LogUtils.getInstance().LOGI('清理投播监听器');
|
|
|
-
|
|
|
+
|
|
|
if (this.castController) {
|
|
|
// 移除所有投播监听器
|
|
|
this.castController.off('playbackStateChange');
|
|
|
@@ -11166,14 +11180,14 @@ export struct LocalMusic {
|
|
|
this.castController.off('seekDone');
|
|
|
this.castController.off('error');
|
|
|
this.castController.off('keyRequest');
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('投播监听器清理完成');
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 清空投播控制器引用
|
|
|
this.castController = undefined;
|
|
|
this.castItem = undefined;
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`清理投播监听器失败: ${error}`);
|
|
|
}
|
|
|
@@ -11315,7 +11329,7 @@ export struct LocalMusic {
|
|
|
try {
|
|
|
// 这里需要根据实际的DRM服务实现许可证获取逻辑
|
|
|
LogUtils.getInstance().LOGI(`请求DRM许可证: ${drmUrl}`);
|
|
|
-
|
|
|
+
|
|
|
// 示例:使用HTTP请求获取许可证
|
|
|
// const response = await fetch(drmUrl, {
|
|
|
// method: 'POST',
|
|
|
@@ -11329,10 +11343,10 @@ export struct LocalMusic {
|
|
|
// const licenseData = await response.arrayBuffer();
|
|
|
// return new Uint8Array(licenseData);
|
|
|
// }
|
|
|
-
|
|
|
+
|
|
|
LogUtils.getInstance().LOGI('DRM许可证获取功能需要根据实际服务配置');
|
|
|
return undefined;
|
|
|
-
|
|
|
+
|
|
|
} catch (error) {
|
|
|
LogUtils.getInstance().LOGI(`获取DRM许可证失败: ${error}`);
|
|
|
return undefined;
|
|
|
@@ -11423,7 +11437,7 @@ export struct LocalMusic {
|
|
|
this.stopProgressTask();
|
|
|
this.CONTROL_PlayStatus = PlayStatus.INIT; // 初始状态,不是暂停
|
|
|
this.setIsPlaying(false);
|
|
|
-
|
|
|
+
|
|
|
// 强制更新UI状态
|
|
|
this.playChange()
|
|
|
this.watchStatus();
|
|
|
@@ -11476,7 +11490,7 @@ export struct LocalMusic {
|
|
|
private async seekTo(value: string) {
|
|
|
try {
|
|
|
const position = parseInt(value);
|
|
|
-
|
|
|
+
|
|
|
// 如果正在投播,使用投播进度控制
|
|
|
if (this.isCurrentlyCasting()) {
|
|
|
await this.handleCastingSeek(position);
|
|
|
@@ -11566,11 +11580,11 @@ export struct LocalMusic {
|
|
|
|
|
|
// 使用UnifiedPlayerService播放下一首,支持所有播放模式(包括随机播放)
|
|
|
await this.unifiedPlayerService.playNext();
|
|
|
-
|
|
|
+
|
|
|
// 智能同步播放列表到UnifiedPlayerService
|
|
|
const servicePlaylist = this.unifiedPlayerService.getPlaylist();
|
|
|
const serviceIndex = this.unifiedPlayerService.getCurrentIndex();
|
|
|
-
|
|
|
+
|
|
|
if (ArrayUtil.isEmpty(servicePlaylist)) {
|
|
|
// 如果服务没有播放列表,使用LocalMusic的播放列表
|
|
|
this.unifiedPlayerService.setPlaylist(this.songList, this.curIndex);
|