diff --git a/zh-cn/application-dev/media/using-avsession-controller.md b/zh-cn/application-dev/media/using-avsession-controller.md index 37aea26eb24fd8eeeb011a3ca2a9be5eda43218c..33ae995170abd813a6a9e36c1e312e2f30c8d0d3 100644 --- a/zh-cn/application-dev/media/using-avsession-controller.md +++ b/zh-cn/application-dev/media/using-avsession-controller.md @@ -12,10 +12,16 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 ## 接口说明 -媒体会话控制方使用的关键接口如下表所示。接口返回值有两种返回形式:callback和promise,下表中为callback形式接口,promise和callback只是返回值方式不一样,功能相同。 +媒体会话控制方使用的关键接口包括两类: +1. 直接通过import得到的AVSessionManager来调用,例如接口`AVSessionManager.createController(sessionId)`。 +2. 通过AVSessionController对象来调用,例如接口`controller.getAVPlaybackState()`。 + +异步的JavaScript接口返回值有两种返回形式:callback和promise,本说明仅提供callback形式接口,promise和callback只是返回值方式不一样,功能相同。 更多API说明请参见[API文档](../reference/apis/js-apis-avsession.md)。 +### 直接通过AVSessionManager调用的接口 + | 接口名 | 说明 | | -------- | -------- | | getAllSessionDescriptors(callback: AsyncCallback<Array<Readonly<AVSessionDescriptor>>>): void | 获取系统中所有媒体会话的描述符。 | @@ -27,6 +33,25 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 | sendControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | 通过会话对应的AVSessionController向会话发送播控命令。 | | sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | 向置顶会话发送播控命令。 | +### 通过AVSessionController对象调用的接口 + +| 接口名 | 说明 | +| -------- | -------- | +| getAVPlaybackState(callback: AsyncCallback<AVPlaybackState>): void | 获取当前会话播放状态相关信息。 | +| getAVMetadata(callback: AsyncCallback<AVMetadata>): void | 获取会话元数据。 | +| getOutputDevice(callback: AsyncCallback<OutputDeviceInfo>): void | 获取播放设备信息。 | +| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback<void>): void | 发送按键事件到会话。| +| getLaunchAbility(callback: AsyncCallback<WantAgent>): void | 获取应用在会话中保存的WantAgent对象。 | +| isActive(callback: AsyncCallback<boolean>): void | 判断会话是否被激活。 | +| destroy(callback: AsyncCallback<void>): void | 销毁当前控制器,销毁后当前控制器不再可用。 | +| getValidCommands(callback: AsyncCallback<Array<AVControlCommandType>>): void | 获取会话支持的有效命令。 | +| sendControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | 通过会话控制器发送命令到其对应的会话。 | +| sendCommonCommand(command: string, args: {[key: string]: Object}, callback: AsyncCallback<void>): void10+ | 通过会话控制器发送自定义命令到其对应的会话。 | +| getAVQueueItems(callback: AsyncCallback<Array<AVQueueItem>>): void10+ | 获取当前播放列表相关信息。 | +| getAVQueueTitle(callback: AsyncCallback<string>): void10+ | 获取当前播放列表的名称。 | +| skipToQueueItem(itemId: number, callback: AsyncCallback<void>): void10+ | 设置指定播放列表单项的ID,发送给session端处理,session端可以选择对这个单项歌曲进行播放。 | +| getExtras(callback: AsyncCallback<{[key: string]: Object}>): void10+ | 获取媒体提供方设置的自定义媒体数据包。 | + ## 开发步骤 系统应用作为媒体会话控制方接入媒体会话的基本步骤如下所示: @@ -48,11 +73,11 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 AVSessionManager.createController(descriptor.sessionId).then((controller) => { g_controller.push(controller); }).catch((err) => { - console.error(`createController : ERROR : ${err.message}`); + console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); }); }); }).catch((err) => { - console.error(`getAllSessionDescriptors : ERROR : ${err.message}`); + console.error(`Failed to get all session descriptors. Code: ${err.code}, message: ${err.message}`); }); ``` @@ -74,7 +99,7 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 AVSessionManager.createController(session.sessionId).then((controller) => { g_controller.push(controller); }).catch((err) => { - console.info(`createController : ERROR : ${err.message}`); + console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); }); }); @@ -103,7 +128,7 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 // 注册服务异常监听 AVSessionManager.on('sessionServiceDie', () => { // 服务端异常,应用清理资源 - console.info("服务端异常"); + console.info('服务端异常'); }) ``` @@ -117,6 +142,10 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 - validCommandChange:媒体会话支持的有效命令变化事件。 - outputDeviceChange:播放设备变化事件。 - sessionDestroy:媒体会话销毁事件。 + - sessionEvent: 媒体会话自定义事件变化事件。 + - extrasChange:媒体会话自定义数据包变化事件。 + - queueItemsChange: 媒体会话自定义播放列表变化事件。 + - queueTitleChange: 媒体会话自定义播放列表的名称变化事件。 媒体会话控制方可以根据实际需要监听对应的事件。 @@ -124,9 +153,9 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 // 注册会话激活状态变更监听 controller.on('activeStateChange', (isActive) => { if (isActive) { - console.info("控制器卡片按键高亮"); + console.info('控制器卡片按键高亮'); } else { - console.info("控制器卡片按键变更为无效"); + console.info('控制器卡片按键变更为无效'); } }); // 注册会话销毁监听 @@ -135,7 +164,7 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 controller.destroy().then(() => { console.info('destroy : SUCCESS '); }).catch((err) => { - console.info(`destroy : ERROR :${err.message}`); + console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); }); }); @@ -164,6 +193,22 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 controller.on('outputDeviceChange', (device) => { console.info(`on outputDeviceChange device isRemote : ${device.isRemote}`); }); + // 注册会话自定义事件变更监听 + controller.on('sessionEvent', (eventName, eventArgs) => { + console.info(`Received new session event, event name is ${eventName}, args are ${JSON.stringify(eventArgs)}`); + }); + // 注册会话自定义媒体数据包变更监听 + controller.on('extrasChange', (extras) => { + console.info(`Received custom media packet, packet data is ${JSON.stringify(extras)}`); + }); + // 注册会话自定义播放列表变更监听 + controller.on('queueItemsChange', (items) => { + console.info(`Caught queue items change, items length is ${items.length}`); + }); + // 注册会话自定义播放标题变更监听 + controller.on('queueTitleChange', (title) => { + console.info(`Caught queue title change, title is ${title}`); + }); ``` 4. 获取媒体会话提供方传递的媒体信息,可以用于界面展示,例如在播控中心展示当前播放的曲目及对应的播放状态。 @@ -186,6 +231,24 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 let avPlaybackState: AVSessionManager.AVPlaybackState = await controller.getAVPlaybackState(); console.info(`get playbackState by controller : ${avPlaybackState.state}`); console.info(`get favoriteState by controller : ${avPlaybackState.isFavorite}`); + // 获取session的播放列表信息 + let queueItems: Array = await controller.getAVQueueItems(); + console.info(`get queueItems length by controller : ${queueItems.length}`); + // 获取session的播放标题信息 + let queueTitle: string = await controller.getAVQueueTitle(); + console.info(`get queueTitle by controller : ${queueTitle}`); + // 获取session的自定义媒体数据包 + let extras: any = await controller.getExtras(); + console.info(`get custom media packets by controller : ${JSON.stringify(extras)}`); + // 获取session对应应用提供的ability信息 + let agent: WantAgent = await controller.getLaunchAbility(); + console.info(`get want agent info by controller : ${JSON.stringify(agent)}`); + // 获取session的当前播放位置信息 + let currentTime: number = controller.getRealPlaybackPositionSync(); + console.info(`get current playback time by controller : ${currentTime}`); + // 获取session支持的有效命令 + let validCommands: Array = await controller.getValidCommands(); + console.info(`get valid commands by controller : ${JSON.stringify(validCommands)}`); } ``` @@ -193,7 +256,6 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 作为媒体会话提供方的音视频应用在监听到相关的播控命令事件后,在相应的逻辑中可以完成对应的操作动作。 - ```ts async sendCommandToSessionByController() { // 假设我们已经有了一个对应session的controller,如何创建controller可以参考之前的案例 @@ -222,6 +284,23 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 let avCommand: AVSessionManager.AVControlCommand = {command:'playNext'}; controller.sendControlCommand(avCommand); } + // 下发自定义控制命令 + let commandName: string = 'custom command'; + let args = { + command : 'This is my custom command' + } + await controller.sendCommonCommand(commandName, args).then(() => { + console.info('SendCommonCommand successfully'); + }).catch((err) => { + console.error(`Failed to send common command. Code: ${err.code}, message: ${err.message}`); + }) + // 设置指定播放列表单项的ID,供session选择播放 + let queueItemId: number = 0; + await controller.skipToQueueItem(queueItemId).then(() => { + console.info('SkipToQueueItem successfully'); + }).catch((err) => { + console.error(`Failed to skip to queue item. Code: ${err.code}, message: ${err.message}`); + }); } ``` @@ -235,7 +314,7 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 // 销毁当前的controller,销毁后这个controller将不在可用 controller.destroy(function (err) { if (err) { - console.info(`Destroy controller ERROR : code: ${err.code}, message: ${err.message}`); + console.error(`Failed to destroy controller. Code: ${err.code}, message: ${err.message}`); } else { console.info('Destroy controller SUCCESS'); } diff --git a/zh-cn/application-dev/media/using-avsession-developer.md b/zh-cn/application-dev/media/using-avsession-developer.md index 40643ac3e089c5cf6cbd0e980cbab7b3b744d2fd..1435f7af6caafa2803349c33285be7dc41e67ee5 100644 --- a/zh-cn/application-dev/media/using-avsession-developer.md +++ b/zh-cn/application-dev/media/using-avsession-developer.md @@ -6,7 +6,7 @@ - 媒体会话元数据(AVMetadata): 用于描述媒体数据相关属性,包含标识当前媒体的ID(assetId),上一首媒体的ID(previousAssetId),下一首媒体的ID(nextAssetId),标题(title),专辑作者(author),专辑名称(album),词作者(writer),媒体时长(duration)等属性。 -- 媒体播放状态(AVPlaybackState):用于描述媒体播放状态的相关属性,包含当前媒体的播放状态(state)、播放位置(position)、播放倍速(speed)、缓冲时间(bufferedTime)、循环模式(loopMode)、是否收藏(isFavorite)等属性。 +- 媒体播放状态(AVPlaybackState):用于描述媒体播放状态的相关属性,包含当前媒体的播放状态(state)、播放位置(position)、播放倍速(speed)、缓冲时间(bufferedTime)、循环模式(loopMode)、是否收藏(isFavorite)、正在播放的媒体Id(activeItemId)、自定义媒体数据(extras)等属性。 ## 接口说明 @@ -21,8 +21,14 @@ | setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback<void>): void | 设置媒体会话播放状态。 | | setLaunchAbility(ability: WantAgent, callback: AsyncCallback<void>): void | 设置启动UIAbility。 | | getController(callback: AsyncCallback<AVSessionController>): void | 获取当前会话自身控制器。 | +| getOutputDevice(callback: AsyncCallback<OutputDeviceInfo>): void | 获取播放设备相关信息。 | | activate(callback: AsyncCallback<void>): void | 激活媒体会话。 | +| deactivate(callback: AsyncCallback<void>): void | 禁用当前会话。 | | destroy(callback: AsyncCallback<void>): void | 销毁媒体会话。 | +| setAVQueueItems(items: Array<AVQueueItem>, callback: AsyncCallback<void>): void 10+ | 设置媒体播放列表。 | +| setAVQueueTitle(title: string, callback: AsyncCallback<void>): void10+ | 设置媒体播放列表名称。 | +| dispatchSessionEvent(event: string, args: {[key: string]: Object}, callback: AsyncCallback<void>): void10+ | 设置会话内自定义事件。 | +| setExtras(extras: {[key: string]: Object}, callback: AsyncCallback<void>): void10+ | 设置键值对形式的自定义媒体数据包。| ## 开发步骤 @@ -31,11 +37,20 @@ 1. 通过AVSessionManager的方法创建并激活媒体会话。 ```ts + // 创建媒体会话需要获取应用的上下文(context)。开发者可以在应用的EntryAbility文件中设置一个全局变量来存储应用的上下文 + export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + globalThis.context = this.context; // 设置一个全局变量globalThis.context来存储应用的上下文 + } + // 其它EntryAbility类的方法 + } + + // 开始创建并激活媒体会话 import AVSessionManager from '@ohos.multimedia.avsession'; //导入AVSessionManager模块 // 创建session async createSession() { - let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(this.context, 'SESSION_NAME', 'audio'); + let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(globalThis.context, 'SESSION_NAME', 'audio'); session.activate(); console.info(`session create done : sessionId : ${session.sessionId}`); } @@ -50,18 +65,18 @@ ```ts async setSessionInfo() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // 播放器逻辑··· 引发媒体信息与播放状态的变更 // 设置必要的媒体信息 let metadata: AVSessionManager.AVMetadata = { - assetId: "0", - title: "TITLE", - artist: "ARTIST" + assetId: '0', + title: 'TITLE', + artist: 'ARTIST' }; session.setAVMetadata(metadata).then(() => { console.info('SetAVMetadata successfully'); }).catch((err) => { - console.info(`SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); + console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); }); // 简单设置一个播放状态 - 暂停 未收藏 let playbackState: AVSessionManager.AVPlaybackState = { @@ -70,7 +85,7 @@ }; session.setAVPlaybackState(playbackState, function (err) { if (err) { - console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); + console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); } else { console.info('SetAVPlaybackState successfully'); } @@ -82,42 +97,85 @@ 设置UIAbility时通过WantAgent接口实现,更多关于WantAgent的信息请参考[WantAgent](../reference/apis/js-apis-app-ability-wantAgent.md)。 ```ts - import WantAgent from "@ohos.app.ability.wantAgent"; + import wantAgent from "@ohos.app.ability.wantAgent"; ``` ```ts // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; let wantAgentInfo: { wants: [ { - bundleName: "com.example.musicdemo", - abilityName: "com.example.musicdemo.MainAbility" + bundleName: 'com.example.musicdemo', + abilityName: 'com.example.musicdemo.MainAbility' } ], - operationType: WantAgent.OperationType.START_ABILITIES, + operationType: wantAgent.OperationType.START_ABILITIES, requestCode: 0, - wantAgentFlags: [WantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] + wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] + } + wantAgent.getWantAgent(wantAgentInfo).then((agent) => { + session.setLaunchAbility(agent); + }) + ``` + +4. 设置一个即时的自定义会话事件,以供媒体控制方接收到事件后进行相应的操作。 + + > **说明:**
+ > 通过dispatchSessionEvent方法设置的数据不会保存在会话对象或AVSession服务中。 + + ```ts + // 假设已经创建了一个session,如何创建session可以参考 "1. 通过AVSessionManager的方法创建并激活媒体会话" + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let eventName = 'dynamic_lyric'; + let args = { + lyric : 'This is my lyric' } - WantAgent.getWantAgent(wantAgentInfo).then((agent) => { - session.setLaunchAbility(agent) + await session.dispatchSessionEvent(eventName, args).then(() => { + console.info('Dispatch session event successfully'); + }).catch((err) => { + console.error(`Failed to dispatch session event. Code: ${err.code}, message: ${err.message}`); }) ``` -4. 注册播控命令事件监听,便于响应用户通过媒体会话控制方,例如播控中心,下发的播控命令。 +5. 设置与当前会话相关的自定义媒体数据包,以供媒体控制方接收到事件后进行相应的操作。 + + > **说明:**
+ > 通过setExtras方法设置的数据包会被存储在AVSession服务中,数据的生命周期与会话一致;会话对应的Controller可以使用getExtras来获取该数据。 + + ```ts + // 假设已经创建了一个session,如何创建session可以参考之前的案例 + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let extras = { + extra : 'This is my custom meida packet' + } + await session.setExtras(extras).then(() => { + console.info('Set extras successfully'); + }).catch((err) => { + console.error(`Failed to set extras. Code: ${err.code}, message: ${err.message}`); + }) + ``` + +6. 注册播控命令事件监听,便于响应用户通过媒体会话控制方,例如播控中心,下发的播控命令。 + + 在session侧注册的监听分为`固定播控命令`和`高级播控事件`两种。 + + 4.1 固定控制命令的监听 + > **说明:** > - > 媒体会话提供方在注册相关播控命令事件监听时,监听的事件会在媒体会话控制方的getValidCommands()方法中体现,即媒体会话控制方会认为对应的方法有效,进而根据需要触发相应的事件。为了保证媒体会话控制方下发的播控命令可以被正常执行,媒体会话提供方请勿进行无逻辑的空实现监听。 + > 媒体会话提供方在注册相关固定播控命令事件监听时,监听的事件会在媒体会话控制方的getValidCommands()方法中体现,即媒体会话控制方会认为对应的方法有效,进而根据需要触发相应的事件。为了保证媒体会话控制方下发的播控命令可以被正常执行,媒体会话提供方请勿进行无逻辑的空实现监听。 + + Session侧的固定播控命令主要包括播放、暂停、上一首、下一首等基础操作命令,详细介绍请参见[AVControlCommand](../reference/apis/js-apis-avsession.md) ```ts async setListenerForMesFromController() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // 一般在监听器中会对播放器做相应逻辑处理 // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例 session.on('play', () => { console.info('on play , do play task'); - // do some tasks ··· }); session.on('pause', () => { @@ -136,15 +194,74 @@ console.info('on playPrevious , do playPrevious task'); // do some tasks ··· }); + session.on('fastForward', () => { + console.info(`on fastForward , do fastForward task`); + // do some tasks ··· + }); + session.on('rewind', () => { + console.info(`on rewind , do rewind task`); + // do some tasks ··· + }); + + session.on('seek', (time) => { + console.info(`on seek , the seek time is ${time}`); + // do some tasks ··· + }); + session.on('setSpeed', (speed) => { + console.info(`on setSpeed , the speed is ${speed}`); + // do some tasks ··· + }); + session.on('setLoopMode', (mode) => { + console.info(`on setLoopMode , the loop mode is ${mode}`); + // do some tasks ··· + }); + session.on('toggleFavorite', (assetId) => { + console.info(`on toggleFavorite , the target asset Id is ${assetId}`); + // do some tasks ··· + }); + } + ``` + + 4.2 高级播控事件的监听 + + Session侧的可以注册的高级播控事件主要包括: + + - skipToQueueItem: 播放列表其中某项被选中的事件。 + - handleKeyEvent: 按键事件。 + - outputDeviceChange: 播放设备变化的事件。 + - commonCommand: 自定义控制命令变化的事件。 + + ```ts + async setListenerForMesFromController() { + // 假设已经创建了一个session,如何创建session可以参考之前的案例 + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + // 一般在监听器中会对播放器做相应逻辑处理 + // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例 + session.on('skipToQueueItem', (itemId) => { + console.info(`on skipToQueueItem , do skip task`); + // do some tasks ··· + }); + session.on('handleKeyEvent', (event) => { + console.info(`on handleKeyEvent , the event is ${JSON.stringify(event)}`); + // do some tasks ··· + }); + session.on('outputDeviceChange', (device) => { + console.info(`on outputDeviceChange , the device info is ${JSON.stringify(device)}`); + // do some tasks ··· + }); + session.on('commonCommand', (commandString, args) => { + console.info(`on commonCommand , command is ${commandString}, args are ${JSON.stringify(args)}`); + // do some tasks ··· + }); } ``` -5. 获取当前媒体会话自身的控制器,与媒体会话对应进行通信交互。 +7. 获取当前媒体会话自身的控制器,与媒体会话对应进行通信交互。 ```ts async createControllerFromSession() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // 通过已有session获取一个controller对象 let controller: AVSessionManager.AVSessionController = await session.getController(); @@ -163,13 +280,13 @@ } ``` -6. 音视频应用在退出,并且不需要继续播放时,及时取消监听以及销毁媒体会话释放资源。 +8. 音视频应用在退出,并且不需要继续播放时,及时取消监听以及销毁媒体会话释放资源。 取消播控命令监听的示例代码如下所示 : ```ts async unregisterSessionListener() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // 取消指定session下的相关监听 session.off('play'); @@ -177,6 +294,10 @@ session.off('stop'); session.off('playNext'); session.off('playPrevious'); + session.off('skipToQueueItem'); + session.off('handleKeyEvent'); + session.off('outputDeviceChange'); + session.off('commonCommand'); } ``` @@ -185,11 +306,11 @@ ```ts async destroySession() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // 主动销毁已创建的session session.destroy(function (err) { if (err) { - console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); + console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); } else { console.info('Destroy : SUCCESS '); } diff --git a/zh-cn/application-dev/media/using-distributed-avsession.md b/zh-cn/application-dev/media/using-distributed-avsession.md index a37f93e62b264f18e0c080174d59cfaa7918bced..bd1d0cecf89a6348fa2f473c611396cd9be3b316 100644 --- a/zh-cn/application-dev/media/using-distributed-avsession.md +++ b/zh-cn/application-dev/media/using-distributed-avsession.md @@ -38,13 +38,13 @@ audioDevices = data; console.info('Promise returned to indicate that the device list is obtained.'); }).catch((err) => { - console.info(`getDevices : ERROR : ${err.message}`); + console.error(`Failed to get devices. Code: ${err.code}, message: ${err.message}`); }); AVSessionManager.castAudio('all', audioDevices).then(() => { console.info('createController : SUCCESS'); }).catch((err) => { - console.info(`createController : ERROR : ${err.message}`); + console.error(`Failed to cast audio. Code: ${err.code}, message: ${err.message}`); }); ```