开发者

Wav File encoded with FFMPEG has issues with codecs while playing using VLC Player

I want to convert raw PCM data(Taken from Android Phone mic) into a libGSM Wave file. After encoding into file, VLC player shows right codec information and duration but unable to play contents. Please help me to find what I am doing wrong.

Below is my code for encoding and header writing:

void EncodeTest(uint8_t *audioData, size_t audioSize)
{
    AVCodecContext  *audioCodec;
    AVCodec *codec;
    uint8_t *buf;    int bufSize, frameBytes;
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Lets encode :%u with size %d\n",(int)audioData, (int)audioSize);
    //Set up audio encoder
    codec = avcodec_find_encoder(CODEC_ID_GSM);
    if (codec == NULL){
        __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to find encoder(CODEC_ID_GSM)");
        codec = avcodec_find_encoder(CODEC_ID_GSM);
        if (codec == NULL){
            __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to find encoder(CODEC_ID_GSM)");
            return;
        }
    }
    audioCodec                  = avcodec_alloc_context();
    audioCodec->channels        = 1;
    audioCodec->sample_rate     = 8000;
    audioCodec->sample_fmt      = SAMPLE_FMT_S16;
    audioCodec->bit_rate        = 13200;
    audioCodec->priv_data       = gsm_create();

    switch(audioCodec->codec_id) {
        case CODEC_ID_GSM:
            audioCodec->frame_size = GSM_FRAME_SIZE;
            audioCodec->block_align = GSM_BLOCK_SIZE;
            int one = 1;
            gsm_option(audioCodec->priv_data, GSM_OPT_WAV49, &one);
            break;
        case CODEC_ID_GSM_MS: {
            int one = 1;
            gsm_option(audioCodec->priv_data, GSM_OPT_WAV49, &one);
            audioCodec->frame_size = 2*GSM_FRAME_SIZE;
            audioCodec->block_align = GSM_MS_BLOCK_SIZE;
        }
    }
    audioCodec->coded_frame= avcodec_alloc_frame();
    audioCodec->coded_frame->key_frame= 1;
    audioCodec->time_base       = (AVRational){1,  audioCodec->sample_rate};
    audioCodec->codec_type      = CODEC_TYPE_AUDIO;

    if (avcodec_open(audioCodec, codec) < 0){
        __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to avcodec_open");
        return;
    }

    bufSize     = FF_MIN_BUFFER_SIZE * 10;
    buf         = (uint8_t *)malloc(bufSize);
    if (buf == NULL) return;
    frameBytes = audioCodec->frame_size * audioCodec->channels * 2;
    FILE *fileWrite = fopen(FILE_NAME,"w+b");
    if(NULL == fileWrite){
        __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to open file for reading.");
    }
    /*Write wave header*/
    WriteWav(fileWrite, 32505);/*Just for test*/

    /*Lets encode raw packet and write into file after header.*/
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Lets Encode Actual Bytes");
 开发者_C百科   int nChunckSize = 0;
    while (audioSize >= frameBytes)
    {
        int packetSize;

        packetSize = avcodec_encode_audio(audioCodec, buf, bufSize, (short *)audioData);
        __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Encoder returned %d bytes of data\n", packetSize);
        nChunckSize += packetSize;
        audioData += frameBytes;
        audioSize -= frameBytes;
        if(NULL != fileWrite){
            fwrite(buf, packetSize, 1, fileWrite);
        }
        else{
            __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"Unable to open file for writting... NULL");
        }
    }
    if(NULL != fileWrite){
        fclose(fileWrite);
    }
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"----- Done with nChunckSize: %d --- ",nChunckSize);
     __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"*****************************");
    wavReadnDisplayHeader(FILE_NAME);
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"*****************************");
    wavReadnDisplayHeader("/sdcard/Voicemail2.wav");
}

Header Writing:

/** Writes WAV headers */
void WriteWav(FILE *f, long int bytes)
{
    /* quick and dirty */
    fwrite("RIFF",sizeof(char),4,f);                /*  0-3 */      //RIFF
    PutNum(bytes+44-8,f,1,4);                       /*  4-7 */      //ChunkSize
    fwrite("WAVEfmt ",sizeof(char),8,f);            /*  8-15 */     //WAVE Header + FMT header
    PutNum(16,f,1,4);                               /* 16-19 */     //Size of the fmt chunk
    PutNum(49,f,1,2);                                /* 20-21 */     //Audio format, 49=libgsm wave, 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
    PutNum(1,f,1,2);                                /* 22-23 */     //Number of channels 1=Mono 2=Sterio
    PutNum(8000,f,1,4);                             /* 24-27 */     //Sampling Frequency in Hz 
    PutNum(2*8000,f,1,4);                           /* 28-31 */     //bytes per second /Sample/persec
    PutNum(2,f,1,2);                                /* 32-33 */     // 2=16-bit mono, 4=16-bit stereo 
    PutNum(16,f,1,2);                                /* 34-35 */     // Number of bits per sample
    fwrite("data",sizeof(char),4,f);                /* 36-39 */     
    PutNum(bytes,f,1,4);                            /* 40-43 */     //Sampled data length  
}

Please help....


I came across this post two weeks ago when I started down the path of how to handle encoding old proprietary WAV formats which used to be thing 15 years ago with Palm OS, HP and some USA prison phone systems.

You cannot decode these using FFMPEG. If you have a WAV file that required a custom ACM codec installed and only runs in Windows Media Player you have to write a custom application that will load the codec and encode it for you. I recommend C++ or C# in Visual Studio and Visual Basic's library translation doesn't handle it very well.

Be prepaired to translate code from other languages from blogs 10 years old....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜