第17章 HarmonyOs开发图解之 媒体会话管理

HarmonyOS 学习系统 | 阶段三:高级深耕期


学习目标

序号能力
1理解 AVSession 四大核心类(Browser/Controller/BrowserService/Session)的分工
2能够实现客户端与服务端的媒体会话连接与控制
3掌握播放列表的订阅与媒体数据的获取

核心图解

HarmonyOS 多媒体框架全景图

内容讲解

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 连接服务
AVBrowser avBrowser = new AVBrowser(context,
    new ElementName("com.example", "AVService"),
    new AVConnectionCallback() {
        @Override
        public void onConnected() {
            // 连接成功,创建控制器
            AVController controller = new AVController(context,
                avBrowser.getAVToken());
            controller.setAVControllerCallback(myCallback);

            // 订阅媒体数据(获取播放列表)
            avBrowser.subscribeByParentMediaId("root",
                new AVSubscriptionCallback() {
                    @Override
                    public void onAVElementListLoaded(List<AVElement> list) {
                        // 获取播放列表,更新 UI
                        for (AVElement element : list) {
                            HiLog.info(TAG, "媒体: " + element.getTitle());
                        }
                    }
                });
        }
        @Override
        public void onDisconnected() {
            HiLog.info(TAG, "与服务端断开连接");
        }
    }, null);

avBrowser.connect(); // 发起连接

// 控制播放
controller.getPlayControls().play();
controller.getPlayControls().pause();
controller.getPlayControls().skipToNext();
controller.getPlayControls().skipToPrevious();

17.4 服务端:提供媒体内容

服务端通过继承 AVBrowserService 并配合 AVSession 来提供媒体内容:

public class AVService extends AVBrowserService {
    @Override
    public void onGetRoot(ElementName caller, int transportId, Bundle rootHints) {
        // 返回根媒体ID,客户端通过此ID订阅内容
        setSessionToken(session.getSessionToken());
    }

    @Override
    public void onLoadChildren(String parentMediaId, Result<List<AVElement>> result) {
        // 根据 parentMediaId 返回对应的媒体列表
        List<AVElement> elements = queryMediaList(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 连不上 AVBrowserService?

AVBrowser 和 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 控制播放
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐