/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { hilog } from '@kit.PerformanceAnalysisKit'; import { common, wantAgent } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { avSession } from '@kit.AVSessionKit'; import { BackgroundTaskManager } from '../common/util/BackgroundTaskManager'; import { VideoItem } from '../viewmodel/VideoItem'; import { ImageUtil, PreferencesUtil } from '@pura/harmony-utils'; import { image } from '@kit.ImageKit'; import { SettingPage } from '../pages/SettingPage'; import { Utility } from '../common/util/Utility'; import LyricUtil from '../common/util/LyricUtil'; import ImageUtils from '../common/util/ImageUtils'; const TAG = 'onecold AvSessionController'; export class AvSessionController { private static instance: AvSessionController | null; private context: common.UIAbilityContext | undefined = undefined; private avSession: avSession.AVSession | undefined = undefined; private avSessionMetadata: avSession.AVMetadata | undefined = undefined; constructor(isVideo:boolean) { this.initAvSession(isVideo); } public static getInstance(isVideo:boolean): AvSessionController { if (!AvSessionController.instance) { AvSessionController.instance = new AvSessionController(isVideo); } return AvSessionController.instance; } public initAvSession(isVideo:boolean) { if(isVideo){ let isBgPlayOpen = PreferencesUtil.getBooleanSync(SettingPage.IS_BGPLAY_OPEN,true) if(!isBgPlayOpen) return } this.context = AppStorage.get('context'); if (!this.context) { hilog.info(0x0000, TAG, `session create failed : conext is undefined`); return; } let type: avSession.AVSessionType = isVideo ? 'video' : 'audio'; avSession.createAVSession(this.context, 'sessionName', type).then(async (avSession) => { this.avSession = avSession; hilog.info(0x0000, TAG, `session create successed : sessionId : ${this.avSession.sessionId}`); BackgroundTaskManager.startContinuousTask(this.context); this.setLaunchAbility(); this.avSession.activate(); this.avSession.setExtras({ requireAbilityList: ['url-cast'] }); }).catch((error:Error) => { console.error('Failed to create AVSession:', error); }); } private setLaunchAbility() { if (!this.context) { return; } const wantAgentInfo: wantAgent.WantAgentInfo = { wants: [ { bundleName: this.context.abilityInfo.bundleName, abilityName: this.context.abilityInfo.name } ], operationType: wantAgent.OperationType.START_ABILITIES, requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] }; wantAgent.getWantAgent(wantAgentInfo).then((agent) => { if (this.avSession) { this.avSession.setLaunchAbility(agent); } }); } public getAvSession() { return this.avSession; } public getAvSessionMetadata() { return this.avSessionMetadata; } public async setAVMetadata(curSource: VideoItem, duration: number) { if (curSource === undefined) { hilog.error(0x0000, TAG, 'SetAVMetadata Error, curSource is null'); return; } BackgroundTaskManager.startContinuousTask(this.context); const imagePixMap = await ImageUtil.getPixelMapFromMedia($r('app.media.ic_avatar7')); let metadata: avSession.AVMetadata = { assetId: `${curSource.filePath}`, title: curSource.name, filter: avSession.ProtocolType.TYPE_CAST_PLUS_STREAM|avSession.ProtocolType.TYPE_DLNA, mediaImage: imagePixMap, duration: duration, // 如果是DRM资源,配置支持的DRM uuid 用于设备过滤。非DRM资源不配置。 drmSchemes: ['3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c'] }; if (this.avSession) { this.avSession.setAVMetadata(metadata).then(() => { this.avSessionMetadata = metadata; hilog.info(0x0000, TAG, 'SetAVMetadata successfully'); }).catch((err: BusinessError) => { hilog.error(0x0000, TAG, `SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); }); } } public async setAVMetadataMusic(curSource: VideoItem, duration: number,lyricContent?:string) { if (curSource === undefined) { hilog.error(0x0000, TAG, 'SetAVMetadata Error, curSource is null'); return; } try { BackgroundTaskManager.startContinuousTask(this.context); let pixelMapPath:string|undefined = curSource.pixelMapPath let imagePixMap: PixelMap|string ; if(pixelMapPath){ imagePixMap = await ImageUtils.imagePathToPixelMap(pixelMapPath) }else{ imagePixMap = await ImageUtil.getPixelMapFromMedia($r('app.media.ic_avatar2')); } let lyric = '' if(lyricContent) lyric = LyricUtil.convertLyricToSimpleLrc(lyricContent) hilog.info(0x0000, TAG, 'onecold SetAVMetadata successfully curSource.pixelMapPath '+curSource.pixelMapPath); let metadata: avSession.AVMetadata = { assetId: `${curSource.filePath}`, title: curSource.name, filter: avSession.ProtocolType.TYPE_CAST_PLUS_STREAM|avSession.ProtocolType.TYPE_DLNA, artist: curSource.artist, mediaImage: imagePixMap, duration: duration, lyric:lyric, }; if (this.avSession) { this.avSession.setAVMetadata(metadata).then(() => { this.avSessionMetadata = metadata; hilog.info(0x0000, TAG, 'SetAVMetadata successfully'); }).catch((err: BusinessError) => { hilog.error(0x0000, TAG, `SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); }); } } catch (error) { console.warn(' setAVMetadataMusic:', error.message); } } public setAvSessionPlayState(playbackState: avSession.AVPlaybackState) { if (this.avSession) { BackgroundTaskManager.startContinuousTask(this.context); this.avSession.setAVPlaybackState(playbackState, (err: BusinessError) => { if (err) { hilog.error(0x0000, TAG, `SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); } else { hilog.info(0x0000, TAG, 'SetAVPlaybackState successfully'); } }); } } async unregisterSessionListener() { if (!this.avSession) { return; } this.avSession.off('play'); this.avSession.off('pause'); this.avSession.off('playNext'); this.avSession.off('playPrevious'); this.avSession.off('setLoopMode'); this.avSession.off('seek'); this.avSession.off('toggleFavorite'); this.avSession.destroy() BackgroundTaskManager.stopContinuousTask(this.context); } }