編輯:關於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學習筆記①——安卓工具的基本安裝,android安卓 安卓已經出來很長時間了,網上的教程也有很多,怕以後忘記,就把網上大牛們的分享的知識自己在學習一下
Android下創建一個SQLite數據庫,androidsqlite數據庫:SQLite(輕量級,嵌入式的數據庫) 大量的相似結構的數據的儲存,快速的查詢。特殊的文件(
Android Develop:構建系統解析 Android構建系統是你用來構建、測試、運行和打包你的app的工具集。這個構建系統能作為Android Studio菜單
上次簡單地介紹了AudioRecord和AudioTrack的使用,這次就結合SurfaceVie
伴隨ListView、RecyclerView、ScrollView滾動