Decoding audio via Android using FFMpeg

后端 未结 2 1472
傲寒
傲寒 2021-02-01 11:36

I can play Wav files using the below code without issues. When trying to play the exact same media in Mp3 format I only get garbled junk. I believe I am fundamentally misunder

相关标签:
2条回答
  • 2021-02-01 11:51

    Ah, you might need to check the data_size value after the call to avcodec_decode_audio3: right now you always feed the return value to the play method, but if data_size is less than 0 then it is not a valid frame decode.

    0 讨论(0)
  • 2021-02-01 11:52

    I was able to solve my problem by taking the audio_decode_example code found in the api_example.c file in libavcodec of the ffmpeg source and modify it to suit my needs. Below is the code. Just to note, it doesn't dynamically pick the correct codec to decode with, that is something I'll have to fix next along with a few other items. The java code remains untouched.

    void Java_com_rohaupt_RRD2_player_Example(JNIEnv* env, jobject obj,jstring file,jbyteArray array)
        {
            jboolean            isfilenameCopy;
            const char *        filename = (*env)->GetStringUTFChars(env, file, &isfilenameCopy);
            AVCodec *codec;
            AVCodecContext *c= NULL;
            int out_size, len;
            FILE *f, *outfile;
            uint8_t *outbuf;
            uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
            AVPacket avpkt;
            jclass              cls = (*env)->GetObjectClass(env, obj);
            jmethodID           play = (*env)->GetMethodID(env, cls, "playSound", "([BI)V");//At the begining of your main function
    
            av_init_packet(&avpkt);
    
            printf("Audio decoding\n");
    
            /* find the mpeg audio decoder */
            codec = avcodec_find_decoder(CODEC_ID_MP3);
            if (!codec) {
                fprintf(stderr, "codec not found\n");
                exit(1);
            }
    
            c= avcodec_alloc_context();
    
            /* open it */
            if (avcodec_open(c, codec) < 0) {
                fprintf(stderr, "could not open codec\n");
                exit(1);
            }
    
            outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
    
            f = fopen(filename, "rb");
            if (!f) {
                fprintf(stderr, "could not open %s\n", filename);
                exit(1);
            }
    
            /* decode until eof */
            avpkt.data = inbuf;
            avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
    
            while (avpkt.size > 0) {
                out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
                len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
                if (len < 0) {
                    fprintf(stderr, "Error while decoding\n");
                    exit(1);
                }
                if (out_size > 0) {
                    /* if a frame has been decoded, output it */
                    jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
                    memcpy(bytes, outbuf, out_size); //
                    (*env)->ReleaseByteArrayElements(env, array, bytes, 0);
                    (*env)->CallVoidMethod(env, obj, play, array, out_size);
    
                }
                avpkt.size -= len;
                avpkt.data += len;
                if (avpkt.size < AUDIO_REFILL_THRESH) {
                    /* Refill the input buffer, to avoid trying to decode
                     * incomplete frames. Instead of this, one could also use
                     * a parser, or use a proper container format through
                     * libavformat. */
                    memmove(inbuf, avpkt.data, avpkt.size);
                    avpkt.data = inbuf;
                    len = fread(avpkt.data + avpkt.size, 1,
                                AUDIO_INBUF_SIZE - avpkt.size, f);
                    if (len > 0)
                        avpkt.size += len;
                }
            }
    
            fclose(f);
            free(outbuf);
    
            avcodec_close(c);
            av_free(c);
        }
    
    0 讨论(0)
提交回复
热议问题