Android之Media播放器源码分析(framework——native)

本文深入分析Android 4.0版本的Media播放器框架,从apk实现到Java、JNI再到C/C++层。讨论了MediaPlayer类的初始化、构造方法、设置播放器参数和数据源的方法,揭示了如何通过SurfaceView显示视频并利用Binder通信与MediaPlayerService交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述:      

      声明:下面我们看的是Android 4.0版本下的Media播放器的框架,我们首先从一个简单的media播放器apk源码入手,从Java->JNI->C/C++一步步研究Android是如何通过Java一个MediaPlayer实现解码到屏幕的输出。

     通常在Android中播放视频用到的是MediaPlayer类,展示视频使用的是SurfaceView控件。

二、apk实现:

     我们首先在main.xml布局文件中添加用于视频画面绘制的SurfaceView控件:

 

<SurfaceView android:layout_width="fill_parent"android:layout_height="240dip"android:id="@+id/surfaceView"/>


 

     例如我们编写一个简单的视频播放器调用的常用方法如下。       

SurfaceView surfaceView = (SurfaceView)this.findViewById(R.id.surfaceView);  
surfaceView.getHolder().setFixedSize(720, 576);  //设置分辨率   
/*下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前*/  
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
/* new 一个播放器 mediaPlayer */
MediaPlayer mediaPlayer = new MediaPlayer();  
mediaPlayer.reset();	//重置为初始状态   
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
/* 设置Video影片以SurfaceHolder播放 */  
mediaPlayer.setDisplay(surfaceView.getHolder());  
mediaPlayer.setDataSource("/mnt/sdcard/test.ts");  
mediaPlayer.prepare();		//缓冲    
mediaPlayer.start();		//播放   

mediaPlayer.pause();		//暂停播放   
mediaPlayer.start();		//恢复播放   
mediaPlayer.stop();			//停止播放   
mediaPlayer.release();		//释放资源 

 

三、源码分析       

       我们首先来看MediaPlayer类,Java层的MediaPlayer.java位于frameworks/base/media/java/android/media/目录下:

 

public class MediaPlayer
{
	...
	static {
		System.loadLibrary("media_jni");
		native_init();
	}
	
	private int mNativeContext;
	private int mNativeSurfaceTexture;
	private int mListenerContext;
	
	private SurfaceHolder mSurfaceHolder;
	private EventHandler mEventHandler;
	
	
	public MediaPlayer() {
		Looper loop;
		if((loop = Looper.myLooper()) != null) {
			mEventHandler = new EventHandler(this, looper);
		} else if((looper = Looper.getMainLooper()) != null) {
			mEventHandler = new EventHandler(this. looper);
		} else {
			mEventHandler = null;
		}
		native_setup(new WeakReference<MediaPlayer>(this));
	}
	....
}

(一) static代码块

      首先会加载libmedia_jni.so库,调用native_init()方法,对应JNI接口为

 

android_media_MediaPlayer_native_init(JNIEnv* env)
{
	jclass clazz;
	
	class = env->FindClass("android/media/MediaPlayer");
	
	fields.context = env->GetFieldID(clazz, "mNativeContext");	// Java类中保存JNI层的mediaplayer对象
	
	/* JNI 事件通知Java,static 函数 */
	fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");

	fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "I");
	
	jclass surface = env->FindClass("android/view/Surface");
	
	fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
	
	fields.bitmapContstructor = env->GetMethodID(fields.bitmapClazz, "<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值