// ------ 初始化
// 方法一
MediaPlayer mp = new MediaPlayer();
mp.setDataSource("/sdcard/test.mp3");
// mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");
mp.prepare();
// 方法二
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //这时就不用调用setDataSource 和 prepare 了
// ------ 播放/暂停/停止/释放
mp.start();
mp.pause();
mp.stop();
mp.release();
// 方法一
MediaPlayer mp = new MediaPlayer();
// 方法二
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //这时就不用调用setDataSource了
frameworks\base\media\java\android\media\MediaPlayer.java
public class MediaPlayer extends PlayerBase implements SubtitleController.Listener, VolumeAutomation, AudioRouting{
public MediaPlayer() {
super(new AudioAttributes.Builder().build(), AudioPlaybackConfiguration.PLAYER_TYPE_JAM_MEDIAPLAYER);
// 线程间异步消息通信(用户不需要考虑互斥加锁的问题) looper,并创建 EventHandler
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
mTimeProvider = new TimeProvider(this);
mOpenSubtitleSources = new Vector<InputStream>();
// 调用jni层接口
native_setup(new WeakReference<MediaPlayer>(this));
baseRegisterPlayer();
}
}
有 looper 就有 handler:
frameworks\base\media\java\android\media\MediaPlayer.java
private class EventHandler extends Handler
{
private MediaPlayer mMediaPlayer;
public EventHandler(MediaPlayer mp, Looper looper) {
super(looper);
mMediaPlayer = mp;
}
@Override
public void handleMessage(Message msg) {
...
}
}
有 native 方法就有:
frameworks\base\media\java\android\media\MediaPlayer.java
static {
System.loadLibrary("media_jni");
native_init();
}
// 方法一
mp.setDataSource("/sdcard/test.mp3");
// mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");
// 方法二
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //这时就不用调用setDataSource 和 prepare了
最后都会调用到:
frameworks\base\media\java\android\media\MediaPlayer.java
private void setDataSource(String path, String[] keys, String[] values, List<HttpCookie> cookies)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
final Uri uri = Uri.parse(path);
// 查找patch对应的方案
final String scheme = uri.getScheme();
if ("file".equals(scheme)) { // 本地流
path = uri.getPath();
} else if (scheme != null) { // 非本地流,如网络片源
// handle non-file sources
nativeSetDataSource( // 非本地流调用
MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),
path,
keys,
values);
return;
}
final File file = new File(path);
try (FileInputStream is = new FileInputStream(file)) {
setDataSource(is.getFD());
}
}
private native void nativeSetDataSource(IBinder httpServiceBinder, String path, String[] keys, String[] values)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
// 本地流调用
public void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException {
_setDataSource(fd, offset, length);
}
private native void _setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException;
mp.prepare();
frameworks\base\media\java\android\media\MediaPlayer.java
public void prepare() throws IOException, IllegalStateException {
_prepare();
scanInternalSubtitleTracks();
// DrmInfo, if any, has been resolved by now.
synchronized (mDrmLock) {
mDrmInfoResolved = true;
}
}
private native void _prepare() throws IOException, IllegalStateException;
mp.start();
frameworks\base\media\java\android\media\MediaPlayer.java
// TODO: 暂时没找到怎样保存播放进度,resume如何恢复
public void start() throws IllegalStateException {
final int delay = getStartDelayMs();
if (delay == 0) {
startImpl();
} else {
new Thread() {
public void run() {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
baseSetStartDelayMs(0);
try {
startImpl();
} catch (IllegalStateException e) {
}
}
}.start();
}
}
private void startImpl() {
baseStart(); // 更新状态信息 PlayerBase.java
stayAwake(true); // 如果有显示,则保持亮屏
_start();
}
private native void _start() throws IllegalStateException;
mp.pause();
frameworks\base\media\java\android\media\MediaPlayer.java
public void pause() throws IllegalStateException {
stayAwake(false); // 如果有显示,关闭保持亮屏
_pause();
basePause(); // 更新状态信息 PlayerBase.java
}
private native void _pause() throws IllegalStateException;
mp.stop();
frameworks\base\media\java\android\media\MediaPlayer.java
public void stop() throws IllegalStateException {
stayAwake(false); // 如果有显示,关闭保持亮屏
_stop();
baseStop(); // 更新状态信息 PlayerBase.java
}
private native void _stop() throws IllegalStateException;
mp.reset();
frameworks\base\media\java\android\media\MediaPlayer.java
public void reset() {
mSelectedSubtitleTrackIndex = -1;
synchronized(mOpenSubtitleSources) {
for (final InputStream is: mOpenSubtitleSources) {
try {
is.close();
} catch (IOException e) {
}
}
mOpenSubtitleSources.clear();
}
if (mSubtitleController != null) {
mSubtitleController.reset();
}
synchronized (mTimeProviderLock) {
if (mTimeProvider != null) {
mTimeProvider.close();
mTimeProvider = null;
}
}
stayAwake(false);
_reset();
// make sure none of the listeners get called anymore
if (mEventHandler != null) {
mEventHandler.removeCallbacksAndMessages(null);
}
synchronized (mIndexTrackPairs) {
mIndexTrackPairs.clear();
mInbandTrackIndices.clear();
};
resetDrmState();
}
private native void _reset();
mp.release();
frameworks\base\media\java\android\media\MediaPlayer.java
public void release() {
baseRelease();
stayAwake(false);
updateSurfaceScreenOn();
mOnPreparedListener = null;
mOnBufferingUpdateListener = null;
mOnCompletionListener = null;
mOnSeekCompleteListener = null;
mOnErrorListener = null;
mOnInfoListener = null;
mOnVideoSizeChangedListener = null;
mOnTimedTextListener = null;
synchronized (mTimeProviderLock) {
if (mTimeProvider != null) {
mTimeProvider.close();
mTimeProvider = null;
}
}
synchronized(this) {
mSubtitleDataListenerDisabled = false;
mExtSubtitleDataListener = null;
mExtSubtitleDataHandler = null;
mOnMediaTimeDiscontinuityListener = null;
mOnMediaTimeDiscontinuityHandler = null;
}
// Modular DRM clean up
mOnDrmConfigHelper = null;
mOnDrmInfoHandlerDelegate = null;
mOnDrmPreparedHandlerDelegate = null;
resetDrmState();
_release();
}
private native void _release();