1# 媒体会话提供方 2 3音视频应用在实现音视频功能的同时,需要作为媒体会话提供方接入媒体会话,在媒体会话控制方(例如播控中心)中展示媒体相关信息,及响应媒体会话控制方下发的播控命令。 4 5## 基本概念 6 7- 媒体会话元数据(AVMetadata): 用于描述媒体数据相关属性,包含标识当前媒体的ID(assetId),上一首媒体的ID(previousAssetId),下一首媒体的ID(nextAssetId),标题(title),专辑作者(author),专辑名称(album),词作者(writer),媒体时长(duration)等属性。 8 9- 媒体播放状态(AVPlaybackState):用于描述媒体播放状态的相关属性,包含当前媒体的播放状态(state)、播放位置(position)、播放倍速(speed)、缓冲时间(bufferedTime)、循环模式(loopMode)、是否收藏(isFavorite)等属性。 10 11## 接口说明 12 13媒体会话提供方使用的关键接口如下表所示。接口返回值有两种返回形式:callback和promise,下表中为callback形式接口,promise和callback只是返回值方式不一样,功能相同。 14 15更多API说明请参见[API文档](../reference/apis/js-apis-avsession.md)。 16 17| 接口名 | 说明 | 18| -------- | -------- | 19| createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback<AVSession>): void | 创建媒体会话。<br/>一个UIAbility只能存在一个媒体会话,重复创建会失败。 | 20| setAVMetadata(data: AVMetadata, callback: AsyncCallback<void>): void | 设置媒体会话元数据。 | 21| setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback<void>): void | 设置媒体会话播放状态。 | 22| setLaunchAbility(ability: WantAgent, callback: AsyncCallback<void>): void | 设置启动UIAbility。 | 23| getController(callback: AsyncCallback<AVSessionController>): void | 获取当前会话自身控制器。 | 24| activate(callback: AsyncCallback<void>): void | 激活媒体会话。 | 25| destroy(callback: AsyncCallback<void>): void | 销毁媒体会话。 | 26 27## 开发步骤 28 29音视频应用作为媒体会话提供方接入媒体会话的基本步骤如下所示: 30 311. 通过AVSessionManager的方法创建并激活媒体会话。 32 33 ```ts 34 import AVSessionManager from '@ohos.multimedia.avsession'; //导入AVSessionManager模块 35 36 // 创建session 37 async createSession() { 38 let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(this.context, 'SESSION_NAME', 'audio'); 39 session.activate(); 40 console.info(`session create done : sessionId : ${session.sessionId}`); 41 } 42 ``` 43 442. 跟随媒体信息的变化,及时设置媒体会话信息。需要设置的媒体会话信息主要包括: 45 - 媒体会话元数据AVMetadata。 46 - 媒体播放状态AVPlaybackState。 47 48 音视频应用设置的媒体会话信息,会被媒体会话控制方通过AVSessionController相关方法获取后进行显示或处理。 49 50 ```ts 51 async setSessionInfo() { 52 // 假设已经创建了一个session,如何创建session可以参考之前的案例 53 let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; 54 // 播放器逻辑··· 引发媒体信息与播放状态的变更 55 // 设置必要的媒体信息 56 let metadata: AVSessionManager.AVMetadata = { 57 assetId: "0", 58 title: "TITLE", 59 artist: "ARTIST" 60 }; 61 session.setAVMetadata(metadata).then(() => { 62 console.info('SetAVMetadata successfully'); 63 }).catch((err) => { 64 console.info(`SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); 65 }); 66 // 简单设置一个播放状态 - 暂停 未收藏 67 let playbackState: AVSessionManager.AVPlaybackState = { 68 state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, 69 isFavorite:false 70 }; 71 session.setAVPlaybackState(playbackState, function (err) { 72 if (err) { 73 console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); 74 } else { 75 console.info('SetAVPlaybackState successfully'); 76 } 77 }); 78 } 79 ``` 80 813. 设置用于被媒体会话控制方拉起的UIAbility。当用户操作媒体会话控制方的界面时,例如点击播控中心的卡片,可以拉起此处配置的UIAbility。 82 设置UIAbility时通过WantAgent接口实现,更多关于WantAgent的信息请参考[WantAgent](../reference/apis/js-apis-app-ability-wantAgent.md)。 83 84 ```ts 85 import WantAgent from "@ohos.app.ability.wantAgent"; 86 ``` 87 88 ```ts 89 // 假设已经创建了一个session,如何创建session可以参考之前的案例 90 let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; 91 let wantAgentInfo = { 92 wants: [ 93 { 94 bundleName: "com.example.musicdemo", 95 abilityName: "com.example.musicdemo.MainAbility" 96 } 97 ], 98 operationType: WantAgent.OperationType.START_ABILITIES, 99 requestCode: 0, 100 wantAgentFlags: [WantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 101 } 102 WantAgent.getWantAgent(wantAgentInfo).then((agent) => { 103 session.setLaunchAbility(agent) 104 }) 105 ``` 106 1074. 注册播控命令事件监听,便于响应用户通过媒体会话控制方,例如播控中心,下发的播控命令。 108 > **说明:** 109 > 110 > 媒体会话提供方在注册相关播控命令事件监听时,监听的事件会在媒体会话控制方的getValidCommands()方法中体现,即媒体会话控制方会认为对应的方法有效,进而根据需要触发相应的事件。为了保证媒体会话控制方下发的播控命令可以被正常执行,媒体会话提供方请勿进行无逻辑的空实现监听。 111 112 ```ts 113 async setListenerForMesFromController() { 114 // 假设已经创建了一个session,如何创建session可以参考之前的案例 115 let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; 116 // 一般在监听器中会对播放器做相应逻辑处理 117 // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例 118 session.on('play', () => { 119 console.info('on play , do play task'); 120 121 // do some tasks ··· 122 }); 123 session.on('pause', () => { 124 console.info('on pause , do pause task'); 125 // do some tasks ··· 126 }); 127 session.on('stop', () => { 128 console.info('on stop , do stop task'); 129 // do some tasks ··· 130 }); 131 session.on('playNext', () => { 132 console.info('on playNext , do playNext task'); 133 // do some tasks ··· 134 }); 135 session.on('playPrevious', () => { 136 console.info('on playPrevious , do playPrevious task'); 137 // do some tasks ··· 138 }); 139 } 140 ``` 141 1425. 获取当前媒体会话自身的控制器,与媒体会话对应进行通信交互。 143 144 ```ts 145 async createControllerFromSession() { 146 // 假设已经创建了一个session,如何创建session可以参考之前的案例 147 let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; 148 149 // 通过已有session获取一个controller对象 150 let controller: AVSessionManager.AVSessionController = await session.getController(); 151 152 // controller可以与原session对象进行基本的通信交互,比如下发播放命令 153 let avCommand: AVSessionManager.AVControlCommand = {command:'play'}; 154 controller.sendControlCommand(avCommand); 155 156 // 或者做状态变更监听 157 controller.on('playbackStateChange', 'all', (state: AVSessionManager.AVPlaybackState) => { 158 159 // do some things 160 }); 161 162 // controller可以做的操作还有很多,具体可以参考媒体会话控制方相关的说明 163 } 164 ``` 165 1666. 音视频应用在退出,并且不需要继续播放时,及时取消监听以及销毁媒体会话释放资源。 167 取消播控命令监听的示例代码如下所示 : 168 169 ```ts 170 async unregisterSessionListener() { 171 // 假设已经创建了一个session,如何创建session可以参考之前的案例 172 let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; 173 174 // 取消指定session下的相关监听 175 session.off('play'); 176 session.off('pause'); 177 session.off('stop'); 178 session.off('playNext'); 179 session.off('playPrevious'); 180 } 181 ``` 182 183 销毁媒体会话示例代码如下所示: 184 185 ```ts 186 async destroySession() { 187 // 假设已经创建了一个session,如何创建session可以参考之前的案例 188 let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; 189 // 主动销毁已创建的session 190 session.destroy(function (err) { 191 if (err) { 192 console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); 193 } else { 194 console.info('Destroy : SUCCESS '); 195 } 196 }); 197 } 198 ``` 199