FFMPEG-音频文件的持续时间不准确

时间:2015-09-16 02:33:01

标签: audio video ffmpeg

我有视频文件(mp4)。我想从该文件中分离音频流(AAC格式)并保存在PC中。 使用以下代码,Generated aac文件现在可以在KM播放器上播放,但无法在VLC播放器上播放。播放器上持续时间显示的信息是错误的。 请帮我解决这个问题。

 err = avformat_open_input(input_format_context, filename, NULL, NULL);
if (err < 0) {
    return err;
}

/* If not enough info to get the stream parameters, we decode the
   first frames to get it. (used in mpeg case for example) */
ret = avformat_find_stream_info(*input_format_context, 0);
if (ret < 0) {
    av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
    return ret;
}

/* dump the file content */
av_dump_format(*input_format_context, 0, filename, 0);

for (size_t i = 0; i < (*input_format_context)->nb_streams; i++) {
    AVStream *st = (*input_format_context)->streams[i];
    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
        *input_codec_context = st->codec;
        *input_audio_stream = st;

        FILE *file = NULL;
        file = fopen("C:\\Users\\MyPC\\Downloads\\Test.aac", "wb");
        AVPacket reading_packet;
        av_init_packet(&reading_packet);
        while (av_read_frame(*input_format_context, &reading_packet) == 0) {
            if (reading_packet.stream_index == (int) i) {

                uint8_t adts_header[7];
                unsigned int obj_type = 0;
                unsigned int num_data_block = (reading_packet.size)/1024;
                int rate_idx = st->codec->sample_rate, channels = st->codec->channels;

                 uint16_t frame_length;

                // include the header length also
                 frame_length = reading_packet.size + 7;

                /* We want the same metadata */
                /* Generate ADTS header */
                if(adts_header == NULL) return -1;
                /* Sync point over a full byte */
                adts_header[0] = 0xFF;
                /* Sync point continued over first 4 bits + static 4 bits
                * (ID, layer, protection)*/
                adts_header[1] = 0xF1;
                /* Object type over first 2 bits */
                adts_header[2] = obj_type << 6;
                /* rate index over next 4 bits */
                adts_header[2] |= (rate_idx << 2);
                /* channels over last 2 bits */
                adts_header[2] |= (channels & 0x4) >> 2;
                /* channels continued over next 2 bits + 4 bits at zero */
                adts_header[3] = (channels & 0x3) << 6;
                /* frame size over last 2 bits */
                adts_header[3] |= (frame_length & 0x1800) >> 11;
                /* frame size continued over full byte */
                adts_header[4] = (frame_length & 0x1FF8) >> 3;
                /* frame size continued first 3 bits */
                adts_header[5] = (frame_length & 0x7) << 5;
                /* buffer fullness (0x7FF for VBR) over 5 last bits*/
                adts_header[5] |= 0x1F;
                /* buffer fullness (0x7FF for VBR) continued over 6 first bits + 2 zeros
                * number of raw data blocks */
                adts_header[6] = 0xFA;
                adts_header[6] |= num_data_block & 0x03; // Set raw Data blocks.

                fwrite(adts_header, 1, 7, file);
                fwrite(reading_packet.data, 1, reading_packet.size, file);
            }
            av_free_packet(&reading_packet);   
        }
        fclose(file);

        return 0;
    }
}

1 个答案:

答案 0 :(得分:0)

对象类型和采样率索引必须设置为真实,正确的值。这两个值都可以从编解码器上下文中的extradata字段中的音频特定配置中解析出来。您需要的所有信息都在这里:http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio