8

如何以编程方式从 mp4 视频文件格式转换(提取音频通道)?
我只是在网上找不到任何使用 C++ 的东西。

将命令行参数传递给 LAME 或 MPLAYER 或 FFMPEG 不是一种选择。

4

2 回答 2

11

您可以尝试使用 ffmpeg 在 C 或 C++ 中执行此操作。这是正常的步骤流程。

  1. 使用 av_register_all() 初始化 ffmpeg;

  2. 使用 avformat_open_input( &informat, sourcefile, 0, 0)) 打开输入文件。

  3. 使用 avformat_find_stream_info(informat, 0)) 查找流信息。

  4. 通过遍历流并将 codec_type 与 AVMEDIA_TYPE_AUDIO 进行比较来查找音频流。

  5. 输入音频流后,您可以找到音频解码器并打开解码器。使用 avcodec_find_decoder(in_aud_strm->codec->codec_id) 和 avcodec_open2(in_aud_codec_ctx, in_aud_codec, NULL)。

  6. 现在对于输出文件,使用 av_guess_format(NULL, (const char*)outfile, NULL) 猜测输出格式。

  7. 为输出格式分配上下文。

  8. 使用 avcodec_find_encoder(outfmt->audio_codec) 查找输出音频编码器。

  9. 添加新的流音频流 avformat_new_stream(outformat, out_aud_codec)。

  10. 用所需的采样率、采样 fmt、通道等填充输出编解码器上下文。

  11. 使用 avio_open() 打开输出文件。

  12. 使用 avformat_write_header(outformat, NULL) 写入输出标头。

  13. 现在在 while 循环中开始读取数据包,仅解码音频数据包对它们进行编码并将它们写入打开的输出文件中。您可以使用 av_read_frame(informat, &pkt) , avcodec_decode_audio4(in_aud_codec_ctx, pframeT, &got_vid_pkt, &pkt), avcodec_encode_audio2() 和 av_write_frame()。

  14. 最后使用 av_write_trailer 编写预告片。

您可以查看 ffmpeg 示例中提供的 demuxing.c 和 muxing.c。

于 2013-04-22T12:36:15.593 回答
2

transcode_aac官方示例开始。我们需要非常少的改变:

  1. 在文件范围内添加一个全局变量:

    /* The index of audio stream that will be transcoded */
    static int audio_stream_idx = -1;
    
  2. 在 中,将第83-88open_input_file()行替换为

    for (audio_stream_idx = 0; audio_stream_idx < (*input_format_context)->nb_streams; audio_stream_idx++) {
    if ((*input_format_context)->streams[audio_stream_idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
        break;
    }
    
    if (audio_stream_idx >= (*input_format_context)->nb_streams) {
        fprintf(stderr, "Could not find an audio stream\n");
        avformat_close_input(input_format_context);
        return AVERROR_EXIT;
    }
    
  3. 在第92107行,替换streams[0]streams[audio_stream_idx].

  4. 在第181行,将硬编码的编解码器 ID 替换AV_CODEC_ID_AAC

    (*output_format_context)->oformat->audio_codec
    
  5. 在第182行,替换错误消息:

    fprintf(stderr, "Could not find audio encoder for %s(%d).\n", (*output_format_context)->oformat->long_name, (*output_format_context)->oformat->audio_codec);
    
  6. decode_audio_frame()我们跳过非音频帧:在第389行,写

    if (error != AVERROR_EOF && input_packet.stream_index != audio_stream_idx) goto cleanup;
    

PS请注意,当音频流不需要转码时,此解决方案无法以最佳方式处理。大多数mp4文件都有 AAC 或 AC3 音轨,因此请确保使用相关的解码器和 MP3 编码器(例如,shine)构建您的 ffmpeg。

这里的PPS是文件,适应 Adnroid。

于 2020-06-07T22:10:06.913 回答