【问题标题】:FFMPEG- Duration of audio file is inaccurateFFMPEG-音频文件的持续时间不准确
【发布时间】:2015-09-16 02:33:01
【问题描述】:

我有视频文件 (mp4)。我想从该文件中分离音频流(AAC 格式)并保存在 PC 中。 使用下面的代码,生成的 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;
    }
}

【问题讨论】:

    标签: audio video ffmpeg


    【解决方案1】:

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

    【讨论】:

    • 嗨 Szatmary,int rate_idx = st->codec->sample_rate。从编解码器上下文获取的采样率是正确的,不是吗?除了解析extradata之外,还有其他方法可以获取真实对象类型和采样率索引吗?我这里还有其他问题。请帮我解决一下这个。 stackoverflow.com/questions/32622314/…
    • 我可以在播放器的搜索栏上搜索音频。但是,持续时间错误,生成的 aac 文件无法在 VLC 播放器上播放。请帮帮我!
    • st->codec->sample_rate 是采样率,需要采样率索引。 wiki.multimedia.cx/…
    • 应用正确的对象索引和采样率索引后,仍然会出现此问题。我的 ADTS 标头似乎仍然存在错误。
    猜你喜欢
    • 2023-03-09
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多