使用音频模板
从API version 23开始,支持媒体应用通过音频模板接入播控中心(系统应用),实现音视频在播控中心进行统一的界面显示和播控管理,减少应用侧开发工作量。该文档介绍音频模板接口能力及开发基本流程,包括通过音模板接入播控中心、上报媒体相关信息(标题、作者、播放状态等)至播控中心、响应播控中心下发的操作(播放、暂停、搜索、收藏)指令等。
音频模板同时支持音频和视频内容,且两者的接入方式相同。本文档以音频场景为例进行说明。
说明:
本功能仅支持在API version 23及以上版本的Car设备工程中使用。创建工程时,请在Device type中选择“Car”。
基本概念
音频模板(AVMusicTemplate):用于描述音频模板相关能力的类,包含标识当前媒体会话的ID(sessionId)、会话标签(sessionTag)等属性,以及与播控中心进行数据交互的操作方法。媒体应用可通过音频模板向播控中心上报媒体相关信息,以及响应播控中心的操作指令。
接口说明
详细的API说明请参考AVMusicTemplate。
开发步骤
媒体应用接入音频模板的基本步骤如下所示:
-
在进程启动时,调用接口createAVMusicTemplate创建音频模板实例(每个媒体应用创建一个音频模板实例,不需要重复创建)并拉起音频模板。
以下示例代码仅展示创建AVMusicTemplate对象的接口调用,应用在真正使用时,需要参考接口@ohos.backgroundTaskManager (后台任务管理)确保AVMusicTemplate对象实例在应用后台播放业务活动期间一直存在,避免被系统回收、释放,导致后台发声时被系统管控。
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { TemplateManager } from '../manager/TemplateManager'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { console.info('onCreate'); TemplateManager.getInstance().createTemplate(); } // ... onForeground(): void { console.info('onForeground'); this.startTemplateControllerAbility(); } private startTemplateControllerAbility() { let want: Want = { bundleName: 'com.example.templatecontroller', abilityName: 'EntryAbility', parameters: { bundleName: 'com.example.templateprovider' } } this.context.startAbility(want).then(() => { console.info('startTemplateControllerAbility: startAbility success'); }).catch((e: BusinessError) => { console.error(`startTemplateControllerAbility: startAbility: errCode: ${e?.code}}`); }); } }import { avMusicTemplate } from '@kit.AVSessionKit'; // ... export class TemplateManager { private template: avMusicTemplate.AVMusicTemplate|undefined = undefined; private static sInstance: TemplateManager; // ... private constructor() { } /** * 获取模板控制器实例。 * * @returns 模板控制器实例。 */ public static getInstance(): TemplateManager { if (!TemplateManager.sInstance) { TemplateManager.sInstance = new TemplateManager(); } return TemplateManager.sInstance; }; /** * 创建音频模板。 */ public createTemplate() { if (this.template) { console.warn('createTemplate: template not undefined'); return } try { this.template = avMusicTemplate.createAVMusicTemplate(avMusicTemplate.AVMusicTemplateType.DEFAULT); console.info('createTemplate: success'); // ... } catch (e) { console.error(`createTemplate, errCode: ${e?.code}`); } } // ... } -
注册事件监听,在监听到事件后可提供应用数据给音频模板使用。监听接口详情请查看AVMusicTemplate。
音频模板主界面显示需要同时注册如下两个接口:
- onQueryMainTabs:注册查询主标签事件监听。提供主界面展示的TAB数据集合,并规定“我的主页”的tabId为"minePage"。
- onQueryMediaTabContent:注册查询媒体标签内容事件监听。根据tabId提供页面展示内容数据。
import { avMusicTemplate } from '@kit.AVSessionKit'; // ... export class TemplateManager { private template: avMusicTemplate.AVMusicTemplate|undefined = undefined; // ... private queryMainTabsEvent: avMusicTemplate.QueryMainTabsEvent = async () => { return new Promise<avMusicTemplate.MediaTab[]>(async (resolve, reject) => { try { let tabs: avMusicTemplate.MediaTab[] = await this.getMainTabs(); resolve(tabs); } catch (e) { console.error(`queryMainTabsEvent fail, errCode: ${e?.code}`); reject(e); } }); }; private queryMediaTabContentEvent: avMusicTemplate.QueryMediaTabContentEvent = async (tabId: string) => { return new Promise<avMusicTemplate.MediaTabContent>(async (resolve, reject) => { try { let tabContent: avMusicTemplate.MediaTabContent = await this.createMediaTabContent(); resolve(tabContent); } catch (e) { console.error(`queryMediaTabContentEvent fail, errCode: ${e?.code}`); reject(e); } }); }; // ... /** * 注册监听。 */ private registerListener() { this.template?.onQueryMainTabs(this.queryMainTabsEvent); this.template?.onQueryMediaTabContent(this.queryMediaTabContentEvent); // ... }; // ... /** * 模拟获取主界面的所有TAB。 * * @returns Promise类型MediaTab数组。 */ private async getMainTabs(): Promise<avMusicTemplate.MediaTab[]> { let homeTab: avMusicTemplate.MediaTab = { tabId: 'home', tabName: '首页' }; let mineTab: avMusicTemplate.MediaTab = { tabId: 'mine', tabName: '我的' }; let mainTabs: avMusicTemplate.MediaTab[] = [homeTab, mineTab]; return mainTabs; }; /** * 模拟获取TAB内容。 * * @returns 标签页内容。 */ private async createMediaTabContent(): Promise<avMusicTemplate.MediaTabContent> { let compilation: avMusicTemplate.Compilation = await this.createCompilation(); let mediaTabContent: avMusicTemplate.MediaTabContent = { errorCode: 0, tabId: 'tabId', compilations: [compilation] } return mediaTabContent; }; /** * 模拟获取合集数据。 * * @returns 合集。 */ private async createCompilation(): Promise<avMusicTemplate.Compilation> { let mediaEntity: avMusicTemplate.MediaEntity = await this.createMediaEntity(); let compilation: avMusicTemplate.Compilation = { errorCode: 0, id: '', title: '', hasMoreData: false, totalSize: 1, memberMediaType: avMusicTemplate.EntityType.SINGLE, topElements: [mediaEntity], } return compilation; }; /** * 模拟获取媒体数据。 * * @returns 媒体数据。 */ private async createMediaEntity(): Promise<avMusicTemplate.MediaEntity> { let mediaEntity: avMusicTemplate.MediaEntity = { mediaId: 'mediaId', mediaType: avMusicTemplate.EntityType.SINGLE, parentId: 'parentId', parentMediaType: avMusicTemplate.EntityType.SINGLE, title: 'title', imageUrl: 'imageUrl', playState: avMusicTemplate.PlaybackState.PLAYBACK_STATE_PREPARE }; return mediaEntity; }; // ... } -
在音频模板无法直接感知的场景(登录,下载等),需要媒体应用主动向音频模板同步数据。同步接口详情请查看AVMusicTemplate。
例如,扫码登录成功的场景。当用户在音频模板界面扫码登录时,由于登录状态只有媒体应用能感知,所以需要调用接口setUserInfo给音频模板同步数据。
import { avMusicTemplate } from '@kit.AVSessionKit'; // ... export class TemplateManager { private template: avMusicTemplate.AVMusicTemplate|undefined = undefined; // ... private isLogin: boolean = false; // ... /** * 模拟登录状态改变。 * * @param isLogin 是否登录。 */ public setLoginState(isLogin: boolean) { this.isLogin = isLogin; this.setUserInfo(); } /** * 用户信息发生变化后通知界面刷新用户信息,如登陆账号后。 */ public setUserInfo() { let userInfo: avMusicTemplate.UserInfo = { userInfoId: this.isLogin ? 'userInfoId' : '', nickName: this.isLogin ? '昵称' : '', profilePicUrl: this.isLogin ? 'profilePicUrl' : '', tips: this.isLogin ? 'tips' : '', isLogin: this.isLogin, isVip: false }; this.template?.setUserInfo(userInfo); }; // ... } -
媒体应用启动时注册的事件监听需要在应用退出时注销,以释放资源。注销接口详情请查看AVMusicTemplate。
import { avMusicTemplate } from '@kit.AVSessionKit'; // ... export class TemplateManager { private template: avMusicTemplate.AVMusicTemplate|undefined = undefined; // ... /** * 注销监听。 */ public unregisterListener() { this.template?.offQueryMainTabs(); this.template?.offQueryMediaTabContent(); this.template?.offQueryMediaEntity(); this.template?.offQueryCompilation(); this.template?.offQueryPlaylist(); this.template?.offQueryCurrentSingle(); this.template?.offQueryCompilationByKeyword(); this.template?.offQueryMediaEntityByKeyword(); this.template?.offQueryRecommendMediaEntityList(); this.template?.offQueryHotWords(); this.template?.offQuerySearchHistory(); this.template?.offClearSearchHistory(); this.template?.offLogin(); this.template?.offRequestDialogInfo(); this.template?.offHandleMemberPurchase(); this.template?.offQueryMemberPurchase(); this.template?.offQueryCustomContent(); this.template?.offDownloadMediaEntity(); this.template?.offSettingsChange(); this.template?.offProblemAndAdvice(); this.template?.offPlayForSearch(); this.template?.offExecuteAction(); this.template?.offPlayMediaEntity(); this.template?.offFavoriteMediaEntity(); this.template?.destroy(); this.template = undefined; }; // ... }
你可能感兴趣的鸿蒙文章
openharmony 鸿蒙 using-distributed-avsession-sys
openharmony 鸿蒙 using-avsession-developer
openharmony 鸿蒙 local-avsession-overview
openharmony 鸿蒙 distributed-avsession-overview-sys
openharmony 鸿蒙 avsession-desktop-lyrics
openharmony 鸿蒙 using-avsession-AVMusicTemplateController-sys
openharmony 鸿蒙 avsession-access-scene