translate audio_player.c into English

translate audio_player.c into English
pull/166/head
xufulong 5 years ago
parent 3e4def578d
commit 639c0082bf
  1. 91
      app/src/main/cpp/openSL_audio_player.c

@ -17,29 +17,28 @@
#define TAG "OpenSLPlayer" #define TAG "OpenSLPlayer"
//引擎接口 //object of engine
SLObjectItf engineObject = NULL; SLObjectItf engineObject = NULL;
SLEngineItf engineEngine; SLEngineItf engineEngine;
//输出混音器接口 //object of mixer
SLObjectItf outputMixObject = NULL; SLObjectItf outputMixObject = NULL;
SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL; SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
//缓冲播放器接口 //object of buffer
SLObjectItf bqPlayerObject = NULL; SLObjectItf bqPlayerObject = NULL;
SLPlayItf bqPlayerPlay; SLPlayItf bqPlayerPlay;
SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
SLEffectSendItf bqPlayerEffectSend; SLEffectSendItf bqPlayerEffectSend;
SLVolumeItf bqPlayerVolume; SLVolumeItf bqPlayerVolume;
//音效设置 //audio effect
const SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR; const SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
void *buffer; void *buffer;
size_t bufferSize; size_t bufferSize;
uint8_t *outputBuffer; uint8_t *outputBuffer;
size_t outputBufferSize; size_t outputBufferSize;
//FFmpeg相关
AVPacket packet; AVPacket packet;
int audioStream; int audioStream;
AVFrame *aFrame; AVFrame *aFrame;
@ -48,48 +47,40 @@ AVFormatContext *aFormatCtx;
AVCodecContext *aCodecCtx; AVCodecContext *aCodecCtx;
int frame_count = 0; int frame_count = 0;
int createAudioPlayer(int *rate, int *channel, const char *file_name) ; int createAudioPlayer(int *rate, int *channel, const char *file_name);
// 释放相关资源
int releaseAudioPlayer(); int releaseAudioPlayer();
// 获取PCM数据, 自动回调获取 int getPCM(void **pcm, size_t *pcmSize);
int getPCM(void **pcm, size_t *pcmSize) ;
//播放回调方法 //callback by player
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bufferQueueItf, void *context) { void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bufferQueueItf, void *context) {
bufferSize = 0; bufferSize = 0;
getPCM(&buffer, &bufferSize); getPCM(&buffer, &bufferSize);
//如果buffer不为空,入待播放队列
if (NULL != buffer && 0 != bufferSize) { if (NULL != buffer && 0 != bufferSize) {
SLresult result; SLresult result;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer, bufferSize); result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer, bufferSize);
if(result < 0){ if (result < 0) {
LOGE(TAG, "Enqueue error..."); LOGE(TAG, "Enqueue error...");
} else{ } else {
LOGI(TAG, "decode frame count=%d", frame_count++); LOGI(TAG, "decode frame count=%d", frame_count++);
} }
} }
} }
//创建OpenSLES引擎 //create the engine of OpenSLES
void createEngine() { void createEngine() {
SLresult result; SLresult result;
//创建引擎
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
LOGI(TAG, "slCreateEngine=%d", result); LOGI(TAG, "slCreateEngine=%d", result);
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
LOGI(TAG, "engineObject->Realize=%d", result); LOGI(TAG, "engineObject->Realize=%d", result);
//获取引擎接口
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
LOGI(TAG, "engineObject->GetInterface=%d", result); LOGI(TAG, "engineObject->GetInterface=%d", result);
//创建输出混音器
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0); result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
LOGI(TAG, "CreateOutputMix=%d", result); LOGI(TAG, "CreateOutputMix=%d", result);
//关联输出混音器
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
LOGI(TAG, "outputMixObject->Realize=%d", result); LOGI(TAG, "outputMixObject->Realize=%d", result);
//获取reverb接口
result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB, result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
&outputMixEnvironmentalReverb); &outputMixEnvironmentalReverb);
LOGI(TAG, "outputMixObject->GetInterface=%d", result); LOGI(TAG, "outputMixObject->GetInterface=%d", result);
@ -101,12 +92,12 @@ void createEngine() {
} }
//创建带有缓冲队列的音频播放器
void createBufferQueueAudioPlayer(int rate, int channel, int bitsPerSample) { void createBufferQueueAudioPlayer(int rate, int channel, int bitsPerSample) {
SLresult result; SLresult result;
//配置音频源 //config audio source
SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
2};
SLDataFormat_PCM format_pcm; SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = (SLuint32) channel; format_pcm.numChannels = (SLuint32) channel;
@ -120,66 +111,54 @@ void createBufferQueueAudioPlayer(int rate, int channel, int bitsPerSample) {
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
SLDataSource audioSrc = {&buffer_queue, &format_pcm}; SLDataSource audioSrc = {&buffer_queue, &format_pcm};
//配置音频池
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL}; SLDataSink audioSnk = {&loc_outmix, NULL};
//创建音频播放器
const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME}; const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
3, ids, req); 3, ids, req);
LOGI(TAG, "CreateAudioPlayer=%d", result); LOGI(TAG, "CreateAudioPlayer=%d", result);
//关联播放器
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
LOGI(TAG, "bqPlayerObject Realize=%d", result); LOGI(TAG, "bqPlayerObject Realize=%d", result);
//获取播放接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
LOGI(TAG, "GetInterface bqPlayerPlay=%d", result); LOGI(TAG, "GetInterface bqPlayerPlay=%d", result);
//获取缓冲队列接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue); &bqPlayerBufferQueue);
LOGI(TAG, "GetInterface bqPlayerBufferQueue=%d", result); LOGI(TAG, "GetInterface bqPlayerBufferQueue=%d", result);
//注册缓冲队列回调
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL); result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
LOGI(TAG, "RegisterCallback=%d", result); LOGI(TAG, "RegisterCallback=%d", result);
//获取音效接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND, result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND,
&bqPlayerEffectSend); &bqPlayerEffectSend);
LOGI(TAG, "GetInterface effect=%d", result); LOGI(TAG, "GetInterface effect=%d", result);
//获取音量接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume); result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
LOGI(TAG, "GetInterface volume=%d", result); LOGI(TAG, "GetInterface volume=%d", result);
//开始播放音乐
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
LOGI(TAG, "SetPlayState=%d", result); LOGI(TAG, "SetPlayState=%d", result);
} }
int createAudioPlayer(int *rate, int *channel, const char *file_name) { int createAudioPlayer(int *rate, int *channel, const char *file_name) {
//注册相关组件
av_register_all(); av_register_all();
aFormatCtx = avformat_alloc_context(); aFormatCtx = avformat_alloc_context();
//打开音频文件
if (avformat_open_input(&aFormatCtx, file_name, NULL, NULL) != 0) { if (avformat_open_input(&aFormatCtx, file_name, NULL, NULL) != 0) {
LOGE(TAG, "Couldn't open file:%s\n", file_name); LOGE(TAG, "Couldn't open file:%s\n", file_name);
return -1; // Couldn't open file return -1;
} }
//寻找stream信息
if (avformat_find_stream_info(aFormatCtx, NULL) < 0) { if (avformat_find_stream_info(aFormatCtx, NULL) < 0) {
LOGE(TAG, "Couldn't find stream information."); LOGE(TAG, "Couldn't find stream information.");
return -1; return -1;
} }
//寻找音频stream
int i; int i;
audioStream = -1; audioStream = -1;
for (i = 0; i < aFormatCtx->nb_streams; i++) { for (i = 0; i < aFormatCtx->nb_streams; i++) {
@ -192,64 +171,56 @@ int createAudioPlayer(int *rate, int *channel, const char *file_name) {
LOGE(TAG, "Couldn't find audio stream!"); LOGE(TAG, "Couldn't find audio stream!");
return -1; return -1;
} }
//获取解码器context
aCodecCtx = aFormatCtx->streams[audioStream]->codec; aCodecCtx = aFormatCtx->streams[audioStream]->codec;
//寻找音频解码器
AVCodec *aCodec = avcodec_find_decoder(aCodecCtx->codec_id); AVCodec *aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if (!aCodec) { if (!aCodec) {
fprintf(stderr, "Unsupported codec!\n"); fprintf(stderr, "Unsupported codec!\n");
return -1; return -1;
} }
//打开解码器
if (avcodec_open2(aCodecCtx, aCodec, NULL) < 0) { if (avcodec_open2(aCodecCtx, aCodec, NULL) < 0) {
LOGE(TAG, "Could not open codec."); LOGE(TAG, "Could not open codec.");
return -1; return -1;
} }
aFrame = av_frame_alloc(); aFrame = av_frame_alloc();
// 设置格式转换
swr = swr_alloc(); swr = swr_alloc();
av_opt_set_int(swr, "in_channel_layout", aCodecCtx->channel_layout, 0); av_opt_set_int(swr, "in_channel_layout", aCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "out_channel_layout", aCodecCtx->channel_layout, 0); av_opt_set_int(swr, "out_channel_layout", aCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "in_sample_rate", aCodecCtx->sample_rate, 0); av_opt_set_int(swr, "in_sample_rate", aCodecCtx->sample_rate, 0);
av_opt_set_int(swr, "out_sample_rate", aCodecCtx->sample_rate, 0); av_opt_set_int(swr, "out_sample_rate", aCodecCtx->sample_rate, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", aCodecCtx->sample_fmt, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", aCodecCtx->sample_fmt, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
swr_init(swr); swr_init(swr);
// 分配PCM数据缓存
outputBufferSize = 8196; outputBufferSize = 8196;
outputBuffer = (uint8_t *) malloc(sizeof(uint8_t) * outputBufferSize); outputBuffer = (uint8_t *) malloc(sizeof(uint8_t) * outputBufferSize);
// 返回sample rate和channels
*rate = aCodecCtx->sample_rate; *rate = aCodecCtx->sample_rate;
*channel = aCodecCtx->channels; *channel = aCodecCtx->channels;
return 0; return 0;
} }
// 获取PCM数据, 自动回调获取
int getPCM(void **pcm, size_t *pcmSize) { int getPCM(void **pcm, size_t *pcmSize) {
while (av_read_frame(aFormatCtx, &packet) >= 0) { while (av_read_frame(aFormatCtx, &packet) >= 0) {
int frameFinished = 0; int frameFinished = 0;
//音频流 //is audio stream
if (packet.stream_index == audioStream) { if (packet.stream_index == audioStream) {
avcodec_decode_audio4(aCodecCtx, aFrame, &frameFinished, &packet); avcodec_decode_audio4(aCodecCtx, aFrame, &frameFinished, &packet);
//解码完一帧数据 //decode success
if (frameFinished) { if (frameFinished) {
// data_size为音频数据所占的字节数
int data_size = av_samples_get_buffer_size( int data_size = av_samples_get_buffer_size(
aFrame->linesize, aCodecCtx->channels, aFrame->linesize, aCodecCtx->channels,
aFrame->nb_samples, aCodecCtx->sample_fmt, 1); aFrame->nb_samples, aCodecCtx->sample_fmt, 1);
if (data_size > outputBufferSize) { if (data_size > outputBufferSize) {
outputBufferSize = (size_t) data_size; outputBufferSize = (size_t) data_size;
outputBuffer = (uint8_t *) realloc(outputBuffer, sizeof(uint8_t) * outputBufferSize); outputBuffer = (uint8_t *) realloc(outputBuffer,
sizeof(uint8_t) * outputBufferSize);
} }
// 音频格式转换
swr_convert(swr, &outputBuffer, aFrame->nb_samples, swr_convert(swr, &outputBuffer, aFrame->nb_samples,
(uint8_t const **) (aFrame->extended_data), (uint8_t const **) (aFrame->extended_data),
aFrame->nb_samples); aFrame->nb_samples);
// 返回pcm数据
*pcm = outputBuffer; *pcm = outputBuffer;
*pcmSize = (size_t) data_size; *pcmSize = (size_t) data_size;
return 0; return 0;
@ -259,7 +230,6 @@ int getPCM(void **pcm, size_t *pcmSize) {
return -1; return -1;
} }
// 释放相关资源
int releaseAudioPlayer() { int releaseAudioPlayer() {
av_packet_unref(&packet); av_packet_unref(&packet);
av_free(outputBuffer); av_free(outputBuffer);
@ -275,20 +245,12 @@ AUDIO_PLAYER_FUNC(void, playAudio, jstring filePath) {
const char *file_name = (*env)->GetStringUTFChars(env, filePath, NULL); const char *file_name = (*env)->GetStringUTFChars(env, filePath, NULL);
LOGI(TAG, "file_name=%s", file_name); LOGI(TAG, "file_name=%s", file_name);
// 创建音频解码器
createAudioPlayer(&rate, &channel, file_name); createAudioPlayer(&rate, &channel, file_name);
// 创建播放引擎
createEngine(); createEngine();
// 创建缓冲队列音频播放器
createBufferQueueAudioPlayer(rate, channel, SL_PCMSAMPLEFORMAT_FIXED_16); createBufferQueueAudioPlayer(rate, channel, SL_PCMSAMPLEFORMAT_FIXED_16);
// 启动音频播放
bqPlayerCallback(bqPlayerBufferQueue, NULL); bqPlayerCallback(bqPlayerBufferQueue, NULL);
} }
//停止播放,释放相关资源
AUDIO_PLAYER_FUNC(void, stop) { AUDIO_PLAYER_FUNC(void, stop) {
if (bqPlayerObject != NULL) { if (bqPlayerObject != NULL) {
(*bqPlayerObject)->Destroy(bqPlayerObject); (*bqPlayerObject)->Destroy(bqPlayerObject);
@ -311,6 +273,5 @@ AUDIO_PLAYER_FUNC(void, stop) {
engineEngine = NULL; engineEngine = NULL;
} }
// 释放解码器相关资源
releaseAudioPlayer(); releaseAudioPlayer();
} }

Loading…
Cancel
Save