Android 音視頻深入 十三 OpenSL ES 製作音樂播放器,能暫停和調整音量(附源碼下載)

來源:互聯網
上載者:User

標籤:音視頻   OpenSL ES   

項目地址
https://github.com/979451341/OpenSLAudio

OpenSL ES 是基於NDK也就是c語言的底層開發音訊公開API,通過使用它能夠做到標準化, 高效能,低回應時間的音頻功能實現方法。

這次是使用OpenSL ES來做一個音樂播放器,它能夠播放m4a、mp3檔案,並能夠暫停和調整音量

播放音樂需要做一些步驟
1.建立聲音引擎

首先建立聲音引擎的對象介面
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);

然後實現它
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);

從聲音引擎的對象中抓取聲音引擎
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);

建立"輸出混音器"
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);

實現輸出混合音
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);

2.建立聲音播放器

建立和實現播放器

// realize the playerresult = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);assert(SL_RESULT_SUCCESS == result);(void)result;// get the play interfaceresult = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);assert(SL_RESULT_SUCCESS == result);(void)result;

3.設定播放緩衝

資料格式配置

SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_8,                               SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,                               SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};

資料定位器 就是定位要播放聲音資料的存放位置,分為4種:記憶體位置,輸入/輸出裝置位置,緩衝區隊列位置,和midi緩衝區隊列位置。
資料定位器配置

SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

得到了緩衝隊列介面,並註冊

// get the buffer queue interfaceresult = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,                                         &bqPlayerBufferQueue);assert(SL_RESULT_SUCCESS == result);(void)result;// register callback on the buffer queueresult = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);assert(SL_RESULT_SUCCESS == result);(void)result;

4.獲得其他介面用來控制播放

得到聲音特效介面

// get the effect send interfaceresult = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND,                                         &bqPlayerEffectSend);assert(SL_RESULT_SUCCESS == result);(void)result;

得到音量介面

// get the volume interfaceresult = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);assert(SL_RESULT_SUCCESS == result);(void)result;// set the player‘s state to playingresult = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);assert(SL_RESULT_SUCCESS == result);(void)result;

5.提供播放資料

開啟音樂檔案

// convert Java string to UTF-8const char *utf8 = (*env)->GetStringUTFChars(env, filename, NULL);assert(NULL != utf8);// use asset manager to open asset by filenameAAssetManager* mgr = AAssetManager_fromJava(env, assetManager);assert(NULL != mgr);AAsset* asset = AAssetManager_open(mgr, utf8, AASSET_MODE_UNKNOWN);// release the Java string and UTF-8(*env)->ReleaseStringUTFChars(env, filename, utf8);// the asset might not be foundif (NULL == asset) {    return JNI_FALSE;}// open asset as file descriptoroff_t start, length;int fd = AAsset_openFileDescriptor(asset, &start, &length);assert(0 <= fd);AAsset_close(asset);

設定播放資料

SLDataLocator_AndroidFD loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};SLDataSource audioSrc = {&loc_fd, &format_mime};

6.播放音樂

播放音樂只需要通過播放介面改變播放狀態就可以了,暫停也是,停止也是,但是暫停必須之前的播放緩衝做了才行,否則那暫停就相當於停止了

    result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, isPlaying ?                                                         SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED);

7.調解音量

SLVolumeItf getVolume()
{
if (fdPlayerVolume != NULL)
return fdPlayerVolume;
else
return bqPlayerVolume;
}

void Java_com_ywl5320_openslaudio_MainActivity_setVolumeAudioPlayer(JNIEnv env, jclass clazz,
jint millibel)
{
SLresult result;
SLVolumeItf volumeItf = getVolume();
if (NULL != volumeItf) {
result = (
volumeItf)->SetVolumeLevel(volumeItf, millibel);
assert(SL_RESULT_SUCCESS == result);
(void)result;
}
}
8.釋放資源

關閉app時釋放佔用資源

void Java_com_ywl5320_openslaudio_MainActivity_shutdown(JNIEnv* env, jclass clazz)
{

// destroy buffer queue audio player object, and invalidate all associated interfacesif (bqPlayerObject != NULL) {    (*bqPlayerObject)->Destroy(bqPlayerObject);    bqPlayerObject = NULL;    bqPlayerPlay = NULL;    bqPlayerBufferQueue = NULL;    bqPlayerEffectSend = NULL;    bqPlayerMuteSolo = NULL;    bqPlayerVolume = NULL;}// destroy file descriptor audio player object, and invalidate all associated interfacesif (fdPlayerObject != NULL) {    (*fdPlayerObject)->Destroy(fdPlayerObject);    fdPlayerObject = NULL;    fdPlayerPlay = NULL;    fdPlayerSeek = NULL;    fdPlayerMuteSolo = NULL;    fdPlayerVolume = NULL;}// destroy output mix object, and invalidate all associated interfacesif (outputMixObject != NULL) {    (*outputMixObject)->Destroy(outputMixObject);    outputMixObject = NULL;    outputMixEnvironmentalReverb = NULL;}// destroy engine object, and invalidate all associated interfacesif (engineObject != NULL) {    (*engineObject)->Destroy(engineObject);    engineObject = NULL;    engineEngine = NULL;}

}
參考文章
http://blog.csdn.net/u013898698/article/details/72822595

http://blog.csdn.net/ywl5320/article/details/78503768

Android 音視頻深入 十三 OpenSL ES 製作音樂播放器,能暫停和調整音量(附源碼下載)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.