基于Android8.1代码 java MediaPlayer() 先从源头开始看 frameworks/base/media/java/android/media/MediaPlayer.java public MediaPlayer() { super(new AudioAttributes.Builder().build(), AudioPlaybackConfiguration.PLAYER_TYPE_JAM_MEDIAPLAYER <MediaPlayer>(this)); frameworks/base/media/jni/android_media_MediaPlayer.cpp static void android_media_MediaPlayer_native_setup ,将java的MediaPlayer实例传递进去 3 将JNIMediaPlayerListener 设置给MediaPlayer() 4 将FFMediaPlayer 设置给Java层的mNativeContext MediaPlayer() frameworks/av/media/libmedia/mediaplayer.cpp MediaPlayer::MediaPlayer() { ALOGV("constructor
MediaPlayer涉及的的文件路径 这里参考的是android8.1 的代码 JAVA类的路径: frameworks/base/media/java/android/media/MediaPlayer.java JNI路径: frameworks/base/media/jni/android_media_MediaPlayer.cpp 编译为 libmedia_jni.so native 层的接口 frameworks MediaPlayerArch.png MediaPlayer是给应用层提供的接口,通过jni调用native层,native层又采用C/S框架,通过binder调用到service端, servcie
private MediaPlayer mediaPlayer = new MediaPlayer(); @Override protected void onCreate( (file.getPath());//指定音频文件的路径 mediaPlayer.prepare();//让MediaPlayer进入到准备状态 }catch ( mediaPlayer.isPlaying()){ mediaPlayer.start();//开始播放 } = null){ mediaPlayer.stop(); mediaPlayer.release(); } } } 接下来我么来解释一下这一段代码 当点击Stop按钮时会进行判断,如果当前MediaPlayer正在播放音频就调用reset()方法将MediaPlayer重置为刚刚创建时的状态,然后重新调用一遍initMediaPlayer()方法。
为了模拟实现Android MediaPlayer的实现,需要先了解下MediaPlayer的简单使用方法, 这里只列举其中一种使用方式, 以这个为模板利用ffmpeg实现对应的同名接口和调用方法. MediaPlayer状态 首先还是贴一下Android MediaPlayer 的状态转换图.因为所有接口的设计和调用方法会以这个状态转换图为依据, 理解状态图也能更好地理解播放器 ? mediaplayer_state_diagram.gif 其实理解Android MediaPlayer最直接的方法是看google的官方文档 https://developer.android.google.cn /reference/android/media/MediaPlayer 因为已经有大量的文章转载和翻译,所以这里暂时不做介绍和翻译,可能会在后续实现接口的过程中引用和参考里面的内容 MediaPlayer MediaPlayerDemo.png 目前还是很不完善, 不过先从简单开始,再一步一步搭建由ffmpeg实现的播放器.从Demo看出,要创建一个可以用的播放器demo,需要实现以下的接口 public MediaPlayer
frameworks/base/media/java/android/media/MediaPlayer.java /** * Starts or resumes playback. 这里没有太多逻辑,直接调用了jni的_start方法 static void android_media_MediaPlayer_start(JNIEnv *env, jobject thiz) { ALOGV("start"); sp<MediaPlayer> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException process_media_player_call( env, thiz, mp->start(), NULL, NULL ); } 直接调用下一层 frameworks/av/media/libmedia/mediaplayer.cpp status_t MediaPlayer::start() { ALOGV("start"); status_t ret = NO_ERROR; Mutex::Autolock
frameworks/base/media/java/android/media/MediaPlayer.java /** * Resets the MediaPlayer to its static void android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz) { ALOGV("reset"); sp< MediaPlayer> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException(env, "java status_t MediaPlayer::reset_l() { mLoop = false; if (mCurrentState == MEDIA_PLAYER_IDLE) return 接着通过p 将NuPlayer的回调函数置为0,并调用到NuPlayer的reset方法,这里是重复调用了reset方法,因为release流程只会调用mediaplayer的disconnect方法,
frameworks/base/media/java/android/media/MediaPlayer.java /** * Prepares the player for playback /home/llm/project/rk/8.1/frameworks/base/media/jni/android_media_MediaPlayer.cpp static void android_media_MediaPlayer_prepareAsync 接着调用到mediaplayer.cpp的接口 status_t MediaPlayer::prepareAsync() { ALOGV("prepareAsync"); Mutex:: 在执行往prepareAsync后会将状态置为prepared,这个操作是在MediaPlayer::notify处理的 void MediaPlayer::notify(int msg, int ext1 我们知道MediaPlayer prepare方法是阻塞的,实际上prepare就是调用mSignal.wait进行等待,其他地方跟prepareAsync的流程是差不多的 status_t MediaPlayer
常见错误 error(-38, 0) 我觉得-38表示在当前的MediaPlayer状态下,不能运行你的操作。 详细怎样做请參考:Android MediaPlayer 另外我在其它资料中。 In this case, the application must release the MediaPlayer object and instantiate a new one. Added in API level 9 MediaPlayer is resuming playback after filling buffers. Added in API level 9 MediaPlayer is temporarily pausing playback internally in order to buffer more Added in API level 3 The media cannot be seeked (e.g live stream) See Also MediaPlayer.OnInfoListener
为了方便先重复贴一下MediaPlayer的状态图和MediaPlayer 的基本框架 ? mediaplayer_state_diagram.gif ? MediaPlayerArch.png 总的分为几个模块,为方便后续文章的书写,各模块后续统一用括号里面的名词 java层MediaPlayer(MediaPlayer) jni层(jni) mediaplayer (NuPlayer) MediaPlayer的状态变量是由mediaplayer记录的 系统初始化 MediaPlayerService是一个native系统服务,在系统初始化阶段,具体是init进程解析 实例或MediaPlayer实例已经创建reset()进入个状态。 1.创建播放器 new mediaplayer实例 设置 mediaplayer --> jni --> MediaPlayer 回调listener 2.reset() 销毁MediaPlayerService
在用 Android 的 MediaPlayer 做 音频播放器 开发时,遇到了一些问题,在此总结。 MediaPlayer 包含了很多状态: Idle, End, Initialized, Prepared, Preparing, Started, Paused, Stop, PlaybackCompleted start() -> [pause() -> start()] -> stop() -> [prepare() -> start() ... -> stop()] -> release() 此外,应注意 MediaPlayer
release相比reset流程,多了一些处理 MediaPlayer层将MediaPlayer的各种listener置为null jni层减少了对surface的引用 jni层销毁了mediaplayer 的实例 这里先偷懒,没详细分析 /** * Releases resources associated with this MediaPlayer object * It is considered good practice to call this method when you're * done using the MediaPlayer * or stopped (its onStop() method is called), this method should be * invoked to release the MediaPlayer (JNIEnv *env, jobject thiz) { ALOGV("release"); decVideoSurfaceRef(env, thiz); sp<MediaPlayer
frameworks/base/media/java/android/media/MediaPlayer.java /** * Stops playback after playback PlayerBase 的接口,这部分主要针对audio, 后面有时间再结合audio模块来分析 下面主要分析一般的流程_stop() frameworks/base/media/jni/android_media_MediaPlayer.cpp static void android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz) { ALOGV("stop"); sp<MediaPlayer status_t MediaPlayer::stop() { ALOGV("stop"); Mutex::Autolock _l(mLock); //已经是stop状态,则直接返回 MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE. mPlayer是mediaplayer
那么可能会黑屏,播放的起点也必须放在surfaceViewCreate里面,只能从这里恢复播放,同时activity强制性退出的时候,需要在surfaceDestroyed把position记录下来,同时如果mediaPlayer position = mediaPlayer.getCurrentPosition(); mediaPlayer.stop(); } 3.播放完毕之后 播放时间, 7.mediaPlayer如果多次销毁,又多次创建,可能也会每次都去分配一定的空间,代价也是蛮大的,但是安全,不会出现为null的情况 8.这个时候如果是播放同一个视频,这里也会造成卡顿的原因 (AudioManager.STREAM_VOICE_CALL);//听筒模式 mediaPlayer 的方法是: Valid and invalid states Method Name Valid surfaceView的相关概念: MediaPlayer主要用于播放音频,它是没有提供输出图像的输出界面,这时我们就用到了SurfaceView控件,将它与MediaPlayer结合起来,就能达到了视频的输出了
结构框架 上一篇文章MediaPlayer--MediaPlayer基本框架没有将C++的mediaplayer binder通讯展开,这篇文章主要展开这一部分。 大概画了下C++ MediaPlayer的uml图,不是很满意,请高手指教 ? IMediaPlayerClient 的服务端在mediaplayer.cpp, 客户端在MediaPlayerService.cpp, 这是MediaPlayerService回调mediaplayer 将IMediaPlayer binder返回MediaPlayer。 调用MediaPlayer接口 ?
本文链接: Android MediaPlayer 播放音频 主要介绍使用MediaPlayer播放音频的方式。 关于MediaPlayer的基础知识,比如状态,可以参考Android MediaPlayer 基础简介。 为了方便表达,定义变量名为mediaPlayer。 MediaPlayer的使用方式 创建MediaPlayer 可以直接 new MediaPlayer,也可以用MediaPlayer提供的create方法创建。 mediaPlayer = new MediaPlayer(); 使用create方法创建成功后,mediaPlayer处于Prepared状态。可以直接start播放。 mediaPlayer; try { mediaPlayer = new MediaPlayer(); mediaPlayer.setLooping(false
从Android API 23 (Android M)开始,MediaPlayer支持调整播放速度。 本文介绍如何使用MediaPlayer调整播放速度。 如果MediaPlayer没有准备(在prepared之前),调用此方法并不会改变MediaPlayer的状态。 MediaPlayer.setPlaybackParams 方法示例 设置播放速度。先判断当前系统版本。 基础简介 Android MediaPlayer 播放音频 Android 使用URLConnection下载音频文件 Android MediaPlayer 音频倍速播放,调整播放速度 Android
/** * 初始化 及 资源准备 */ private fun audioPrepare(path: String) { mMediaPlayer = MediaPlayer
通过对CWMPPlayer4、CWMPSettings和CWMPControls等几个类的使用可以实现Windows Media Player的大部分常规功能,如果需要做进一步的控制,可以在用下面这些函数返回相关类对象后调用相关成员函数来加以实现:
Android里面提供了MediaPlayer类来播放媒体文件,下面来看一下怎样用MediaPlayer对象来播放媒体文件: 一般来说,用MediaPlayer类来播放媒体文件有以下几个步骤: 1、 新建一个MediaPlayer对象。 static int MEDIAPLAYER_STATE = MEDIAPLAYER_IS_STOP; // 开始的时候MediaPlayer对象处于停止状态 @Override (); MEDIAPLAYER_STATE = MEDIAPLAYER_IS_PLAYING; updateButtonState(MEDIAPLAYER_STATE); == MEDIAPLAYER_IS_PAUSE) { mediaPlayer.start(); MEDIAPLAYER_STATE =
+MediaPlayer 来播放视频。 2.MediaPlayer的输出 在 GLVideoRenderer 的构造函数中初始化 MediaPlayer : mediaPlayer=new MediaPlayer(); try ); mediaPlayer.setLooping(true); mediaPlayer.setOnVideoSizeChangedListener(this); onSurfaceCreated 函数中使用SurfaceTexture来设置MediaPlayer的输出。 =new MediaPlayer(); try{ mediaPlayer.setDataSource(context, Uri.parse(videoPath))