第二章 常用的系统播放器MediaPlayer

1. 从创建到setDataSource过程

① 创建过程

        使用create()方式创建MediaPlayer实例

public static MediaPlayer create(Context context, Uri uri);
public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder);

/**
 * Same factory method as {@link #create(Context, Uri, SurfaceHolder)} but that lets you specify
 * the audio attributes and session ID to be used by the new MediaPlayer instance.
 * @param context the Context to use
 * @param uri the Uri from which to get the datasource
 * @param holder the SurfaceHolder to use for displaying the video, may be null.
 * @param audioAttributes the {@link AudioAttributes} to be used by the media player.
 * @param audioSessionId the audio session ID to be used by the media player,
 *     see {@link AudioManager#generateAudioSessionId()} to obtain a new session.
 * @return a MediaPlayer object, or null if creation failed
 */
public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder,
        AudioAttributes audioAttributes, int audioSessionId) {

    try {
        MediaPlayer mp = new MediaPlayer(audioSessionId);
        final AudioAttributes aa = audioAttributes != null ? audioAttributes :
            new AudioAttributes.Builder().build();
        
        // 设置声音会话的ID,音频与视频是分开渲染的;
        mp.setAudioAttributes(aa);

        // 调用frameworks/av/media/libmedia/mediaplayer.cpp中的方法设置audio sessionID
        mp.native_setAudioSessionId(audioSessionId);


        mp.setDataSource(context, uri);

        /**
         * 一个Surface控制器,用来操纵Surface,处理它在Canvas上作画的效果和动画,控制表面、大小、像素等;
         */
        if (holder != null) {
            mp.setDisplay(holder);
        }
        
        // 调用native层方法,准备播放器
        mp.prepare();
        return mp;
    } catch (IOException ex) {
        // .....
    }

    return null;
}
MediaPlayer实例创建过程

 

setDataSource流程图

 

setDisplay 流程图

 

这里有如下几个概念需要理解:

        1. SurfaceTexture:SurfaceTexture是Android 3.0(API 11)加入的一个类。这个类跟SurfaceView很像,可以从视频解码里面获取图像流(image stream)。但是,和SurfaceView不同的是,SurfaceTexture在接收图像流之后,不需要显示出来。SurfaceTexture不需要显示到屏幕上,因此我们可以用SurfaceTexture接收解码出来的图像流,然后从SurfaceTexture中取得图像帧的副本进行处理,处理完毕后再送给另一个SurfaceView用于显示。

        2. Surface:处理被屏幕排序的原生的Buffer,Android中的Surface就是一个用来画图形(graphic)或图像(image)的地方。对于View及其子类,都是画在Surface上的,各Surface对象通过SurfaceFlinger合成到frameBuffer。每个Surface都是双缓冲的(实际上就是两个线程,一个渲染线程,一个UI更新线程),它有一个backBuffer和一个frontBuffer在Surface中创建的Canvas对象,可用来管理Surface绘图操作,Canvas对应Bitmap,存储Surface中的内容

        3. SurfaceView:在Camera、MediaRecorder、MediaPlayer中SurfaceView经常被用来显示图像。SurfaceView是View的子类,实现了Parcelable接口,其中内嵌了一个专门用于绘制的Surface,SurfaceView可以控制这个Surface的格式和尺寸,以及Surface的绘制位置。可以理解Surface就是管理数据的地方,SurfaceView就是展示数据的地方。

        4. SurfaceHolder:顾名思义,是一个管理SurfaceHolder的容器。SurfaceHolder是一个接口,其可被理解为一个Surface的监听器。通过回调函数addCallback(SurfaceHolder.Callback callback)监听Surface的创建,通过获取Surface中的Canvas对象,锁定之。所得到的Canvas对象在完成修改Surface中的数据后,释放同步锁,并提交改变Surface的状态及图像,展示新的图像数据

        最后总结一下,SurfaceView中调用getHolder函数,可以获得当前SurfaceView中的Surface对应的SurfaceHolder,SurfaceHolder开始对Surface进行管理操作。这里按MVC模式可以更好地理解M:Surface(图像数据)、V:SurfaceView(图像展示)、C:SurfaceHolder(图像数据管理)。MediaPlayer.java中的setDisplay操作就是对将要显示的视频进行预设置。

// Todo...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值