上一篇MediaPlayer中看到实现一个最简单的播放器只需要5个接口,接下来会看看这些接口实现内容

/**********************************************************
* Java -> C++
* 构造函数 构造函数
* setDataSource setDataSource
* setDisPlay setVideoSurfaceTexture
* prepareAsync prepareAsync
* start start
**********************************************************/

native mediaplayer 代码位置 http://aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libmedia/mediaplayer.cpp

1、构造函数

构造函数主要是初始化了一些成员变量,获取了一个audio_session_t,后面会利用这个session来创建audioSink

MediaPlayer::MediaPlayer(const AttributionSourceState& attributionSource)
: mAttributionSource(attributionSource)
{
ALOGV("constructor");
mListener = NULL;
mCookie = NULL;
mStreamType = AUDIO_STREAM_MUSIC;
mAudioAttributesParcel = NULL;
mCurrentPosition = -1;
mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
mSeekPosition = -1;
mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
mCurrentState = MEDIA_PLAYER_IDLE;
mPrepareSync = false;
mPrepareStatus = NO_ERROR;
mLoop = false;
mLeftVolume = mRightVolume = 1.0;
mVideoWidth = mVideoHeight = 0;
mLockThreadId = 0;
mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
AudioSystem::acquireAudioSessionId(mAudioSessionId, (pid_t)-1, (uid_t)-1); // always in client.
mSendLevel = 0;
mRetransmitEndpointValid = false;
}

2、setDataSource

setDataSource做的内容相当重要:

a. getMediaPlayerService获取media.player服务

b. 调用service的create方法实例化mPlayer

c. setDataSource

status_t MediaPlayer::setDataSource(
const sp<IMediaHTTPService> &httpService,
const char *url, const KeyedVector<String8, String8> *headers)
{
ALOGV("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
const sp<IMediaPlayerService> service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(this, mAudioSessionId, mAttributionSource));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
(NO_ERROR != player->setDataSource(httpService, url, headers))) {
player.clear();
}
err = attachNewPlayer(player);
}
}
return err;
}

3、setVideoSurfaceTexture

这里也很简单,调用IMediaPlayer的setVideoSurfaceTexture

status_t MediaPlayer::setVideoSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer)
{
ALOGV("setVideoSurfaceTexture");
Mutex::Autolock _l(mLock);
if (mPlayer == 0) return NO_INIT;
return mPlayer->setVideoSurfaceTexture(bufferProducer);
}

4、prepareAsync

prepareAsync做了两件事:

a. 调用IMediaPlayer的setAudioStreamType方法,mStreamType在构造函数中被初始化为AUDIO_STREAM_MUSIC

b. 调用IMediaPlayer的prepareAsync方法

status_t MediaPlayer::prepareAsync()
{
ALOGV("prepareAsync");
Mutex::Autolock _l(mLock);
return prepareAsync_l();
} status_t MediaPlayer::prepareAsync_l()
{
if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
if (mAudioAttributesParcel != NULL) {
mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel);
} else {
mPlayer->setAudioStreamType(mStreamType);
}
mCurrentState = MEDIA_PLAYER_PREPARING;
return mPlayer->prepareAsync();
}
ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}

5、start/pause/stop/seekTo

在这里做了三件事:

a. setLooping

b. setVolume

c. start

status_t MediaPlayer::start()
{
ALOGV("start"); status_t ret = NO_ERROR;
Mutex::Autolock _l(mLock); mLockThreadId = getThreadId(); if (mCurrentState & MEDIA_PLAYER_STARTED) {
ret = NO_ERROR;
} else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
mPlayer->setLooping(mLoop);
mPlayer->setVolume(mLeftVolume, mRightVolume);
mPlayer->setAuxEffectSendLevel(mSendLevel);
mCurrentState = MEDIA_PLAYER_STARTED;
ret = mPlayer->start();
if (ret != NO_ERROR) {
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
} else {
if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
ALOGV("playback completed immediately following start()");
}
}
} else {
ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
ret = INVALID_OPERATION;
} mLockThreadId = 0; return ret;
}

看到这里,Native MediaPlayer主要操作的是一个从mediaplayerservice中获取到的IMediaPlayer对象,下面一节会看看mediaplayerservice以及IMediaPlayer中到底是什么样子的。

Android 12(S) MultiMedia Learning(三)MediaPlayer Native的更多相关文章

  1. Android 12(S) 图形显示系统 - 应用建立和SurfaceFlinger的沟通桥梁(三)

    1 前言 上一篇文章中我们已经创建了一个Native示例应用,从使用者的角度了解了图形显示系统API的基本使用,从这篇文章开始我们将基于这个示例应用深入图形显示系统API的内部实现逻辑,分析运作流程. ...

  2. Android 12(S) 图形显示系统 - 基本概念(一)

    1 前言 Android图形系统是系统框架中一个非常重要的子系统,与其它子系统一样,Android 框架提供了各种用于 2D 和 3D 图形渲染的 API供开发者使用来创建绚丽多彩的应用APP.图形渲 ...

  3. Android 12(S) 图形显示系统 - SurfaceFlinger的启动和消息队列处理机制(四)

    1 前言 SurfaceFlinger作为Android图形显示系统处理逻辑的核心单元,我们有必要去了解其是如何启动,初始化及进行消息处理的.这篇文章我们就来简单分析SurfaceFlinger这个B ...

  4. Android 12(S) 图形显示系统 - createSurface的流程(五)

    题外话 刚刚开始着笔写作这篇文章时,正好看电视在采访一位92岁的考古学家,在他的日记中有这样一句话,写在这里与君共勉"不要等待幸运的降临,要去努力的掌握知识".如此朴实的一句话,此 ...

  5. Android 12(S) 图形显示系统 - BufferQueue的工作流程(八)

    题外话 最近总有一个感觉:在不断学习中,越发的感觉自己的无知,自己是不是要从"愚昧之巅"掉到"绝望之谷"了,哈哈哈 邓宁-克鲁格效应 一.前言 前面的文章中已经 ...

  6. Android 12(S) 图形显示系统 - BufferQueue的工作流程(九)

    题外话 Covid-19疫情的强烈反弹,小区里检测出了无症状感染者.小区封闭管理,我也不得不居家办公了.既然这么大把的时间可以光明正大的宅家里,自然要好好利用,八个字 == 努力工作,好好学习 一.前 ...

  7. Android 12(S) 图形显示系统 - Surface 一点补充知识(十二)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 因为个人工作主要是Android多媒体播放的内容,在工作中查看源码或设计程序经常会遇到调用API: static inline i ...

  8. Android 12(S) 图形显示系统 - 简单聊聊 SurfaceView 与 BufferQueue的关联(十三)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 前面的文章中,讲解的内容基本都是从我们提供的一个 native demo Android 12(S) 图形显示系统 - 示例应用( ...

  9. Android 12(S) 图形显示系统 - 解读Gralloc架构及GraphicBuffer创建/传递/释放(十四)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 在前面的文章中,已经出现过 GraphicBuffer 的身影,GraphicBuffer 是Android图形显示系统中的一个重 ...

  10. Android 12(S) 图像显示系统 - 基础知识之 BitTube

    必读: Android 12(S) 图像显示系统 - 开篇 一.基本概念 在Android显示子系统中,我们会看到有使用BitTube来进行跨进程数据传递.BitTube的实现很简洁,就是一对&quo ...

随机推荐

  1. Grafana 系列-统一展示-1-开篇

    系列文章 Grafana 系列文章 Grafana 简介 Grafana 是 Grafana Labs 的第一款也是最重要的产品.它的定位是可视化, 用于监控展示 和 可观察性. 是当前最为完善.流行 ...

  2. k8s集群安装(kubeadm方式)

    一.准备三台虚拟机,系统CentOS7.9: 192.168.1.221 master1 192.168.1.189  node1 192.168.1.60  node2 二..对三台虚拟机初始化 1 ...

  3. CTFshow命令执行29-123

    命令执行 WEB29 eval是php中执行以PHP脚本执行的命令 PHP命令可以执行脚本命令 本题使用方法是先 system(cp f*.php 1.txt) 然后访问1.txt WEB30 在PH ...

  4. 使用OpenMMLab系列的开源库时,常用的脚本合集。

    使用OpenMMLab系列的开源库时,常用的脚本合集. 开源仓库:gy-7/mmlab_scripts 脚本解释: anchor_visiual.py 生成的锚框可视化 aug_test.py 自动数 ...

  5. dom4j 通用解析器,解析成List<Map<String,Object>>

    import java.io.InputStream; import java.util.Iterator; import java.util.LinkedHashMap; import java.u ...

  6. python异步字符串查找,asyncio和marisa_trie

    自然语言处理当中经常需要字符串的查找操作,比如通过查找返回字串在文本当中的位置,比如通过匹配实现的ner import pandas as pd import asyncio # data = pd. ...

  7. 【.net】Error while trying to retrieve text for error ORA-06413

    [.net]Error while trying to retrieve text for error ORA-06413 系统需要,有一个外挂系统使用的是.net,出了问题,所以部署环境查询代码 但 ...

  8. 存储过程编写·记(“xxx“在需要下列之一:if)

    存储过程编写·记("xxx"在需要下列之一:if) 使用的数据库为Oracle数据库,数据库客户端为DBeaver 简单来说,就是使用SQL语句进行一些函数编写,进而进行一些过滤啊 ...

  9. 记一次 JMeter 压测 HTTPS 性能问题

    ​简介:在使用 JMeter 压测时,发现同一后端服务,在单机 500 并发下,HTTP 和 HTTPS 协议压测 RT 差距非常大.同时观测后端服务各监控指标水位都很低,因此怀疑性能瓶颈在 JMet ...

  10. “2021ISIG中国产业智能大会低代码峰会”即将开幕,钉钉宜搭叶周全受邀出席

    ​简介:2021年12月8-9日,"2021ISIG中国产业智能大会" 将在上海举行.阿里巴巴资深技术专家,钉钉宜搭创始人叶周全将作为特邀嘉宾出席大会. 2021年12月8-9日, ...