Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android4.1 MediaPlayer無縫播放

Android4.1 MediaPlayer無縫播放

編輯:關於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函數。

  1. status_t MediaPlayerService::Client::setNextPlayer(const sp<IMediaPlayer>& player) { 
  2.     ALOGV("setNextPlayer"); 
  3.     Mutex::Autolock l(mLock); 
  4.     sp<Client> c = static_cast<Client*>(player.get()); 
  5.     mNextClient = c; 
  6.     if (mAudioOutput != NULL && c != NULL) { 
  7.         mAudioOutput->setNextOutput(c->mAudioOutput); 
  8.     } else { 
  9.         ALOGE("no current audio output"); 
  10.     } 
  11.     return OK; 

 

 從MediaPlayerServie中的client獲得另外一個track的AndroidOutput

void MediaPlayerService::AudioOutput::setNextOutput(const sp<AudioOutput>& nextOutput) {
    mNextOutput = nextOutput;
}

   設置好了mNextOutput後,AndroidOutput定義了另外一個重要的函數switchToNextOutput

 

  1. void MediaPlayerService::AudioOutput::switchToNextOutput() { 
  2.     ALOGV("switchToNextOutput"); 
  3.     if (mNextOutput != NULL) { 
  4.         if (mCallbackData != NULL) { 
  5.             mCallbackData->beginTrackSwitch(); 
  6.         } 
  7.         delete mNextOutput->mCallbackData; 
  8.         mNextOutput->mCallbackData = mCallbackData; 
  9.         mCallbackData = NULL; 
  10.         mNextOutput->mRecycledTrack = mTrack; 
  11.         mTrack = NULL; 
  12.         mNextOutput->mSampleRateHz = mSampleRateHz; 
  13.         mNextOutput->mMsecsPerFrame = mMsecsPerFrame; 
  14.         mNextOutput->mBytesWritten = mBytesWritten; 
  15.         mNextOutput->mFlags = mFlags; 
  16.     } 

 這個函數的調用是在notify函數中,

 

  1. void MediaPlayerService::Client::notify( 
  2.         void* cookie, int msg, int ext1, int ext2, const Parcel *obj) 
  3.     Client* client = static_cast<Client*>(cookie); 
  4.  
  5.     { 
  6.         Mutex::Autolock l(client->mLock); 
  7.         if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) { 
  8.             client->mAudioOutput->switchToNextOutput(); 
  9.             client->mNextClient->start(); 
  10.             client->mNextClient->mClient->notify(MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj); 
  11.         } 
  12.     } 
  13.  
  14.     if (MEDIA_INFO == msg && 
  15.         MEDIA_INFO_METADATA_UPDATE == ext1) { 
  16.         const media::Metadata::Type metadata_type = ext2; 
  17.  
  18.         if(client->shouldDropMetadata(metadata_type)) { 
  19.             return; 
  20.         } 
  21.  
  22.         // Update the list of metadata that have changed. getMetadata 
  23.         // also access mMetadataUpdated and clears it. 
  24.         client->addNewMetadataUpdate(metadata_type); 
  25.     } 
  26.     ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); 
  27.     client->mClient->notify(msg, ext1, ext2, obj); 

  當前播放的client發出MEDIA_PLAYBACK_COMPLETE消息時,調用switchToNextOutput函數,從而實現了兩個獨立的MediaPlayer的無縫播放。

  三、總結
無縫播放是android4.1添加的新的特性,支持音頻流在一起播放而不產生停頓。這對需要在不同的音頻文件無縫轉換的App很有用。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved