Android Audio Video Depth 14 ffmpeg with OpenSL ES play mp3 music, can pause (attached source

Source: Internet
Author: User

Project Address
Https://github.com/979451341/FFmpegOpenslES

This is the FFmpeg decoding MP3, the data to OpenSL es playback, and to be able to pause.
1. Creating an engine

slCreateEngine(&engineObject,0,NULL,0,NULL,NULL);//创建引擎(*engineObject)->Realize(engineObject,SL_BOOLEAN_FALSE);//实现engineObject接口对象(*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineEngine);//通过引擎调用接口初始化SLEngineItf

2. Create a mixer

(*engineEngine)->CreateOutputMix(engineEngine,&outputMixObject,0,0,0);//用引擎对象创建混音器接口对象(*outputMixObject)->Realize(outputMixObject,SL_BOOLEAN_FALSE);//实现混音器接口对象SLresult   sLresult = (*outputMixObject)->GetInterface(outputMixObject,SL_IID_ENVIRONMENTALREVERB,&outputMixEnvironmentalReverb);//利用混音器实例对象接口初始化具体的混音器对象//设置if (SL_RESULT_SUCCESS == sLresult) {    (*outputMixEnvironmentalReverb)->            SetEnvironmentalReverbProperties(outputMixEnvironmentalReverb, &settings);}

3.FFmpeg Decoding MP3 prep work

av_register_all();char *input = "/storage/emulated/0/pauseRecordDemo/video/a.mp3";pFormatCtx = avformat_alloc_context();LOGE("Lujng %s",input);LOGE("xxx %p",pFormatCtx);int error;char buf[] = "";//打开视频地址并获取里面的内容(解封装)if (error = avformat_open_input(&pFormatCtx, input, NULL, NULL) < 0) {    av_strerror(error, buf, 1024);    // LOGE("%s" ,inputPath)    LOGE("Couldn‘t open file %s: %d(%s)", input, error, buf);    // LOGE("%d",error)    LOGE("打开视频失败")}//3.获取视频信息if(avformat_find_stream_info(pFormatCtx,NULL) < 0){    LOGE("%s","获取视频信息失败");    return -1;}int i=0;for (int i = 0; i < pFormatCtx->nb_streams; ++i) {    if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {        LOGE("  找到音频id %d", pFormatCtx->streams[i]->codec->codec_type);        audio_stream_idx=i;        break;    }}

MP3 's Decoder

Get Audio Codec
pcodecctx=pformatctx->streams[audio_stream_idx]->codec;
LOGE ("Get Video Encoder context%p", pcodecctx);

pCodex = avcodec_find_decoder(pCodecCtx->codec_id);LOGE("获取视频编码 %p",pCodex);if (avcodec_open2(pCodecCtx, pCodex, NULL)<0) {}packet = (AVPacket *)av_malloc(sizeof(AVPacket));

Av_init_packet (packet);
Audio data

frame = av_frame_alloc();

The encoded format contained in the MP3 is converted into PCM Swccontext
Swrcontext = Swr_alloc ();

int length=0;int got_frame;

441002
Out_buffer = (uint8_t
) av_malloc (44100 * 2);
uint64_t Out_ch_layout=av_ch_layout_stereo;
Output Sample bits 16 bits
Enum Avsampleformat OUT_FORMART=AV_SAMPLE_FMT_S16;
The sample rate of the output must be the same as the input
int out_sample_rate = pcodecctx->sample_rate;

swr_alloc_set_opts(swrContext, out_ch_layout, out_formart, out_sample_rate,                   pCodecCtx->channel_layout, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0,                   NULL);swr_init(swrContext);

Get the number of channels 2
OUT_CHANNER_NB = Av_get_channel_layout_nb_channels (Av_ch_layout_stereo);
Rate = pcodecctx->sample_rate;
Channel = pcodecctx->channels;

4. Cache Queue Settings

int rate;int channels;createFFmpeg(&rate,&channels);LOGE("RATE %d",rate);LOGE("channels %d",channels);/* * typedef struct SLDataLocator_AndroidBufferQueue_ {SLuint32    locatorType;//缓冲区队列类型SLuint32    numBuffers;//buffer位数

} */

Sldatalocator_androidbufferqueue android_queue = {sl_datalocator_androidsimplebufferqueue,2};/**typedef struct  sldataformat_pcm_ {SLuint32 formattype;  PCM SLuint32 Numchannels;  Number of channels SLuint32 samplespersec;  Sampling rate SLuint32 bitspersample;  Number of sample bits SLuint32 containersize;     Contains the number of bits SLuint32 channelmask;    Stereo SLuint32 endianness; End flag bit} SLDATAFORMAT_PCM; */SLDATAFORMAT_PCM PCM = {sl_dataformat_pcm,channels,rate*1000, sl_pcmsampleformat_fixed_16, SL_PCMSAMPLEFOR MAT_FIXED_16, sl_speaker_front_left|sl_speaker_front_right,sl_byteorder_littleendian};/* * typedef struct SLDATASOU rce_ {void *plocator;//buffer queue void *pformat;//data style, configuration information} Sldatasource; * */sldatasource DataSource = {&android_queue,&pcm}; Sldatalocator_outputmix Sldatalocator_outputmix={sl_datalocator_outputmix,outputmixobject}; Sldatasink Sldatasink = {&sldatalocator_outputmix,null};const Slinterfaceid ids[3]={Sl_iid_bufferqueue,sl_iid_effectsend,sl_iid_volume};const Slboolean req[3]={sl_boolean_false,sl_boolean_false, sl_boolean_false};/* * Slresult (*createaudioplayer) (SLENGINEITF self, SLOBJECTITF * Pplayer, SLDataSource *pAu  diosrc,//Data Settings Sldatasink *paudiosnk,//associated mixer SLuint32 numinterfaces, const SLINTERFACEID * pinterfaceids, const Slboolean * pinterfacerequired); * */loge ("Execute Here") (*engineengine)->createaudioplayer (engineengine,&audioplayer,&datasource,& Sldatasink,3,ids,req)->realize (audioplayer,sl_boolean_false);(*audioplayer); LOGE ("Execute here 2") (*audioplayer)->getinterface (AUDIOPLAYER,SL_IID_PLAY,&AMP;SLPLAYITF);//Initialize player//register buffer, through buffer inside Data for playback (*audioplayer)->getinterface (AUDIOPLAYER,SL_IID_BUFFERQUEUE,&AMP;SLBUFFERQUEUEITF);//Set Callback interface (* SLBUFFERQUEUEITF)->registercallback (slbufferqueueitf,getqueuecallback,null);

Finally, give the cache callback function parameters, this callback function is mainly responsible for providing ffmpeg decoded data

//开始播放getQueueCallBack(slBufferQueueItf,NULL);

Let's take a look at what this function says, by enqueue the data into the queue, which is obtained from the GETPCM function.

void Getqueuecallback (SLANDROIDSIMPLEBUFFERQUEUEITF slbufferqueueitf, void context) {
buffersize=0;
GETPCM (&buffer,&buffersize);
if (buffer!=null&&buffersize!=0) {
Adding the resulting data to the queue
(
SLBUFFERQUEUEITF)->enqueue (slbufferqueueitf,buffer,buffersize);
}
}

This ffmpeg decoding mp3 to get the PCM data, this is the main decoding a packet data, jump out of the loop, the data to the upper function into the queue, when the queue of data read, The Getqueuecallback function is called again to get the PCM data decoded by the FFmpeg.

int getpcm (void *pcm,size_t pcm_size) {
int framecount=0;
int got_frame;
while (Av_read_frame (pformatctx, packet) >= 0) {
if (Packet->stream_index = = Audio_stream_idx) {
Decode MP3 encoded format frame----PCM frame
Avcodec_decode_audio4 (Pcodecctx, frame, &got_frame, packet);
if (got_frame) {
LOGE ("decoding");
/**

    • int Swr_convert (struct swrcontext s, uint8_t out , int out_count,
      Const uint8_t
      in, int in_count);
      /
      Swr_convert (Swrcontext, &out_buffer, 44100 * 2, (const uint8_t *) Frame->data, frame->nb_samples);
      Size of the buffer
      int size = Av_samples_get_buffer_size (NULL, OUT_CHANNER_NB, Frame->nb_samples,
      AV_SAMPLE_FMT_S16, 1);
      PCM = Out_buffer;
      *pcm_size = size;
      Break
      }
      }
      }
      return 0;
      }

5. Play Music

(*slPlayItf)->SetPlayState(slPlayItf,SL_PLAYSTATE_PLAYING);

6. Pause Music

(*slPlayItf)->SetPlayState(slPlayItf, SL_PLAYSTATE_PAUSED);

7. Releasing Resources

First release the entity about OpenSL ES

if(audioplayer!=NULL){    (*audioplayer)->Destroy(audioplayer);    audioplayer=NULL;    slBufferQueueItf=NULL;    slPlayItf=NULL;}if(outputMixObject!=NULL){    (*outputMixObject)->Destroy(outputMixObject);    outputMixObject=NULL;    outputMixEnvironmentalReverb=NULL;}if(engineObject!=NULL){    (*engineObject)->Destroy(engineObject);    engineObject=NULL;    engineEngine=NULL;}

Then release the resources that FFmpeg occupies

av_free_packet(packet);av_free(out_buffer);av_frame_free(&frame);swr_free(&swrContext);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);

Android Audio Video Depth 14 ffmpeg with OpenSL ES play mp3 music, can pause (attached source

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.