如何在Android中通过FFmpeg的解除code音频 [英] How to decode audio via FFmpeg in Android

查看:134
本文介绍了如何在Android中通过FFmpeg的解除code音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个播放器为Android与FFmpeg的编译为Android NDK。

我可以打开通过FFmpeg的文件,写这样的:

  av_register_all();

字符*海峡=(* ENV) - > GetStringUTFChars(ENV,argv的,0);
__android_log_print(ANDROID_LOG_INFO,HelloNDK!,STR,STR);

如果(av_open_input_file(安培;!pFormatCtx,海峡,NULL,0,NULL)= 0)
    返回-2; //无法打开文件

//获得流信息
如果(av_find_stream_info(pFormatCtx)℃,)
    返回-3; //不能够找到流信息

//转储有关文件到标准的错误信息
dump_format(pFormatCtx,0,argv的,0);

//找到所述第一视频数据流
视频流=  -  1;
audioStream =  -  1;
对于(i = 0; I< pFormatCtx-> nb_streams;我++){
    如果(pFormatCtx->流[I]  - > codeC-> codec_type == codeC_TYPE_AUDIO和放大器;&安培; audioStream℃下){
        audioStream =我;
    }
}

如果(audioStream == -1)
    返回-5;

一个codecCtx = pFormatCtx->流[audioStream]  - > codeC;
从codeC信息//设置音频设置

一个codeC = AV codec_find_de codeR(A codecCtx-> codec_id);

如果(!一个codeC){
    fprintf中(错误,不支持codeC \ N!);
    返回-1;
}

AV codec_open(A codecCtx,一个codeC);
 

我怎么能现在去code中的音频,并返回到Java程序?也许有人可以给我一个例子

编辑: 当使用AV codec_de code_audio3 得到如下: 7月3号至22号:54:00.988:信息/ DEBUG(31): *的 * 的* *的 * 的* *的 * 的* * * * ** *的 * 的*的 * 的 7月3号至22号:54:00.988:信息/ DEBUG(31):构建指纹:通用/ SDK /通用/ 2.2 / FRF91 / 43546:ENG /测试键 7月3号至22号:54:00.988:信息/ DEBUG(31):PID:435 TID:435 >>> org.libsdl.app<<< 7月3号至22号:54:00.998:信息/ DEBUG(1931):11(SIGSEGV),故障地址00000000 7月3号至22号:54:00.998:信息/ DEBUG(1931年):R0,R1 00000000 00000000 R2 81893210 R3 00000000 7月3号至22号:54:01.008:信息/ DEBUG(1931年):R4 8189324c R5 818931d0 R6 00000000 R7 00000000 7月3号至22号:54:01.008:信息/ DEBUG(1931年):R8 00000200 R9 00000600 10 00000300 00000500 FP 7月3号至22号:54:01.019:信息/ DEBUG(1931年):IP 81350868 SP bef4c438 LR 8112cb3b PC 8112cb6c CPSR 80000030 7月3号至22号:54:01.369:信息/ DEBUG(31):#00件0012cb6c /数据/数据​​/ org.libsdl.app / lib中/ libtest.so 7月3号至22号:54:01.369:信息/ DEBUG(31):#01件0012db46 /数据/数据​​/ org.libsdl.app / lib中/ libtest.so 7月3号至22号:54:01.379:信息/ DEBUG(31):#02件0013052e /数据/数据​​/ org.libsdl.app / lib中/ libtest.so 7月3号至22号:54:01.379:信息/ DEBUG(31):#03件00132142 /数据/数据​​/ org.libsdl.app / lib中/ libtest.so 7月3号至22号:54:01.389:信息/ DEBUG(31):#04件001a2836 /数据/数据​​/ org.libsdl.app / lib中/ libtest.so 7月3号至22号:54:01.399:信息/ DEBUG(31):#05件00024ee6 ​​/数据/数据​​/ org.libsdl.app / lib中/ libtest.so 7月3号至22号:54:01.399:信息/ DEBUG(31):#06件00013974 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.409:信息/ DEBUG(31):#07件0003de3c /系统/ lib中/ libdvm.so 7月3号至22号:54:01.409:信息/ DEBUG(31):#08件00037216 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.419:信息/ DEBUG(31):#09件000432ec /系统/ lib中/ libdvm.so 7月3号至22号:54:01.419:信息/ DEBUG(31):#10件00018714 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.439:信息/ DEBUG(31):#11件0001e8c4 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.439:信息/ DEBUG(31):#12件0001d790 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.439:信息/ DEBUG(31):#13件0005408e /系统/ lib中/ libdvm.so 7月3号至22号:54:01.449:信息/ DEBUG(31):#14件0005bde2 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.449:信息/ DEBUG(31):#15件00018714 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.459:信息/ DEBUG(31):#16件0001e8c4 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.469:信息/ DEBUG(31):#17件0001d790 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.469:信息/ DEBUG(31):#18件00053eec /系统/ lib中/ libdvm.so 7月3号至22号:54:01.479:信息/ DEBUG(31):#19件0004072c /系统/ lib中/ libdvm.so 7月3号至22号:54:01.479:信息/ DEBUG(31):#20件00034454 /系统/ lib中/ libdvm.so 7月3号至22号:54:01.489:信息/ DEBUG(31):#21件0002c930 /系统/ lib中/ libandroid_runtime.so 7月3号至22号:54:01.489:信息/ DEBUG(31):#22件0002d85c /系统/ lib中/ libandroid_runtime.so 7月3号至22号:54:01.499:信息/ DEBUG(31):#23件00008c86 /系统/斌/ app_process 7月3号至22号:54:01.519:信息/ DEBUG(31):#24件0000d362 /系统/ lib中/ libc.so

我可以使用AV codec_de code_audio2? 我在最近几天已达成如下code:

  AVFormatContext * pFormatCtx;
INT I,视频流,audioStream;
AV codecContext * P codecCtx;
AV codeC * P codeC;
AVFrame * PFRAME;
AVPacket包;
INT frameFinished;
浮动aspect_ratio;

AV codecContext *一个codecCtx;
AV codeC *一个codeC;


AV codecContext * C = NULL;
INT out_size,LEN;
int16_t * audio_buf;
uint8_t有* outbuf中;
uint8_t有INBUF [AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]。



av_register_all();

字符*海峡=(* ENV) - > GetStringUTFChars(ENV,argv的,0);


如果(av_open_input_file(&pFormatCtx,海峡,NULL,0,NULL)!= 0)
返回-150;


如果(av_find_stream_info(pFormatCtx)nb_streams;我++){

如果(pFormatCtx->流[I]  - > codeC-> codec_type == codeC_TYPE_VIDEO &&视频流流[I]  - > codeC-> codec_type == codeC_TYPE_AUDIO && audioStream流[audioStream]  - > codeC;



一个codeC = AV codec_find_de codeR(A codecCtx-> codec_id);
如果(!一个codeC){
fprintf中(错误,不支持codeC \ N!);
返回-45;
}

AV codec_open(A codecCtx,一个codeC);
C = AV codec_alloc_context();
packet_queue_init(audioq);
而(av_read_frame(pFormatCtx,&分组)> = 0){


如果(packet.stream_index ==视频流){

}否则,如果(packet.stream_index == audioStream){

packet_queue_put(audioq,和包);
INT LEN1,DATA_SIZE;
DATA_SIZE = 417;

LEN1 = AV codec_de code_audio2(A codecCtx,(int16_t *)audio_buf,与DATA_SIZE,
packet.data,packet.size);
返回packet.size;
} 其他 {
av_free_packet(包);
}



}



返回0;
 

在这种情况下,当AV codec_de code_audio2我-1。我做错了什么?

请注意: 当我开车INT DATA_SIZE = 417;那么DEBUG不会出现,函数返回-1,但是当我开的是:INT DATA_SIZE = AV codeC_MAX_AUDIO_FRAME_SIZE * 2;然后vyskakievaet DEBUG在你的功能,所以在我自己的!这又如何解决呢?

EDIT2: 我的新code:

 
JNIEXPORT jint JNICALL Java_org_libsdl_app_SDLActivity_main(JNIEnv的* ENV,jobject OBJ,INT ARGC,ARGV的jstring,jbyteArray阵列){
      AVFormatContext * pFormatCtx;
      INT I,视频流,audioStream;
      AV codecContext * P codecCtx;
      AV codeC * P codeC;
      AVFrame * PFRAME;
      AVPacket包;
      INT frameFinished;
      浮动aspect_ratio;

      AV codecContext *一个codecCtx;
      AV codeC *一个codeC;

      SDL_Overlay * BMP;
      SDL_Surface *屏;
      SDL_Rect RECT;
      SDL_Event事件;
      SDL_AudioSpec wanted_spec,规范;
      AV codecContext * C = NULL;
         INT out_size,LEN;
         int16_t * audio_buf;
         uint8_t有* outbuf中;
         uint8_t有INBUF [AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]。
         字符* pAudioBuffer =(字符*)av_malloc(AV codeC_MAX_AUDIO_FRAME_SIZE * 2);




      av_register_all();

      字符*海峡=(* ENV) - > GetStringUTFChars(ENV,argv的,0);


      如果(av_open_input_file(&pFormatCtx,海峡,NULL,0,NULL)!= 0)
        返回-150; //无法打开文件


      如果(av_find_stream_info(pFormatCtx)nb_streams;我++){
        如果(pFormatCtx->流[I]  - > codeC  - > codec_type == codeC_TYPE_VIDEO &&
           视频流流[I]  - > codeC  - > codec_type == codeC_TYPE_AUDIO &&
           audioStream流[audioStream]  - > codeC;



      一个codeC = AV codec_find_de codeR(A codecCtx  - > codec_id);
      如果(!一个codeC){
        fprintf中(错误,不支持codeC \ N!);
        返回-45;
      }

      AV codec_open(A codecCtx,一个codeC);
      C = AV codec_alloc_context();
      packet_queue_init(audioq);
        而(av_read_frame(pFormatCtx,&分组)> = 0){
            如果(A codecCtx  - > codec_type == AVMEDIA_TYPE_AUDIO){
                        INT DATA_SIZE = AV codeC_MAX_AUDIO_FRAME_SIZE * 2;
                        INT大小= packet.size;
                        而(大小> 0){
                                INT LEN = AV codec_de code_audio3(A codecCtx,(int16_t *)pAudioBuffer,与DATA_SIZE,和包);

                                jbyte *字节=(* ENV) - > GetByteArrayElements(ENV,阵列,NULL);
                                的memcpy(字节,(int16_t *)pAudioBuffer,大小);
                                (* ENV) - > ReleaseByteArrayElements(包膜,阵列,字节,0);


                                大小= packet.size-LEN;
                                }
            }

     }










 返回5;
}
 

解决方案

使用audiotrack课上做的工作适合你。你可以做这样的事情。

JAVA端。

  AudioTrack轨道;

            INT BUFSIZE = AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_CONFIGURATION_MONO,
                            AudioFormat.ENCODING_PCM_16BIT);


            轨道=新AudioTrack(AudioManager.STREAM_MUSIC,44100,AudioFormat.CHANNEL_CONFIGURATION_MONO,
                        AudioFormat.ENCODING_PCM_16BIT,BUFSIZE,AudioTrack.MODE_STREAM);

            track.play();

            而(真){
            readBufferFromNative(); //更新从本地code缓冲区

                    ....................
                    ....................
                    }
 

在本机端:你需要阅读帧和第一个将其转换成原始的PCM格式,然后开始不断地填充音频缓冲。当缓冲区满时,它会自动播放。

  JNIEXPORT INT JNICALL Java_com_ffmpeg_Main_jniMainEntry(JNIEnv的* ENV,jobject OBJ,的jstring输入){

    为const char * pszFileName =(* ENV) - > GetStringUTFChars(ENV,输入,0);
    AVFormatContext * m_fc;
    INT ERR;
    AVPacket PKT;
    字符* pAudioBuffer =(字符*)av_malloc(AV codeC_MAX_AUDIO_FRAME_SIZE * 2);
    INT I;

    AV codec_register_all();
    avdevice_register_all();
    av_register_all();

    ERR = av_open_input_file(安培; m_fc,pszFileName,0,0,0);
    ERR = av_find_stream_info(m_fc);
    对于(i = 0; I< m_fc-> nb_streams;我++){
    如果((m_fc->流[I]  - > codeC-> codec_type == AVMEDIA_TYPE_VIDEO)||(m_fc->流[I]  - > codeC-> codec_type == AVMEDIA_TYPE_AUDIO)){
    AV codeC * codeC = AV codec_find_de codeR(m_fc->流[I]  - > codeC-> codec_id);

    如果(codeC == 0)
            继续;
    ERR = AV codec_open(m_fc->流[I]  - > codeC,codeC);
    如果(犯错℃,)
            继续;
    }
 }
    而(av_read_frame(m_fc,和放大器; PKT)> = 0){
            如果(m_fc->流[pkt.stream_index]  - > codeC-> codec_type == AVMEDIA_TYPE_AUDIO){
                    INT DATA_SIZE = AV codeC_MAX_AUDIO_FRAME_SIZE * 2;
                    INT大小= pkt->大小;
                    而(尺寸大于0){
                            INT LEN = AV codec_de code_audio3(m_fc->流[pkt.stream_index]  - > codeC,(int16_t *)pAudioBuffer,和放大器; DATA_SIZE,和放大器; PKT);
                            LOGD(DATA_SIZE%D LEN%D,DATA_SIZE,LEN);
                            大小= pkt->大小-LEN;
                            }
            }
 }
 

}

I am writing a player for Android with FFmpeg compiled for Android NDK.

I could open the file through FFmpeg and wrote this:

av_register_all();

char* str = (*env) -> GetStringUTFChars(env, argv, 0);
__android_log_print(ANDROID_LOG_INFO, "HelloNDK!", str, str);

if (av_open_input_file (&pFormatCtx, str, NULL, 0, NULL) != 0)
    return -2; // Couldn't open file

// Retrieve stream information
if (av_find_stream_info(pFormatCtx) < 0)
    return -3; // Couldn't find stream information

// Dump information about file onto standard error
dump_format(pFormatCtx, 0, argv, 0);

// Find the first video stream
videoStream =- 1;
audioStream =- 1;
for (i = 0; i < pFormatCtx->nb_streams; i++) {
    if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && audioStream <0) {
        audioStream = i;
    }
}

if (audioStream == -1)
    return -5;

aCodecCtx = pFormatCtx->streams[audioStream]->codec;
// Set audio settings from codec info

aCodec = avcodec_find_decoder(aCodecCtx->codec_id);

if (!aCodec) {
    fprintf (stderr, "Unsupported codec! \n");
    return -1;
}

avcodec_open (aCodecCtx, aCodec);

How can I now decode the audio and return it to the Java program? Maybe somebody could give me an example

EDIT: When using avcodec_decode_audio3 Get the following: 03-22 07:54:00.988: INFO / DEBUG (31): * ** * ** * ** * * * ** * ** * 03-22 07:54:00.988: INFO / DEBUG (31): Build fingerprint: 'generic / sdk / generic /: 2.2/FRF91/43546: eng / test-keys' 03-22 07:54:00.988: INFO / DEBUG (31): pid: 435, tid: 435>>> org.libsdl.app <<< 03-22 07:54:00.998: INFO / DEBUG (1931): signal 11 (SIGSEGV), fault addr 00000000 03-22 07:54:00.998: INFO / DEBUG (1931): r0 00000000 r1 00000000 r2 81893210 r3 00000000 03-22 07:54:01.008: INFO / DEBUG (1931): r4 8189324c r5 818931d0 r6 00000000 r7 00000000 03-22 07:54:01.008: INFO / DEBUG (1931): r8 00000200 r9 00000600 10 00000300 00000500 fp 03-22 07:54:01.019: INFO / DEBUG (1931): ip 81350868 sp bef4c438 lr 8112cb3b pc 8112cb6c cpsr 80000030 03-22 07:54:01.369: INFO / DEBUG (31): # 00 pc 0012cb6c / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.369: INFO / DEBUG (31): # 01 pc 0012db46 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.379: INFO / DEBUG (31): # 02 pc 0013052e / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.379: INFO / DEBUG (31): # 03 pc 00132142 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.389: INFO / DEBUG (31): # 04 pc 001a2836 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.399: INFO / DEBUG (31): # 05 pc 00024ee6 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.399: INFO / DEBUG (31): # 06 pc 00013974 / system / lib / libdvm.so 03-22 07:54:01.409: INFO / DEBUG (31): # 07 pc 0003de3c / system / lib / libdvm.so 03-22 07:54:01.409: INFO / DEBUG (31): # 08 pc 00037216 / system / lib / libdvm.so 03-22 07:54:01.419: INFO / DEBUG (31): # 09 pc 000432ec / system / lib / libdvm.so 03-22 07:54:01.419: INFO / DEBUG (31): # 10 pc 00018714 / system / lib / libdvm.so 03-22 07:54:01.439: INFO / DEBUG (31): # 11 pc 0001e8c4 / system / lib / libdvm.so 03-22 07:54:01.439: INFO / DEBUG (31): # 12 pc 0001d790 / system / lib / libdvm.so 03-22 07:54:01.439: INFO / DEBUG (31): # 13 pc 0005408e / system / lib / libdvm.so 03-22 07:54:01.449: INFO / DEBUG (31): # 14 pc 0005bde2 / system / lib / libdvm.so 03-22 07:54:01.449: INFO / DEBUG (31): # 15 pc 00018714 / system / lib / libdvm.so 03-22 07:54:01.459: INFO / DEBUG (31): # 16 pc 0001e8c4 / system / lib / libdvm.so 03-22 07:54:01.469: INFO / DEBUG (31): # 17 pc 0001d790 / system / lib / libdvm.so 03-22 07:54:01.469: INFO / DEBUG (31): # 18 pc 00053eec / system / lib / libdvm.so 03-22 07:54:01.479: INFO / DEBUG (31): # 19 pc 0004072c / system / lib / libdvm.so 03-22 07:54:01.479: INFO / DEBUG (31): # 20 pc 00034454 / system / lib / libdvm.so 03-22 07:54:01.489: INFO / DEBUG (31): # 21 pc 0002c930 / system / lib / libandroid_runtime.so 03-22 07:54:01.489: INFO / DEBUG (31): # 22 pc 0002d85c / system / lib / libandroid_runtime.so 03-22 07:54:01.499: INFO / DEBUG (31): # 23 pc 00008c86 / system / bin / app_process 03-22 07:54:01.519: INFO / DEBUG (31): # 24 pc 0000d362 / system / lib / libc.so

Can I use avcodec_decode_audio2? I have in recent days has reached the following code:

AVFormatContext * pFormatCtx; 
int i, videoStream, audioStream; 
AVCodecContext * pCodecCtx; 
AVCodec * pCodec; 
AVFrame * pFrame; 
AVPacket packet; 
int frameFinished; 
float aspect_ratio; 

AVCodecContext * aCodecCtx; 
AVCodec * aCodec; 


AVCodecContext * c = NULL; 
int out_size, len; 
int16_t * audio_buf; 
uint8_t * outbuf; 
uint8_t inbuf [AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 



av_register_all (); 

char * str = (* env) -> GetStringUTFChars (env, argv, 0); 


if (av_open_input_file (& pFormatCtx, str, NULL, 0, NULL)! = 0) 
return -150; 


if (av_find_stream_info (pFormatCtx)  nb_streams; i + +) { 

if (pFormatCtx-> streams [i] -> codec-> codec_type == CODEC_TYPE_VIDEO & & videoStream  streams [i] -> codec-> codec_type == CODEC_TYPE_AUDIO & & audioStream  streams [audioStream] -> codec; 



aCodec = avcodec_find_decoder (aCodecCtx-> codec_id); 
if (! aCodec) { 
fprintf (stderr, "Unsupported codec! \ n"); 
return -45; 
} 

avcodec_open (aCodecCtx, aCodec); 
c = avcodec_alloc_context (); 
packet_queue_init (& audioq); 
while (av_read_frame (pFormatCtx, & packet)> = 0) { 


if (packet.stream_index == videoStream) { 

} Else if (packet.stream_index == audioStream) { 

packet_queue_put (& audioq, & packet); 
int len1, data_size; 
data_size = 417; 

len1 = avcodec_decode_audio2 (aCodecCtx, (int16_t *) audio_buf, & data_size, 
packet.data, packet.size); 
return packet.size; 
} Else { 
av_free_packet (& packet); 
} 



} 



return 0; 

In this case, when the avcodec_decode_audio2 I got -1. What I did wrong?

Note: When I drove int data_size = 417; then DEBUG does not appear and the function returns -1, but when I drive a: int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2; then vyskakievaet DEBUG in your function so in my own! How can this be solved?

EDIT2: My new code:


JNIEXPORT jint JNICALL Java_org_libsdl_app_SDLActivity_main( JNIEnv* env, jobject obj, int argc, jstring argv, jbyteArray array) {
      AVFormatContext *pFormatCtx;
      int             i, videoStream, audioStream;
      AVCodecContext  *pCodecCtx;
      AVCodec         *pCodec;
      AVFrame         *pFrame;
      AVPacket        packet;
      int             frameFinished;
      float           aspect_ratio;

      AVCodecContext  *aCodecCtx;
      AVCodec         *aCodec;

      SDL_Overlay     *bmp;
      SDL_Surface     *screen;
      SDL_Rect        rect;
      SDL_Event       event;
      SDL_AudioSpec   wanted_spec, spec;
      AVCodecContext *c= NULL;
         int out_size, len;
         int16_t *audio_buf;
         uint8_t *outbuf;
         uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
         char *pAudioBuffer = (char *) av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);




      av_register_all();

      char *str = (*env)->GetStringUTFChars(env, argv, 0);


      if(av_open_input_file(&pFormatCtx, str, NULL, 0, NULL)!=0)
        return -150; // Couldn't open file


      if(av_find_stream_info(pFormatCtx)nb_streams; i++) {
        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO &&
           videoStream streams[i]->codec->codec_type==CODEC_TYPE_AUDIO &&
           audioStream streams[audioStream]->codec;



      aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
      if(!aCodec) {
        fprintf(stderr, "Unsupported codec!\n");
        return -45;
      }

      avcodec_open(aCodecCtx, aCodec);
      c=avcodec_alloc_context();
      packet_queue_init(&audioq);
        while (av_read_frame(pFormatCtx, &packet)>= 0) {
            if (aCodecCtx->codec_type == AVMEDIA_TYPE_AUDIO) {
                        int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
                        int size=packet.size;
                        while(size > 0) {
                                int len = avcodec_decode_audio3(aCodecCtx, (int16_t *) pAudioBuffer, &data_size, &packet);

                                jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
                                memcpy(bytes, (int16_t *) pAudioBuffer, size);
                                (*env)->ReleaseByteArrayElements(env, array, bytes, 0);


                                size = packet.size-len;
                                }
            }

     }










 return 5;
}

解决方案

Use audiotrack class to do the work for you. You can do something like this.

JAVA side.

            AudioTrack track;

            int bufSize = AudioTrack.getMinBufferSize(44100,                                AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                            AudioFormat.ENCODING_PCM_16BIT);


            track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                        AudioFormat.ENCODING_PCM_16BIT, bufSize, AudioTrack.MODE_STREAM);

            track.play(); 

            while(true){
            readBufferFromNative(); //update buffer from native code

                    ....................
                    ....................
                    }

On native Side : You need to read the frames and convert them into raw pcm format first and then start filling the audio buffer continuously. When the buffer is full, it will automatically play.

JNIEXPORT int JNICALL Java_com_ffmpeg_Main_jniMainEntry(JNIEnv* env, jobject obj, jstring input) {

    const char * pszFileName = (*env)->GetStringUTFChars(env, input, 0);
    AVFormatContext * m_fc;
    int err;
    AVPacket pkt;
    char * pAudioBuffer = (char *) av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);
    int i;

    avcodec_register_all ();
    avdevice_register_all ();
    av_register_all ();

    err = av_open_input_file(&m_fc, pszFileName, 0, 0, 0);
    err = av_find_stream_info(m_fc);
    for(i = 0; i<m_fc->nb_streams; i++) {
    if((m_fc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) || (m_fc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)) {
    AVCodec *codec = avcodec_find_decoder(m_fc->streams[i]->codec->codec_id);

    if (codec == 0)
            continue;
    err = avcodec_open(m_fc->streams[i]->codec, codec);
    if (err <0)
            continue;
    }
 }
    while (av_read_frame(m_fc, &pkt)>= 0) {
            if (m_fc-> streams[pkt.stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
                    int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
                    int size=pkt->size;
                    while(size > 0) {
                            int len = avcodec_decode_audio3(m_fc->streams[pkt.stream_index]->codec, (int16_t *) pAudioBuffer, &data_size, &pkt);
                            LOGD("data_size %d len %d", data_size, len);
                            size = pkt->size-len;
                            }
            }
 }

}

这篇关于如何在Android中通过FFmpeg的解除code音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆