第17章 HarmonyOs开发图解之 媒体会话管理HarmonyOS 学习系统 | 阶段三高级深耕期学习目标序号能力1理解 AVSession 四大核心类Browser/Controller/BrowserService/Session的分工2能够实现客户端与服务端的媒体会话连接与控制3掌握播放列表的订阅与媒体数据的获取核心图解内容讲解17.1 媒体会话管理概述AVSession 框架是 HarmonyOS 提供的标准化媒体控制协议它将媒体播放的控制方和播放方解耦。控制方如系统媒体栏、蓝牙耳机、语音助手不需要知道播放方的内部实现只需通过 AVSession 定义的标准接口即可控制播放。生活化类比AVSession 就像遥控器 电视的约定想象你有一个万能遥控器AVController/AVBrowser可以控制任何品牌的电视AVBrowserService。但遥控器和电视之间需要一套约定——按 1 号键是什么功能按 2 号键是什么功能。AVSession 就是这套约定它定义了播放/暂停/上一曲/下一曲等标准控制指令。而 AVElement 就像电视节目单告诉遥控器有哪些节目可以看。17.2 AVSession 四大核心类类名角色使用位置说明AVBrowser媒体浏览器客户端用于浏览和发现媒体内容AVController媒体控制器客户端用于控制播放播放/暂停/上下曲AVBrowserService媒体浏览器服务服务端提供媒体内容给客户端浏览AVSession媒体会话服务端管理播放状态接收控制指令17.3 客户端连接与控制客户端通过 AVBrowser 连接到服务端的 AVBrowserService连接成功后创建 AVController 来控制播放。// 创建 AVBrowser 连接服务AVBrowseravBrowsernewAVBrowser(context,newElementName(com.example,AVService),newAVConnectionCallback(){OverridepublicvoidonConnected(){// 连接成功创建控制器AVControllercontrollernewAVController(context,avBrowser.getAVToken());controller.setAVControllerCallback(myCallback);// 订阅媒体数据获取播放列表avBrowser.subscribeByParentMediaId(root,newAVSubscriptionCallback(){OverridepublicvoidonAVElementListLoaded(ListAVElementlist){// 获取播放列表更新 UIfor(AVElementelement:list){HiLog.info(TAG,媒体: element.getTitle());}}});}OverridepublicvoidonDisconnected(){HiLog.info(TAG,与服务端断开连接);}},null);avBrowser.connect();// 发起连接// 控制播放controller.getPlayControls().play();controller.getPlayControls().pause();controller.getPlayControls().skipToNext();controller.getPlayControls().skipToPrevious();17.4 服务端提供媒体内容服务端通过继承 AVBrowserService 并配合 AVSession 来提供媒体内容publicclassAVServiceextendsAVBrowserService{OverridepublicvoidonGetRoot(ElementNamecaller,inttransportId,BundlerootHints){// 返回根媒体ID客户端通过此ID订阅内容setSessionToken(session.getSessionToken());}OverridepublicvoidonLoadChildren(StringparentMediaId,ResultListAVElementresult){// 根据 parentMediaId 返回对应的媒体列表ListAVElementelementsqueryMediaList(parentMediaId);result.sendResult(elements);}}代码速查卡API功能示例new AVBrowser(ctx, name, cb, opts)创建媒体浏览器new AVBrowser(context, elementName, callback, null)avBrowser.connect()连接服务端avBrowser.connect()new AVController(ctx, token)创建媒体控制器new AVController(context, avBrowser.getAVToken())getPlayControls().play()播放controller.getPlayControls().play()getPlayControls().pause()暂停controller.getPlayControls().pause()subscribeByParentMediaId()订阅媒体列表avBrowser.subscribeByParentMediaId(root, cb)setSessionToken(token)设置会话令牌setSessionToken(session.getSessionToken())与 Android/iOS 对比特性HarmonyOSAndroidiOS会话框架AVSessionMediaSessionMPNowPlayingInfoCenter浏览器AVBrowser / AVBrowserServiceMediaBrowser / MediaBrowserService不提供需自建控制器AVControllerMediaControllerMPRemoteCommandCenter系统媒体栏自动集成自动集成自动集成通知栏控制通过 AVSession通过 MediaSession通过 MPNowPlayingInfoCenter⚠️ 踩坑回忆录为什么 AVBrowser 连不上 AVBrowserServiceAVBrowser 和 AVBrowserService 是一对 CP必须在 config.json 中正确配置 Ability 的 type 和 name。我犯过一个低级错误Service 的 BundleName 写错了导致连接回调永远不会触发——整个下午都在排查代码逻辑最后发现是配置文件里的一个字母写错了。另一个坑subscribeByParentMediaId前必须先调用unsubscribeByParentMediaId否则会重复订阅导致回调被多次触发。这个先退后进的设计让人防不胜防建议在 onConnected 里先统一 unsubscribe 一次。必做实操任务序号任务难度1实现一个简单的音乐播放服务端提供播放列表高2实现客户端连接服务端并控制播放/暂停高3在客户端展示播放列表通过 subscribeByParentMediaId中4实现上一曲/下一曲切换功能中5配合系统通知栏实现锁屏状态下的媒体控制高学习检查清单能说出 AVBrowser、AVController、AVBrowserService、AVSession 四者的关系能实现客户端连接服务端的完整流程能使用 AVController 控制播放/暂停/上下曲能通过 subscribeByParentMediaId 获取播放列表知道为什么 subscribe 前需要先 unsubscribe能在 config.json 中正确配置 AVBrowserService理解 AVElement 的作用媒体元数据载体理解客户端与服务端分离的设计思想进阶方向实现完整的音乐播放器 App包含服务端和客户端学习 AVMetadata媒体元数据的设置与获取探索蓝牙耳机按键如何通过 AVSession 控制播放vice理解 AVElement 的作用媒体元数据载体理解客户端与服务端分离的设计思想进阶方向实现完整的音乐播放器 App包含服务端和客户端学习 AVMetadata媒体元数据的设置与获取探索蓝牙耳机按键如何通过 AVSession 控制播放