編輯:Android開發實例
摘要:在Android4.1中,MediaPlayer實現兩個完全獨立的MediaPlayer類上執行無縫播放,這裡介紹一下Android是如何實現無縫播放的。
一、使用方法
在第一個MediaPlayer類執行結束前的任何時間調用setNextMediaPlayer(MediaPlayer next)這個方法,該方法的參數是第二個文件創建的MediaPlayer實例。然後Android系統將會在您第一個停止的時候緊接著播放第二個文件。
二、實現
MediaPlayer類中的setNextMediaPlayer方法一路追蹤JNI層的Android_Media_MediaPlayer.cpp,再到MediaPlayer.cpp,通過IMediaPlayer.cpp中的BnMediaPlayer到MediaPlayerService中的Client::setNextPlayer函數。
- status_t MediaPlayerService::Client::setNextPlayer(const sp<IMediaPlayer>& player) {
- ALOGV("setNextPlayer");
- Mutex::Autolock l(mLock);
- sp<Client> c = static_cast<Client*>(player.get());
- mNextClient = c;
- if (mAudioOutput != NULL && c != NULL) {
- mAudioOutput->setNextOutput(c->mAudioOutput);
- } else {
- ALOGE("no current audio output");
- }
- return OK;
- }
從MediaPlayerServie中的client獲得另外一個track的AndroidOutput
void MediaPlayerService::AudioOutput::setNextOutput(const sp<AudioOutput>& nextOutput) { mNextOutput = nextOutput; }
設置好了mNextOutput後,AndroidOutput定義了另外一個重要的函數switchToNextOutput
- void MediaPlayerService::AudioOutput::switchToNextOutput() {
- ALOGV("switchToNextOutput");
- if (mNextOutput != NULL) {
- if (mCallbackData != NULL) {
- mCallbackData->beginTrackSwitch();
- }
- delete mNextOutput->mCallbackData;
- mNextOutput->mCallbackData = mCallbackData;
- mCallbackData = NULL;
- mNextOutput->mRecycledTrack = mTrack;
- mTrack = NULL;
- mNextOutput->mSampleRateHz = mSampleRateHz;
- mNextOutput->mMsecsPerFrame = mMsecsPerFrame;
- mNextOutput->mBytesWritten = mBytesWritten;
- mNextOutput->mFlags = mFlags;
- }
- }
這個函數的調用是在notify函數中,
- void MediaPlayerService::Client::notify(
- void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
- {
- Client* client = static_cast<Client*>(cookie);
- {
- Mutex::Autolock l(client->mLock);
- if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
- client->mAudioOutput->switchToNextOutput();
- client->mNextClient->start();
- client->mNextClient->mClient->notify(MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
- }
- }
- if (MEDIA_INFO == msg &&
- MEDIA_INFO_METADATA_UPDATE == ext1) {
- const media::Metadata::Type metadata_type = ext2;
- if(client->shouldDropMetadata(metadata_type)) {
- return;
- }
- // Update the list of metadata that have changed. getMetadata
- // also access mMetadataUpdated and clears it.
- client->addNewMetadataUpdate(metadata_type);
- }
- ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
- client->mClient->notify(msg, ext1, ext2, obj);
- }
當前播放的client發出MEDIA_PLAYBACK_COMPLETE消息時,調用switchToNextOutput函數,從而實現了兩個獨立的MediaPlayer的無縫播放。
三、總結
無縫播放是android4.1添加的新的特性,支持音頻流在一起播放而不產生停頓。這對需要在不同的音頻文件無縫轉換的App很有用。
本文實例總結了 Android中Notification用法。分享給大家供大家參考,具體如下: 我們在用手機的時候,如果來了短信,而我們沒有點擊查看的話,是不是在
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
大家好,眾所周知,android裡兩個相同方向的ScrollView是不能嵌套的,那要是有這樣的需求怎麼辦?(這個需求一般都是不懂android的人提出來的)難道
本文實例講述了Android實現仿通訊錄側邊欄滑動SiderBar效果代碼。分享給大家供大家參考,具體如下: 之前看到某些應用的側邊欄做得不錯,想想自己也弄一個出