Android音视频开发入门(2)MediaPlayer 生命周期及create()分析

private static void postEventFromNative(Object mediaplayer_ref,

int what, int arg1, int arg2, Object obj)

{

//得到弱引用的MediaPlayer

final MediaPlayer mp = (MediaPlayer)((WeakReference)mediaplayer_ref).get();

if (mp == null) {

return;

}

//如果handler不为空,则发送一条message

if (mp.mEventHandler != null) {

Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);

mp.mEventHandler.sendMessage(m);

}

}

postEventFromNative总结

总的来说,就是拿到Native层创建好的MediaPlayer,并且向Handler发送一条message,至于后面做了啥之后再讲。

我们之前在create()的时候,创建MediaPlayer之后,会走native_setup方法,我们来看看这个方法做了什么:

//android_media_MediaPlayer.cpp

static void

android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)

{

ALOGV(“native_setup”);

sp mp = new MediaPlayer();

// 给MediaPlayer创建一个Listener,便于我们在Java层设置的 setPrepareListener、setOnCompleteListener能产生回调

sp listener = new JNIMediaPlayerListener(env, thiz, weak_this);

mp->setListener(listener);

// 对于Java层来说,C++中的MediaPlayer是不透明的,也无需关心其对应的逻辑,各司其职就行了

setMediaPlayer(env, thiz, mp);

}

native_setup总结

  1. 设置监听器

  2. C++层自己处理这个MediaPlayer

2.2 setDataSource过程


上面是一个MediaPlayer的构造过程,在构造完,着实的获取到MediaPlayer这个对象之后,我们就会去 setDataSource(),我们来看看它的源码(注:这一段代码比较无聊,可以大致浏览一下并直接看总结):

(注:下面一段是传入的uri为文件资源形式的代码,就比如我们传了一个本地的媒体文件

private void setDataSource(String path, Map<String, String> headers, List cookies)

throws IOException, IllegalArgumentException, SecurityException, IllegalStateException

{

String[] keys = null;

String[] values = null;

if (headers != null) {

keys = new String[headers.size()];

values = new String[headers.size()];

int i = 0;

//把HTPP/RTSP中包含的key、value分别装到两个数组中

for (Map.Entry<String, String> entry: headers.entrySet()) {

keys[i] = entry.getKey();

values[i] = entry.getValue();

++i;

}

}

setDataSource(path, keys, values, cookies);

}

private void setDataSource(String path, String[] keys, String[] values,

List cookies)

throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {

//解析path

final Uri uri = Uri.parse(path);

final String scheme = uri.getScheme();

if (“file”.equals(scheme)) {

path = uri.getPath();

} else if (scheme != null) {

// 处理非资源文件

nativeSetDataSource(

MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),

path,

keys,

values);

return;

}

//处理文件类型

final File file = new File(path);

if (file.exists()) {

FileInputStream is = new FileInputStream(file);

//得到文件标识符

FileDescriptor fd = is.getFD();

//传入文件标志符

setDataSource(fd);

is.close();

} else {

throw new IOException(“setDataSource failed.”);

}

}

public void setDataSource(FileDescriptor fd)

throws IOException, IllegalArgumentException, IllegalStateException {

setDataSource(fd, 0, 0x7ffffffffffffffL);

}

public void setDataSource(FileDescriptor fd, long offset, long length)

throws IOException, IllegalArgumentException, IllegalStateException {

//进入native层

_setDataSource(fd, offset, length);

}

setDataSource()总结

解析uri,如果得到的路径是文件,则把该文件资源的资源标识符丢给native层处理。

native层并没有setDataSource函数,但是有一个函数名映射函数说明,这是JNI中常用的动态注册方法:

在这里插入图片描述

所以我们找到 setDataSourceFD():

static void

android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)

{

//获得MediaPlayer

sp mp = getMediaPlayer(env, thiz);

//在JNI中获取 java.i

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值