start是MusicDemo中播放音乐的最后一步,也是最重要的一步。这里我们就得把三步都打开了,后面为了看清楚,可以把前面两步的日志先过滤出去。
private void play(){
try {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Music/Test.mp3";
player.setDataSource(path);
Log.d("Jaychou","MusicDemo setDataSource");
player.prepare();
Log.d("Jaychou","MusicDemo Prepare");
player.start();
Log.d("Jaychou","MusicDemo start");
} catch (IOException e) {
e.printStackTrace();
Log.d("Jaychou","err when play");
}
}
1. start流程图
和之前一样,还是先来看一看start的流程图,其实和setDataSource和prepare几乎是一样的。
2. client端
如之前一样,MusicDemo, MediaPlayer.java和MediaPlayer.cpp都是属于Client端,它们是跑在同一个进程里面。
这里也简单用下图示例一下。
从MusicDemo一直到MediaPlayer.cpp的start
./frameworks/av/media/libmedia/Mediaplayer.cpp#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;
}
可以看到,这里也没有做多少事情,就是调用server端来设置是否循环,音量等参数,当然,最重要的是调用server端的start。
以下是一些相关的日志可供参考。
02-17 17:51:59.379 V/MediaPlayer-JNI( 5974): start
02-