赞
踩
音视频应用在实现音视频功能的同时,需要作为媒体会话提供方接入媒体会话,在媒体会话控制方(例如播控中心)中展示媒体相关信息,及响应媒体会话控制方下发的播控命令。
媒体会话提供方使用的关键接口如下表所示。接口返回值有两种返回形式:callback和promise,下表中为callback形式接口,promise和callback只是返回值方式不一样,功能相同。
接口名 | 说明 |
---|---|
createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback): void10+ | 创建媒体会话。一个UIAbility只能存在一个媒体会话,重复创建会失败。 |
setAVMetadata(data: AVMetadata, callback: AsyncCallback): void10+ | 设置媒体会话元数据。 |
setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback): void10+ | 设置媒体会话播放状态。 |
setLaunchAbility(ability: WantAgent, callback: AsyncCallback): void10+ | 设置启动UIAbility。 |
getController(callback: AsyncCallback): void10+ | 获取当前会话自身控制器。 |
getOutputDevice(callback: AsyncCallback): void10+ | 获取播放设备相关信息。 |
activate(callback: AsyncCallback): void10+ | 激活媒体会话。 |
deactivate(callback: AsyncCallback): void10+ | 禁用当前会话。 |
destroy(callback: AsyncCallback): void10+ | 销毁媒体会话。 |
setAVQueueItems(items: Array, callback: AsyncCallback): void 10+ | 设置媒体播放列表。 |
setAVQueueTitle(title: string, callback: AsyncCallback): void10+ | 设置媒体播放列表名称。 |
dispatchSessionEvent(event: string, args: {[key: string]: Object}, callback: AsyncCallback): void10+ | 设置会话内自定义事件。 |
setExtras(extras: {[key: string]: Object}, callback: AsyncCallback): void10+ | 设置键值对形式的自定义媒体数据包。 |
getOutputDeviceSync(): OutputDeviceInfo10+ | 使用同步方法获取当前输出设备信息。 |
音视频应用作为媒体会话提供方接入媒体会话的基本步骤如下所示:
import { avSession as AVSessionManager } from '@kit.AVSessionKit';
// 开始创建并激活媒体会话
// 创建session
let context: Context = getContext(this);
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}`);
}
跟随媒体信息的变化,及时设置媒体会话信息。需要设置的媒体会话信息主要包括:
音视频应用设置的媒体会话信息,会被媒体会话控制方通过AVSessionController相关方法获取后进行显示或处理。
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; import { BusinessError } from '@kit.BasicServicesKit'; let context: Context = getContext(this); async function setSessionInfo() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); // 播放器逻辑··· 引发媒体信息与播放状态的变更 // 设置必要的媒体信息 let metadata: AVSessionManager.AVMetadata = { assetId: '0', // 由应用指定,用于标识应用媒体库里的媒体 title: 'TITLE', mediaImage: 'IMAGE', artist: 'ARTIST' }; session.setAVMetadata(metadata).then(() => { console.info(`SetAVMetadata successfully`); }).catch((err: BusinessError) => { console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); }); // 简单设置一个播放状态 - 暂停 未收藏 let playbackState: AVSessionManager.AVPlaybackState = { state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, isFavorite:false }; session.setAVPlaybackState(playbackState, (err) => { if (err) { console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); } else { console.info(`SetAVPlaybackState successfully`); } }); // 设置一个播放列表 let queueItemDescription_1: AVSessionManager.AVMediaDescription = { assetId: '001', title: 'music_name', subtitle: 'music_sub_name', description: 'music_description', mediaImage: "PIXELMAP_OBJECT", extras: {'extras':'any'} }; let queueItem_1: AVSessionManager.AVQueueItem = { itemId: 1, description: queueItemDescription_1 }; let queueItemDescription_2: AVSessionManager.AVMediaDescription = { assetId: '002', title: 'music_name', subtitle: 'music_sub_name', description: 'music_description', mediaImage: "PIXELMAP_OBJECT", extras: {'extras':'any'} }; 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: 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: BusinessError) => { console.info(`Failed to set AVQueueTitle, error code: ${err.code}, error message: ${err.message}`); }); }
设置UIAbility时通过WantAgent接口实现
import { wantAgent } from '@kit.AbilityKit';
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; import { wantAgent } from '@kit.AbilityKit'; let context: Context = getContext(this); 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: 'MainAbility' } ], operationType: wantAgent.OperationType.START_ABILITIES, requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] } wantAgent.getWantAgent(wantAgentInfo).then((agent) => { session.setLaunchAbility(agent); }) }
说明
通过dispatchSessionEvent方法设置的数据不会保存在会话对象或AVSession服务中。
import { avSession as AVSessionManager } from '@kit.AVSessionKit';
import { BusinessError } from '@kit.BasicServicesKit';
let context: Context = getContext(this);
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}`);
})
}
说明
通过setExtras方法设置的数据包会被存储在AVSession服务中,数据的生命周期与会话一致;会话对应的Controller可以使用getExtras来获取该数据。
import { avSession as AVSessionManager } from '@kit.AVSessionKit';
import { BusinessError } from '@kit.BasicServicesKit';
let context: Context = getContext(this);
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}`);
})
}
注册播控命令事件监听,便于响应用户通过媒体会话控制方,例如播控中心,下发的播控命令。
在Session侧注册的监听分为固定播控命令和高级播控事件两种。
6.1 固定控制命令的监听
说明
媒体会话提供方在注册相关固定播控命令事件监听时,监听的事件会在媒体会话控制方的getValidCommands()方法中体现,即媒体会话控制方会认为对应的方法有效,进而根据需要触发相应暂不使用时的事件。为了保证媒体会话控制方下发的播控命令可以被正常执行,媒体会话提供方请勿进行无逻辑的空实现监听。
Session侧的固定播控命令主要包括播放、暂停、上一首、下一首等基础操作命令。
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; let context: Context = getContext(this); async function setListenerForMesFromController() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 let type: AVSessionManager.AVSessionType = 'audio'; let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 一般在监听器中会对播放器做相应逻辑处理 // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例 session.on('play', () => { console.info(`on play , do play task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('play')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态 }); session.on('pause', () => { console.info(`on pause , do pause task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('pause')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态 }); session.on('stop', () => { console.info(`on stop , do stop task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('stop')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态 }); session.on('playNext', () => { console.info(`on playNext , do playNext task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('playNext')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态,使用SetAVMetadata上报媒体信息 }); session.on('playPrevious', () => { console.info(`on playPrevious , do playPrevious task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('playPrevious')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态,使用SetAVMetadata上报媒体信息 }); session.on('fastForward', () => { console.info(`on fastForward , do fastForward task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('fastForward')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态和播放position }); session.on('rewind', () => { console.info(`on rewind , do rewind task`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('rewind')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态和播放position }); session.on('seek', (time) => { console.info(`on seek , the seek time is ${time}`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('seek')取消监听 // 处理完毕后,请使用SetAVPlayState上报播放状态和播放position }); 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}`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('setLoopMode')取消监听 // 应用自定下一个模式,处理完毕后,请使用SetAVPlayState上报切换后的LoopMode }); session.on('toggleFavorite', (assetId) => { console.info(`on toggleFavorite , the target asset Id is ${assetId}`); // 如暂不支持该指令,请勿注册;或在注册后但暂不使用时,通过session.off('toggleFavorite')取消监听 // 处理完毕后,请使用SetAVPlayState上报收藏结果isFavorite }); }
6.2 高级播控事件的监听
Session侧的可以注册的高级播控事件主要包括:
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; let context: Context = getContext(this); async function setListenerForMesFromController() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 let type: AVSessionManager.AVSessionType = 'audio'; let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 一般在监听器中会对播放器做相应逻辑处理 // 不要忘记处理完后需要通过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 ··· }); }
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; let context: Context = getContext(this); async function createControllerFromSession() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 let type: AVSessionManager.AVSessionType = 'audio'; let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 通过已有session获取一个controller对象 let controller = await session.getController(); // controller可以与原session对象进行基本的通信交互,比如下发播放命令 let avCommand: AVSessionManager.AVControlCommand = {command:'play'}; controller.sendControlCommand(avCommand); // 或者做状态变更监听 controller.on('playbackStateChange', 'all', (state) => { // do some things }); // controller可以做的操作还有很多,具体可以参考媒体会话控制方相关的说明 }
音视频应用在退出,并且不需要继续播放时,及时取消监听以及销毁媒体会话释放资源。
取消播控命令监听的示例代码如下所示 :
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; let context: Context = getContext(this); async function unregisterSessionListener() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 let type: AVSessionManager.AVSessionType = 'audio'; let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 取消指定session下的相关监听 session.off('play'); session.off('pause'); session.off('stop'); session.off('playNext'); session.off('playPrevious'); session.off('skipToQueueItem'); session.off('handleKeyEvent'); session.off('outputDeviceChange'); session.off('commonCommand'); }
销毁媒体会话示例代码如下所示:
import { avSession as AVSessionManager } from '@kit.AVSessionKit'; let context: Context = getContext(this); async function destroySession() { // 假设已经创建了一个session,如何创建session可以参考之前的案例 let type: AVSessionManager.AVSessionType = 'audio'; let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); // 主动销毁已创建的session session.destroy((err) => { if (err) { console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); } else { console.info(`Destroy : SUCCESS `); } }); }
很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。
而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点
如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。
针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。
鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。
并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。