音视频开发|跨进程媒体控制和信息同步|MediaSession-标准化媒体控制的实现

MediaSession主要解决了什么问题?

早期多媒体应用的控制逻辑与播放逻辑紧密耦合,处于同一个进程中。

随着多媒体用户场景的拓展,用户能够在锁屏页、通知栏、桌面widget、蓝牙耳机、遥控器等地方来控制媒体播放、查看媒体信息。这些场景下媒体的信息展示、播放控制和播放实现处于不同的进程下,这需要我们在技术上将媒体控制逻与媒体播放实现解耦合,提升应用的灵活性和扩展性。

MediaSession就是为了解耦媒体控制与播放逻辑而生的,它是Android系统提供的一种实现媒体控制与播放实现分离的框架;利用MediaSession框架,我们能够将自己App的媒体播放能力(可以认为是媒体服务端)发布到系统中,供系统和其他进程调用,我们也可以使用MediaSession提供的标准化API来控制已经接MediaSession框架的App或者系统媒体服务,并且可以通过标准化API自动同步播放状态和播放视频的信息。

总结下:

  • MediaSession是一种媒体控制与播放实现分离的框架
  • MediaSession提供了标准化的媒体控制、播放状态管理和同步方案

MediaSession是如何解决这些问题的?

先上图~

MediaSession框架示例

MediaSession 框架提供了一套标准化的 API:

  • 开发者调用MediaController 标准的媒体控制API时候,MediaSession 框架会把媒体控制命令(可跨进程)转发给MediaSession服务端,开发者需要在MediaSession服务端的回调接口中调用播放器对应的播放、暂停等方法;同时开发者也需要在播放状态变化的时候,通过MediaSession 将服务端播放器的各种播放状态(播放、暂停、退出)和视频信息跨进程通知到MediaController 。

  • 开发者调用MediaBrower的获取媒体文件列表、获取文件信息等标准API时候,MediaSession 框架会把浏览命令(可跨进程)转发MediaBrowerService,开发者需要在自定义的MediaBrowerService中实现获取媒体文件目录以及单个媒体信息的方法,MediaSession 框架也会把这些目录和媒体信息跨进程发送给MediaBrower实例,需要注意一点是,MediaBrower实现前提是媒体文件的组织结构类似于树状结构。

MediaSession 使用示例

下面是一个在 Android 中使用 MediaSession 的代码示例:

1. 创建 MediaSession

import android.content.Context;
import android.media.MediaPlayer;
import android.media.session.MediaSession;
import android.media.session.MediaSession.Callback;
import android.media.session.MediaSession.Token;
import androidx.media.session.MediaControllerCompat;
import androidx.media.session.MediaMetadataCompat;

public class MyMediaService extends Service {
    private MediaSession mediaSession;
    private MediaPlayer mediaPlayer;

    @Override
    public void onCreate() {
        super.onCreate();

        // 初始化 MediaPlayer
        mediaPlayer = new MediaPlayer();

        // 创建 MediaSession
        mediaSession = new MediaSession(this, "MyMediaSession");

        // 设置回调,处理媒体控制命令
        mediaSession.setCallback(new Callback() {
            @Override
            public void onPlay() {
                mediaPlayer.start(); // 开始播放
                mediaSession.setActive(true); // 激活 MediaSession
            }

            @Override
            public void onPause() {
                mediaPlayer.pause(); // 暂停播放
            }

            @Override
            public void onStop() {
                mediaPlayer.stop(); // 停止播放
                mediaSession.release(); // 释放 MediaSession
            }
        });

        // 设置媒体元数据
        MediaMetadataCompat metadata = new MediaMetadataCompat.Builder()
                .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Sample Title")
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Sample Artist")
                .build();
        mediaSession.setMetadata(metadata); // 设置元数据

        // 启动 MediaSession
        mediaSession.setActive(true); // 激活 MediaSession
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null; // 返回 null 表示不绑定
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mediaSession.release(); // 释放 MediaSession
        mediaPlayer.release(); // 释放 MediaPlayer
    }
}

2. 使用 MediaController 控制 MediaSession

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;

// 在其他组件中控制 MediaSession
public void controlMediaSession(Context context) {
    MediaSessionManager mediaSessionManager = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
    MediaController mediaController = null;

    // 获取正在运行的 MediaSession
    for (MediaController controller : mediaSessionManager.getActiveSessions(new ComponentName(context, MyMediaService.class))) {
        mediaController = controller; // 获取第一个 MediaController
        break;
    }

    if (mediaController != null) {
        // 控制命令
        mediaController.getTransportControls().play(); // 播放
        mediaController.getTransportControls().pause(); // 暂停
        mediaController.getTransportControls().stop(); // 停止
    }
}

未来媒体框架的演进

随着技术的不断发展,未来的媒体框架可能会在以下几个方面演进:

  1. 增强的跨平台支持:随着不同设备(如智能音箱、车载系统等)的普及,未来的媒体框架可能会进一步增强跨平台的支持能力,使得开发者能够更方便地为多种设备提供一致的媒体控制体验。
  2. 更丰富的元数据支持:未来的 MediaSession 可能会扩展对更丰富元数据的支持,例如支持更复杂的内容类型、动态生成的封面等,以提升用户的多媒体体验。
  3. 智能控制功能:随着 AI 和机器学习技术的发展,未来的媒体框架可能会引入智能控制功能,能够根据用户的习惯和偏好自动调整播放设置,提供个性化的媒体体验。
  4. 增强的隐私和安全性:随着对用户隐私的重视,未来的媒体框架可能会加强对用户数据的保护,确保在媒体控制和共享过程中保持用户的隐私。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容