FFMpeg复制流没有转码

我试图将所有来自多个文件的流复制到一个文件而不转码流。 你通常使用ffmpeg实用程序做的事情ffmpeg -i “file_with_audio.mp4” -i “file_with_video.mp4” -c copy -shortest file_with_audio_and_video.mp4

这是代码:

 int ffmpegOpenInputFile(const char* filename, AVFormatContext **ic) { int ret; unsigned int i; *ic = avformat_alloc_context(); if (!(*ic)) return -1; // Couldn't allocate input context if((ret = avformat_open_input(ic, filename, NULL, NULL)) < 0) return ret; // Couldn't open file // Get format info (retrieve stream information) if ((ret = avformat_find_stream_info(*ic, NULL)) < 0) return ret; // Couldn't find stream information for (int i = 0; i nb_streams; i++) { AVStream *stream; AVCodecContext *codec_ctx; stream = (*ic)->streams[i]; codec_ctx = stream->codec; /* Reencode video & audio and remux subtitles etc. */ if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { /* Open decoder */ ret = avcodec_open2(codec_ctx, avcodec_find_decoder(codec_ctx->codec_id), NULL); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i); return ret; } } } // Dump information about file onto standard error av_dump_format(*ic, 0, filename, 0); return 0; } int main(int argc, char *argv[]) { const char *inputFilename1 = "/avfiles/video_input.mp4"; const char *inputFilename2 = "/avfiles/audio_input.mp4"; const char *filename = "/avfiles/out.mp4"; int ret; av_register_all(); AVFormatContext *ic1 = nullptr; AVFormatContext *ic2 = nullptr; AVFormatContext *oc = nullptr; if ((ret = ffmpegOpenInputFile(inputFilename1, &ic1)) < 0) return ret; // and free resources and if ((ret = ffmpegOpenInputFile(inputFilename2, &ic2)) < 0) return ret; // and free resources and AVOutputFormat *outfmt = av_guess_format(NULL, filename, NULL); if (outfmt == NULL) return -1; // Could not guess output format avformat_alloc_output_context2(&oc, outfmt, NULL, filename); if (!oc) return AVERROR_UNKNOWN; // Could not create output context // populate input streams from all input files AVStream **input_streams = NULL; int nb_input_streams = 0; for (int i = 0; i nb_streams; i++) { input_streams = (AVStream **) grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1); input_streams[nb_input_streams - 1] = ic1->streams[i]; } for (int i = 0; i nb_streams; i++) { input_streams = (AVStream **) grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1); input_streams[nb_input_streams - 1] = ic2->streams[i]; } for (int i = 0; i video_codec_id*/ oc->oformat->video_codec != AV_CODEC_ID_NONE && ist != NULL && ist->codec->codec_type == AVMEDIA_TYPE_VIDEO) { AVCodec *out_vid_codec = avcodec_find_encoder(oc->oformat->video_codec); if (NULL == out_vid_codec) return -1; // Couldn't find video encoder AVStream *m_out_vid_strm = avformat_new_stream(oc, out_vid_codec); if (NULL == m_out_vid_strm) return -1; // Couldn't output video stream m_out_vid_strm->id = 0; // XXX: ret = avcodec_copy_context(m_out_vid_strm->codec, ist->codec); if (ret audio_codec_id*/ oc->oformat->audio_codec != AV_CODEC_ID_NONE && ist != NULL && ist->codec->codec_type == AVMEDIA_TYPE_AUDIO) { AVCodec *out_aud_codec = avcodec_find_encoder(oc->oformat->audio_codec); if (nullptr == out_aud_codec) return -1; // couldn't find audio codec AVStream *m_out_aud_strm = avformat_new_stream(oc, out_aud_codec); if (nullptr == m_out_aud_strm) return -1; // couldn't allocate audio out stream ret = avcodec_copy_context(m_out_aud_strm->codec, ist->codec); if (ret flags & AVFMT_NOFILE)) { ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE); if (ret < 0) return ret; // Could not open output file av_dump_format(oc, 0, filename, 1); ret = avformat_write_header(oc, NULL); if (ret < 0) return ret; // Error occurred when opening output file } return 0; } 

avformat_write_header(oc, NULL); 总是返回错误,我看到这样的消息:

 [mp4 @ 0x7f84ec900a00] Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated. Set AVStream.time_base instead. [mp4 @ 0x7f84ec900a00] Tag avc1/0x31637661 incompatible with output codec id '28' ([33][0][0][0]) 

但输入和输出流匹配:

 Input streams from 2 files: Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 2834 kb/s, 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc (default) Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default) Output #0, mp4, to '/Users/alex/Workspace/_qt/tubisto/avfiles/out.mp4': Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2834 kb/s, 47.95 tbc Stream #0:1: Audio: aac (libvo_aacenc) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s 

为什么输出编解码器不兼容的错误发生? 我的代码有什么问题,以及如何将所有输入文件中的所有流复制到输出文件?

原因是您没有正确设置编码器的codec_tag

您应该设置正确的codec_tag ,或将codec_tag设置为0并让codec_tag器为您处理。

以下是示例代码怎么做。

 AVFormatContext *ofmt_ctx; // todo AVCodec *oc; // todo AVStream *stream = avformat_new_stream(ofmt_ctx, oc); if (stream != NULL) { // ... unsigned int tag = 0; // for ffmpeg new api 3.x AVCodecParameters *parameters = stream->codecpar; if (av_codec_get_tag2(ofmt_ctx->oformat->codec_tag, oc->id, &tag) == 0) { av_log(NULL, AV_LOG_ERROR, "could not find codec tag for codec id %d, default to 0.\n", oc->id); } parameters->codec_tag = tag; stream->codec = avcodec_alloc_context3(oc); // more setting for stream->codec avcodec_parameters_to_context(stream->codec, parameters); // for old ffmpeg version stream->codec->codec_tag = tag; // ... }