From 3da94302961ea4606fa4ea1011c698c007ed068e Mon Sep 17 00:00:00 2001 From: zhangkai269 Date: Wed, 30 Aug 2023 11:05:39 +0800 Subject: [PATCH] =?UTF-8?q?fixed=20fa7d23d=20from=20https://gitee.com/zhan?= =?UTF-8?q?gkai269/docs=5F3/pulls/23495=20arkts=E6=A0=BC=E5=BC=8F=E6=95=B4?= =?UTF-8?q?=E6=94=B9(audio,=20avsession)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangkai269 --- .../media/audio-input-device-management.md | 1 + .../media/audio-output-device-management.md | 1 + .../audio-recording-stream-management.md | 2 +- .../media/local-avsession-overview.md | 9 +- zh-cn/application-dev/media/mic-management.md | 97 +++++---- .../using-audiocapturer-for-recording.md | 10 +- .../media/using-avsession-controller.md | 181 +++++++++-------- .../media/using-avsession-developer.md | 191 ++++++++++-------- .../media/using-distributed-avsession.md | 39 ++-- 9 files changed, 294 insertions(+), 237 deletions(-) diff --git a/zh-cn/application-dev/media/audio-input-device-management.md b/zh-cn/application-dev/media/audio-input-device-management.md index 32a4b1d27b..824949799d 100644 --- a/zh-cn/application-dev/media/audio-input-device-management.md +++ b/zh-cn/application-dev/media/audio-input-device-management.md @@ -65,6 +65,7 @@ audioRoutingManager.off('deviceChange', (deviceChanged: audio.DeviceChangeAction > 用户可以选择连接一组音频设备(如一对蓝牙耳机),但系统侧只感知为一个设备,该组设备共用一个设备id。 ```ts +import audio from '@ohos.multimedia.audio'; let inputAudioDeviceDescriptor: audio.AudioDeviceDescriptors = [{ deviceRole : audio.DeviceRole.INPUT_DEVICE, deviceType : audio.DeviceType.EARPIECE, diff --git a/zh-cn/application-dev/media/audio-output-device-management.md b/zh-cn/application-dev/media/audio-output-device-management.md index 5d0eb28804..fa24e22a10 100644 --- a/zh-cn/application-dev/media/audio-output-device-management.md +++ b/zh-cn/application-dev/media/audio-output-device-management.md @@ -66,6 +66,7 @@ audioRoutingManager.off('deviceChange'); > 用户可以选择连接一组音频设备(如一对蓝牙耳机),但系统侧只感知为一个设备,该组设备共用一个设备ID。 ```ts +import audio from '@ohos.multimedia.audio'; let outputAudioDeviceDescriptor: audio.AudioDeviceDescriptors = [{ deviceRole : audio.DeviceRole.OUTPUT_DEVICE, deviceType : audio.DeviceType.SPEAKER, diff --git a/zh-cn/application-dev/media/audio-recording-stream-management.md b/zh-cn/application-dev/media/audio-recording-stream-management.md index 6ccbd29d8e..51b3637cbe 100644 --- a/zh-cn/application-dev/media/audio-recording-stream-management.md +++ b/zh-cn/application-dev/media/audio-recording-stream-management.md @@ -61,7 +61,7 @@ console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); - let devDescriptor = AudioCapturerChangeInfoArray[i].deviceDescriptors; + let devDescriptor: audio.AudioDeviceDescriptors = AudioCapturerChangeInfoArray[i].deviceDescriptors; for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); diff --git a/zh-cn/application-dev/media/local-avsession-overview.md b/zh-cn/application-dev/media/local-avsession-overview.md index e71021292b..8bcbead894 100644 --- a/zh-cn/application-dev/media/local-avsession-overview.md +++ b/zh-cn/application-dev/media/local-avsession-overview.md @@ -38,8 +38,9 @@ import AVSessionManager from '@ohos.multimedia.avsession'; ```ts // 创建session -async createSession() { - let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(this.context, 'SESSION_NAME', 'audio'); +let context: Context = this.context; +async function createSession() { + let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); console.info(`session create done : sessionId : ${session.sessionId}`); } ``` @@ -48,9 +49,9 @@ async createSession() { ```ts // 创建controller -async createController() { +async function createController() { // 获取到所有存活session的描述符列表 - let descriptorsArray: Array> = await AVSessionManager.getAllSessionDescriptors(); + let descriptorsArray: Array = await AVSessionManager.getAllSessionDescriptors(); if (descriptorsArray.length > 0) { // 为了演示,我们简单取第一个描述符的sessionId用来创建对应的controller let sessionId: string = descriptorsArray[0].sessionId; diff --git a/zh-cn/application-dev/media/mic-management.md b/zh-cn/application-dev/media/mic-management.md index 5752716815..f69897c329 100644 --- a/zh-cn/application-dev/media/mic-management.md +++ b/zh-cn/application-dev/media/mic-management.md @@ -12,8 +12,8 @@ ```ts import audio from '@ohos.multimedia.audio'; - - let audioVolumeGroupManager; + + let audioVolumeGroupManager: audio.AudioVolumeGroupManager; async function loadVolumeGroupManager() { //创建audioVolumeGroupManager对象 const groupid = audio.DEFAULT_VOLUME_GROUP_ID; audioVolumeGroupManager = await audio.getAudioManager().getVolumeManager().getVolumeGroupManager(groupid); @@ -28,7 +28,7 @@ ```ts async function on() { //监听麦克风状态变化 - audioVolumeGroupManager.on('micStateChange', (micStateChange) => { + audioVolumeGroupManager.on('micStateChange', (micStateChange: audio.MicStateChangeEvent) => { console.info(`Current microphone status is: ${micStateChange.mute} `); }); } @@ -38,7 +38,7 @@ ```ts async function isMicrophoneMute() { //查询麦克风是否静音 - await audioVolumeGroupManager.isMicrophoneMute().then((value) => { + await audioVolumeGroupManager.isMicrophoneMute().then((value: boolean) => { console.info(`isMicrophoneMute is: ${value}.`); }); } @@ -64,51 +64,48 @@ 参考以下示例,完成从设置麦克风静音到取消麦克风静音的过程。 ```ts -import audio from '@ohos.multimedia.audio'; - -@Entry -@Component -struct AudioVolumeGroup { - private audioVolumeGroupManager: audio.AudioVolumeGroupManager; - - async loadVolumeGroupManager() { - const groupid = audio.DEFAULT_VOLUME_GROUP_ID; - this.audioVolumeGroupManager = await audio.getAudioManager().getVolumeManager().getVolumeGroupManager(groupid); - console.info('audioVolumeGroupManager------create-------success.'); - } + import audio from '@ohos.multimedia.audio'; + + let audioVolumeGroupManager: audio.AudioVolumeGroupManager; + + async function loadVolumeGroupManager() { + const groupid = audio.DEFAULT_VOLUME_GROUP_ID; + audioVolumeGroupManager = await audio.getAudioManager().getVolumeManager().getVolumeGroupManager(groupid); + console.info('audioVolumeGroupManager------create-------success.'); + } + + async function on() { //监听麦克风状态变化 + await loadVolumeGroupManager(); + audioVolumeGroupManager.on('micStateChange', (micStateChange) => { + console.info(`Current microphone status is: ${micStateChange.mute} `); + }); + } + async function isMicrophoneMute() { //查询麦克风是否静音 + await audioVolumeGroupManager.isMicrophoneMute().then((value) => { + console.info(`isMicrophoneMute is: ${value}.`); + }); + } + async function setMicrophoneMuteTrue() { //设置麦克风静音 + await loadVolumeGroupManager(); + await audioVolumeGroupManager.setMicrophoneMute(true).then(() => { + console.info('setMicrophoneMute to mute.'); + }); + } + async function setMicrophoneMuteFalse() { //取消麦克风静音 + await loadVolumeGroupManager(); + await audioVolumeGroupManager.setMicrophoneMute(false).then(() => { + console.info('setMicrophoneMute to not mute.'); + }); + } + async function test(){ + await on(); + await isMicrophoneMute(); + await setMicrophoneMuteTrue(); + await isMicrophoneMute(); + await setMicrophoneMuteFalse(); + await isMicrophoneMute(); + await setMicrophoneMuteTrue(); + await isMicrophoneMute(); + } - async on() { //监听麦克风状态变化 - await this.loadVolumeGroupManager(); - this.audioVolumeGroupManager.on('micStateChange', (micStateChange) => { - console.info(`Current microphone status is: ${micStateChange.mute} `); - }); - } - async isMicrophoneMute() { //查询麦克风是否静音 - await this.audioVolumeGroupManager.isMicrophoneMute().then((value) => { - console.info(`isMicrophoneMute is: ${value}.`); - }); - } - async setMicrophoneMuteTrue() { //设置麦克风静音 - await this.loadVolumeGroupManager(); - await this.audioVolumeGroupManager.setMicrophoneMute(true).then(() => { - console.info('setMicrophoneMute to mute.'); - }); - } - async setMicrophoneMuteFalse() { //取消麦克风静音 - await this.loadVolumeGroupManager(); - await this.audioVolumeGroupManager.setMicrophoneMute(false).then(() => { - console.info('setMicrophoneMute to not mute.'); - }); - } - async test(){ - await this.on(); - await this.isMicrophoneMute(); - await this.setMicrophoneMuteTrue(); - await this.isMicrophoneMute(); - await this.setMicrophoneMuteFalse(); - await this.isMicrophoneMute(); - await this.setMicrophoneMuteTrue(); - await this.isMicrophoneMute(); - } -} ``` diff --git a/zh-cn/application-dev/media/using-audiocapturer-for-recording.md b/zh-cn/application-dev/media/using-audiocapturer-for-recording.md index f191727753..a02a53a848 100644 --- a/zh-cn/application-dev/media/using-audiocapturer-for-recording.md +++ b/zh-cn/application-dev/media/using-audiocapturer-for-recording.md @@ -21,24 +21,24 @@ AudioCapturer是音频采集器,用于录制PCM(Pulse Code Modulation)音 import audio from '@ohos.multimedia.audio'; import fs from '@ohos.file.fs'; import { BusinessError } from '@ohos.base'; - + let audioStreamInfo: audio.AudioStreamInfo = { samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, channels: audio.AudioChannel.CHANNEL_2, sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW }; - + let audioCapturerInfo: audio.AudioCapturerInfo = { source: audio.SourceType.SOURCE_TYPE_MIC, capturerFlags: 0 }; - + let audioCapturerOptions: audio.AudioCapturerOptions = { streamInfo: audioStreamInfo, capturerInfo: audioCapturerInfo }; - + audio.createAudioCapturer(audioCapturerOptions, (err, data) => { if (err) { console.error(`Invoke createAudioCapturer failed, code is ${err.code}, message is ${err.message}`); @@ -169,7 +169,7 @@ export default class AudioCapturerDemo { while (numBuffersToCapture) { let bufferSize = await this.audioCapturer.getBufferSize(); let buffer = await this.audioCapturer.read(bufferSize, true); - let options = { + let options: Options = { offset: count * bufferSize, length: bufferSize }; diff --git a/zh-cn/application-dev/media/using-avsession-controller.md b/zh-cn/application-dev/media/using-avsession-controller.md index 63e0dac552..7bda9bf6ce 100644 --- a/zh-cn/application-dev/media/using-avsession-controller.md +++ b/zh-cn/application-dev/media/using-avsession-controller.md @@ -58,27 +58,28 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 ```ts //导入AVSessionManager模块 - import AVSessionManager from '@ohos.multimedia.avsession'; - + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + // 全局变量定义 let g_controller = new Array(); let g_centerSupportCmd:Set = new Set(['play', 'pause', 'playNext', 'playPrevious', 'fastForward', 'rewind', 'seek','setSpeed', 'setLoopMode', 'toggleFavorite']); let g_validCmd:Set; // 获取会话描述符,创建控制器 AVSessionManager.getAllSessionDescriptors().then((descriptors) => { - descriptors.forEach((descriptor) => { - AVSessionManager.createController(descriptor.sessionId).then((controller) => { - g_controller.push(controller); - }).catch((err) => { - console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); - }); - }); - }).catch((err) => { - console.error(`Failed to get all session descriptors. Code: ${err.code}, message: ${err.message}`); + descriptors.forEach((descriptor) => { + AVSessionManager.createController(descriptor.sessionId).then((controller) => { + g_controller.push(controller); + }).catch((err: BusinessError) => { + console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); + }); + }); + }).catch((err: BusinessError) => { + console.error(`Failed to get all session descriptors. Code: ${err.code}, message: ${err.message}`); }); - + // 获取历史会话的描述符 - avSession.getHistoricalSessionDescriptors().then((descriptors) => { + AVSessionManager.getHistoricalSessionDescriptors().then((descriptors) => { console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors.length : ${descriptors.length}`); if (descriptors.length > 0){ console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].isActive : ${descriptors[0].isActive}`); @@ -87,7 +88,7 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].sessionId : ${descriptors[0].sessionId}`); console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].elementName.bundleName : ${descriptors[0].elementName.bundleName}`); } - }).catch((err) => { + }).catch((err: BusinessError) => { console.error(`Failed to get historical session descriptors, error code: ${err.code}, error message: ${err.message}`); }); ``` @@ -103,42 +104,46 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 AVSession服务状态事件指sessionServiceDie,在AVSession服务异常时产生该事件。 ```ts + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + let g_controller = new Array(); // 注册会话创建监听,创建控制器 AVSessionManager.on('sessionCreate', (session) => { // 新增会话,需要创建控制器 AVSessionManager.createController(session.sessionId).then((controller) => { g_controller.push(controller); - }).catch((err) => { + }).catch((err: BusinessError) => { console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); }); }); - + // 注册系统会话销毁监听 AVSessionManager.on('sessionDestroy', (session) => { - let index = g_controller.findIndex((controller) => { - return controller.sessionId === session.sessionId; - }); - if (index !== 0) { - g_controller[index].destroy(); - g_controller.splice(index, 1); - } + let index = g_controller.findIndex((controller) => { + return controller.sessionId === session.sessionId; + }); + if (index !== 0) { + g_controller[index].destroy(); + g_controller.splice(index, 1); + } }); // 注册系统最高优先级会话变更监听 AVSessionManager.on('topSessionChange', (session) => { - let index = g_controller.findIndex((controller) => { - return controller.sessionId === session.sessionId; - }); - // 将该会话显示排到第一个 - if (index !== 0) { - g_controller.sort((a, b) => { - return a.sessionId === session.sessionId ? -1 : 0; - }); - } + let index = g_controller.findIndex((controller) => { + return controller.sessionId === session.sessionId; + }); + // 将该会话显示排到第一个 + if (index !== 0) { + g_controller.sort((a, b) => { + return a.sessionId === session.sessionId ? -1 : 0; + }); + } }); // 注册服务异常监听 AVSessionManager.on('sessionServiceDie', () => { - // 服务端异常,应用清理资源 - console.info(`服务端异常`); + // 服务端异常,应用清理资源 + console.info(`服务端异常`); }) ``` @@ -160,6 +165,13 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 媒体会话控制方可以根据实际需要监听对应的事件。 ```ts + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + let g_controller = new Array(); + let controller = g_controller[0]; + let g_validCmd:Set; + let g_centerSupportCmd:Set = new Set(['play', 'pause', 'playNext', 'playPrevious', 'fastForward', 'rewind', 'seek','setSpeed', 'setLoopMode', 'toggleFavorite']); // 注册会话激活状态变更监听 controller.on('activeStateChange', (isActive) => { if (isActive) { @@ -170,38 +182,39 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 }); // 注册会话销毁监听 controller.on('sessionDestroy', () => { - info(`on sessionDestroy : SUCCESS `); - controller.destroy().then(() => { - console.info(`destroy : SUCCESS`); - }).catch((err) => { - console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); - }); + console.info(`on sessionDestroy : SUCCESS `); + controller.destroy().then(() => { + console.info(`destroy : SUCCESS`); + }).catch((err: BusinessError) => { + console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); + }); }); - + // 注册元数据更新监听 let metaFilter = ['assetId', 'title', 'description']; - controller.on('metadataChange', metaFilter, (metadata) => { - console.info(`on metadataChange assetId : ${metadata.assetId}`); + controller.on('metadataChange', metaFilter, (metadata: AVSessionManager.AVMetadata) => { + console.info(`on metadataChange assetId : ${metadata.assetId}`); }); // 注册播放状态更新监听 let playbackFilter = ['state', 'speed', 'loopMode']; - controller.on('playbackStateChange', playbackFilter, (playbackState) => { - console.info(`on playbackStateChange state : ${playbackState.state}`); + controller.on('playbackStateChange', playbackFilter, (playbackState: AVSessionManager.AVPlaybackState) => { + console.info(`on playbackStateChange state : ${playbackState.state}`); }); // 注册会话支持的命令变更监听 controller.on('validCommandChange', (cmds) => { - console.info(`validCommandChange : SUCCESS : size : ${cmds.size}`); - console.info(`validCommandChange : SUCCESS : cmds : ${cmds.values()}`); - g_validCmd.clear(); - for (let c of g_centerSupportCmd) { - if (cmds.has(c)) { - g_validCmd.add(c); - } - } + console.info(`validCommandChange : SUCCESS : size : ${cmds.length}`); + console.info(`validCommandChange : SUCCESS : cmds : ${cmds.values()}`); + g_validCmd.clear(); + let centerSupportCmd = Array.from(g_centerSupportCmd.values()) + for (let c of centerSupportCmd) { + if (cmds.concat(c)) { + g_validCmd.add(c); + } + } }); // 注册输出设备变更监听 - controller.on('outputDeviceChange', (device) => { - console.info(`on outputDeviceChange device isRemote : ${device.isRemote}`); + controller.on('outputDeviceChange', (state, device) => { + console.info(`outputDeviceChange device are : ${JSON.stringify(device)}`); }); // 注册会话自定义事件变更监听 controller.on('sessionEvent', (eventName, eventArgs) => { @@ -224,40 +237,41 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 4. 获取媒体会话提供方传递的媒体信息,可以用于界面展示,例如在播控中心展示当前播放的曲目及对应的播放状态。 ```ts - async getInfoFromSessionByController() { + import AVSessionManager from '@ohos.multimedia.avsession'; + async function getInfoFromSessionByController() { // 假设我们已经有了一个对应session的controller,如何创建controller可以参考之前的案例 - let controller: AVSessionManager.AVSessionController = ALLREADY_HAVE_A_CONTROLLER; + let controller = await AVSessionManager.createController("") // 获取sessionId - let sessionId: string = controller.sessionId; + let sessionId = controller.sessionId; console.info(`get sessionId by controller : isActive : ${sessionId}`); // 获取session激活状态 - let isActive: boolean = await controller.isActive(); + let isActive = await controller.isActive(); console.info(`get activeState by controller : ${isActive}`); // 获取session的媒体信息 - let metadata: AVSessionManager.AVMetadata = await controller.getAVMetadata(); + let metadata = await controller.getAVMetadata(); console.info(`get media title by controller : ${metadata.title}`); console.info(`get media artist by controller : ${metadata.artist}`); // 获取session的播放信息 - let avPlaybackState: AVSessionManager.AVPlaybackState = await controller.getAVPlaybackState(); + let 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(); + let queueItems = await controller.getAVQueueItems(); console.info(`get queueItems length by controller : ${queueItems.length}`); // 获取session的播放标题信息 - let queueTitle: string = await controller.getAVQueueTitle(); + let queueTitle = await controller.getAVQueueTitle(); console.info(`get queueTitle by controller : ${queueTitle}`); // 获取session的自定义媒体数据包 - let extras: any = await controller.getExtras(); + let extras = await controller.getExtras(); console.info(`get custom media packets by controller : ${JSON.stringify(extras)}`); // 获取session对应应用提供的ability信息 - let agent: WantAgent = await controller.getLaunchAbility(); + let agent = await controller.getLaunchAbility(); console.info(`get want agent info by controller : ${JSON.stringify(agent)}`); // 获取session的当前播放位置信息 - let currentTime: number = controller.getRealPlaybackPositionSync(); + let currentTime = controller.getRealPlaybackPositionSync(); console.info(`get current playback time by controller : ${currentTime}`); // 获取session支持的有效命令 - let validCommands: Array = await controller.getValidCommands(); + let validCommands = await controller.getValidCommands(); console.info(`get valid commands by controller : ${JSON.stringify(validCommands)}`); } ``` @@ -267,11 +281,14 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 作为媒体会话提供方的音视频应用在监听到相关的播控命令事件后,在相应的逻辑中可以完成对应的操作动作。 ```ts - async sendCommandToSessionByController() { + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + async function sendCommandToSessionByController() { // 假设我们已经有了一个对应session的controller,如何创建controller可以参考之前的案例 - let controller: AVSessionManager.AVSessionController = ALLREADY_HAVE_A_CONTROLLER; + let controller = await AVSessionManager.createController("") // 获取这个session支持的命令种类 - let validCommandTypeArray: Array = await controller.getValidCommands(); + let validCommandTypeArray = await controller.getValidCommands(); console.info(`get validCommandArray by controller : length : ${validCommandTypeArray.length}`); // 下发播放命令 // 如果可用命令包含播放,则下发播放命令,正常session都应该提供并实现播放功能 @@ -295,20 +312,17 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 controller.sendControlCommand(avCommand); } // 下发自定义控制命令 - let commandName: string = 'custom command'; - let args = { - command : 'This is my custom command' - } - await controller.sendCommonCommand(commandName, args).then(() => { + let commandName = 'custom command'; + await controller.sendCommonCommand(commandName, {command : 'This is my custom command'}).then(() => { console.info(`SendCommonCommand successfully`); - }).catch((err) => { + }).catch((err: BusinessError) => { console.error(`Failed to send common command. Code: ${err.code}, message: ${err.message}`); }) // 设置指定播放列表单项的ID,供session选择播放 - let queueItemId: number = 0; + let queueItemId = 0; await controller.skipToQueueItem(queueItemId).then(() => { console.info(`SkipToQueueItem successfully`); - }).catch((err) => { + }).catch((err: BusinessError) => { console.error(`Failed to skip to queue item. Code: ${err.code}, message: ${err.message}`); }); } @@ -317,12 +331,15 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 6. 在媒体会话控制方应用退出时及时取消事件监听,并释放资源。 ```ts - async destroyController() { + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + async function destroyController() { // 假设我们已经有了一个对应session的controller,如何创建controller可以参考之前的案例 - let controller: AVSessionManager.AVSessionController = ALLREADY_HAVE_A_CONTROLLER; - + let controller = await AVSessionManager.createController("") + // 销毁当前的controller,销毁后这个controller将不在可用 - controller.destroy(function (err) { + controller.destroy((err: BusinessError) => { if (err) { console.error(`Failed to destroy controller. Code: ${err.code}, message: ${err.message}`); } else { diff --git a/zh-cn/application-dev/media/using-avsession-developer.md b/zh-cn/application-dev/media/using-avsession-developer.md index 57ecb7be0f..7328e17edc 100644 --- a/zh-cn/application-dev/media/using-avsession-developer.md +++ b/zh-cn/application-dev/media/using-avsession-developer.md @@ -37,22 +37,16 @@ 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'; // 开始创建并激活媒体会话 - import AVSessionManager from '@ohos.multimedia.avsession'; //导入AVSessionManager模块 - // 创建session - async createSession() { - let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(globalThis.context, 'SESSION_NAME', 'audio'); - session.activate(); - console.info(`session create done : sessionId : ${session.sessionId}`); + let context: Context = this.context; + async function createSession() { + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); + await session.activate(); + console.info(`session create done : sessionId : ${session.sessionId}`); } ``` @@ -63,9 +57,13 @@ 音视频应用设置的媒体会话信息,会被媒体会话控制方通过AVSessionController相关方法获取后进行显示或处理。 ```ts - async setSessionInfo() { + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + let context: Context = this.context; + async function setSessionInfo() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); // 播放器逻辑··· 引发媒体信息与播放状态的变更 // 设置必要的媒体信息 let metadata: AVSessionManager.AVMetadata = { @@ -75,7 +73,7 @@ }; session.setAVMetadata(metadata).then(() => { console.info(`SetAVMetadata successfully`); - }).catch((err) => { + }).catch((err: BusinessError) => { console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); }); // 简单设置一个播放状态 - 暂停 未收藏 @@ -83,7 +81,7 @@ state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, isFavorite:false }; - session.setAVPlaybackState(playbackState, function (err) { + session.setAVPlaybackState(playbackState, (err) => { if (err) { console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); } else { @@ -91,43 +89,41 @@ } }); // 设置一个播放列表 - let queueItemDescription_1 = { - mediaId: '001', + let queueItemDescription_1: AVSessionManager.AVMediaDescription = { + assetId: '001', title: 'music_name', subtitle: 'music_sub_name', description: 'music_description', - icon: PIXELMAP_OBJECT, - iconUri: 'http://www.xxx.com', + mediaImage: "PIXELMAP_OBJECT", extras: {'extras':'any'} }; - let queueItem_1 = { + let queueItem_1: AVSessionManager.AVQueueItem = { itemId: 1, description: queueItemDescription_1 }; - let queueItemDescription_2 = { - mediaId: '002', + let queueItemDescription_2: AVSessionManager.AVMediaDescription = { + assetId: '002', title: 'music_name', subtitle: 'music_sub_name', description: 'music_description', - icon: PIXELMAP_OBJECT, - iconUri: 'http://www.xxx.com', + mediaImage: "PIXELMAP_OBJECT", extras: {'extras':'any'} }; - let queueItem_2 = { + let queueItem_2: AVSessionManager.AVQueueItem = { itemId: 2, description: queueItemDescription_2 }; let queueItemsArray = [queueItem_1, queueItem_2]; session.setAVQueueItems(queueItemsArray).then(() => { console.info(`SetAVQueueItems successfully`); - }).catch((err) => { + }).catch((err: BusinessError) => { console.error(`Failed to set AVQueueItem, error code: ${err.code}, error message: ${err.message}`); }); // 设置媒体播放列表名称 let queueTitle = 'QUEUE_TITLE'; - session.setAVQueueTitle(queueTitle).then(() => { - console.info(`SetAVQueueTitle successfully`); - }).catch((err) => { + session.setAVQueueTitle(queueTitle).then(() => { + console.info(`SetAVQueueTitle successfully`); + }).catch((err: BusinessError) => { console.info(`Failed to set AVQueueTitle, error code: ${err.code}, error message: ${err.message}`); }); } @@ -141,22 +137,29 @@ ``` ```ts - // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; - let wantAgentInfo = { + import AVSessionManager from '@ohos.multimedia.avsession'; + import wantAgent from '@ohos.app.ability.wantAgent'; + + let context: Context = this.context; + async function getWantAgent() { + let type: AVSessionManager.AVSessionType = 'audio'; + // 假设已经创建了一个session,如何创建session可以参考之前的案例 + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); + let wantAgentInfo: wantAgent.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, requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] - } - wantAgent.getWantAgent(wantAgentInfo).then((agent) => { + } + wantAgent.getWantAgent(wantAgentInfo).then((agent) => { session.setLaunchAbility(agent); - }) + }) + } ``` 4. 设置一个即时的自定义会话事件,以供媒体控制方接收到事件后进行相应的操作。 @@ -165,17 +168,23 @@ > 通过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' + + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + let context: Context = this.context; + async function dispatchSessionEvent() { + // 假设已经创建了一个session,如何创建session可以参考之前的案例 + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); + let eventName = 'dynamic_lyric'; + await session.dispatchSessionEvent(eventName, {lyric : 'This is my lyric'}).then(() => { + console.info(`Dispatch session event successfully`); + }).catch((err: BusinessError) => { + console.error(`Failed to dispatch session event. Code: ${err.code}, message: ${err.message}`); + }) } - 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}`); - }) + ``` 5. 设置与当前会话相关的自定义媒体数据包,以供媒体控制方接收到事件后进行相应的操作。 @@ -184,16 +193,20 @@ > 通过setExtras方法设置的数据包会被存储在AVSession服务中,数据的生命周期与会话一致;会话对应的Controller可以使用getExtras来获取该数据。 ```ts - // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; - let extras = { - extra : 'This is my custom meida packet' + import AVSessionManager from '@ohos.multimedia.avsession'; + import { BusinessError } from '@ohos.base'; + + let context: Context = this.context; + async function setExtras() { + // 假设已经创建了一个session,如何创建session可以参考之前的案例 + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); + await session.setExtras({extra : 'This is my custom meida packet'}).then(() => { + console.info(`Set extras successfully`); + }).catch((err: BusinessError) => { + console.error(`Failed to set extras. Code: ${err.code}, message: ${err.message}`); + }) } - 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. 注册播控命令事件监听,便于响应用户通过媒体会话控制方,例如播控中心,下发的播控命令。 @@ -209,9 +222,13 @@ Session侧的固定播控命令主要包括播放、暂停、上一首、下一首等基础操作命令,详细介绍请参见[AVControlCommand](../reference/apis/js-apis-avsession.md) ```ts - async setListenerForMesFromController() { + import AVSessionManager from '@ohos.multimedia.avsession'; + + let context: Context = this.context; + async function setListenerForMesFromController() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 一般在监听器中会对播放器做相应逻辑处理 // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例 session.on('play', () => { @@ -272,9 +289,13 @@ - commonCommand: 自定义控制命令变化的事件。 ```ts - async setListenerForMesFromController() { + import AVSessionManager from '@ohos.multimedia.avsession'; + + let context: Context = this.context; + async function setListenerForMesFromController() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 一般在监听器中会对播放器做相应逻辑处理 // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例 session.on('skipToQueueItem', (itemId) => { @@ -299,23 +320,27 @@ 7. 获取当前媒体会话自身的控制器,与媒体会话对应进行通信交互。 ```ts - async createControllerFromSession() { + import AVSessionManager from '@ohos.multimedia.avsession'; + + let context: Context = this.context; + async function createControllerFromSession() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; - + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); + // 通过已有session获取一个controller对象 - let controller: AVSessionManager.AVSessionController = await session.getController(); - + let controller = await session.getController(); + // controller可以与原session对象进行基本的通信交互,比如下发播放命令 let avCommand: AVSessionManager.AVControlCommand = {command:'play'}; controller.sendControlCommand(avCommand); - + // 或者做状态变更监听 - controller.on('playbackStateChange', 'all', (state: AVSessionManager.AVPlaybackState) => { - + controller.on('playbackStateChange', 'all', (state) => { + // do some things }); - + // controller可以做的操作还有很多,具体可以参考媒体会话控制方相关的说明 } ``` @@ -324,10 +349,14 @@ 取消播控命令监听的示例代码如下所示 : ```ts - async unregisterSessionListener() { + import AVSessionManager from '@ohos.multimedia.avsession'; + + let context: Context = this.context; + async function unregisterSessionListener() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; - + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); + // 取消指定session下的相关监听 session.off('play'); session.off('pause'); @@ -344,11 +373,15 @@ 销毁媒体会话示例代码如下所示: ```ts - async destroySession() { + import AVSessionManager from '@ohos.multimedia.avsession'; + + let context: Context = this.context; + async function destroySession() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 - let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let type: AVSessionManager.AVSessionType = 'audio'; + let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 主动销毁已创建的session - session.destroy(function (err) { + session.destroy((err) => { if (err) { console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); } else { diff --git a/zh-cn/application-dev/media/using-distributed-avsession.md b/zh-cn/application-dev/media/using-distributed-avsession.md index 5a535dd398..de47ec150e 100644 --- a/zh-cn/application-dev/media/using-distributed-avsession.md +++ b/zh-cn/application-dev/media/using-distributed-avsession.md @@ -30,22 +30,29 @@ 2. 通过AVSessionManager的castAudio接口将当前设备所有会话投播到其他设备。 ```ts - // 投播到其他设备 - let audioManager = audio.getAudioManager(); - let audioRoutingManager = audioManager.getRoutingManager(); - let audioDevices; - await audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { - audioDevices = data; - console.info(`Promise returned to indicate that the device list is obtained.`); - }).catch((err) => { - console.error(`Failed to get devices. Code: ${err.code}, message: ${err.message}`); - }); - - AVSessionManager.castAudio('all', audioDevices).then(() => { - console.info(`createController : SUCCESS`); - }).catch((err) => { - console.error(`Failed to cast audio. Code: ${err.code}, message: ${err.message}`); - }); + import AVSessionManager from '@ohos.multimedia.avsession'; + import audio from '@ohos.multimedia.audio'; + import { BusinessError } from '@ohos.base'; + + async function castAudio() { + // 投播到其他设备 + let audioManager = audio.getAudioManager(); + let audioRoutingManager = audioManager.getRoutingManager(); + let audioDevices: audio.AudioDeviceDescriptors; + await audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { + audioDevices = data; + console.info(`Promise returned to indicate that the device list is obtained.`); + }).catch((err: BusinessError) => { + console.error(`Failed to get devices. Code: ${err.code}, message: ${err.message}`); + }); + + AVSessionManager.castAudio('all', audioDevices).then(() => { + console.info(`createController : SUCCESS`); + }).catch((err: BusinessError) => { + console.error(`Failed to cast audio. Code: ${err.code}, message: ${err.message}`); + }); + } + ``` 系统应用在投播主控端发起投播后,媒体会话框架会通知远端设备的AVSession服务创建远端媒体会话。投播主控端的媒体会话变化时(例如媒体信息变化、播放状态变化等),媒体会话框架会自动同步变化到远端设备。 -- GitLab