ffmpeg mkv 转 MP4

ffmpeg -i 源文件名 -c:v copy -c:a aac 目标文件名
ffmpeg -i 1.mkv -c:v copy -c:a aac 1.mp4

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要使用 C++ 和 FFmpeg 进行视频格式换,你需要了解 FFmpeg 的基本用法和 C++ 的编程知识。 以下是一个简单的示例代码,可以将 MKV 格式的视频文件换为 MP4 格式。在代码中,我们使用了 FFmpeg 提供的 libavformat 和 libavcodec 库来进行视频格式的解封装和编码。 ```c++ #include <iostream> #include <string> extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/opt.h> } int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " input.mkv output.mp4" << std::endl; return 1; } const std::string input_filename = argv[1]; const std::string output_filename = argv[2]; // 初始化 FFmpeg av_register_all(); // 打开输入文件 AVFormatContext* input_format_context = nullptr; if (avformat_open_input(&input_format_context, input_filename.c_str(), nullptr, nullptr) < 0) { std::cerr << "Could not open input file: " << input_filename << std::endl; return 1; } // 获取流信息 if (avformat_find_stream_info(input_format_context, nullptr) < 0) { std::cerr << "Could not find stream information" << std::endl; avformat_close_input(&input_format_context); return 1; } // 找到视频流 int video_stream_index = -1; for (unsigned int i = 0; i < input_format_context->nb_streams; i++) { AVStream* stream = input_format_context->streams[i]; if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream_index = i; break; } } if (video_stream_index == -1) { std::cerr << "Could not find video stream" << std::endl; avformat_close_input(&input_format_context); return 1; } // 打开编码器 AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) { std::cerr << "Could not find H.264 codec" << std::endl; avformat_close_input(&input_format_context); return 1; } AVCodecContext* codec_context = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_context, input_format_context->streams[video_stream_index]->codecpar); if (avcodec_open2(codec_context, codec, nullptr) < 0) { std::cerr << "Could not open codec" << std::endl; avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); return 1; } // 创建输出文件 AVFormatContext* output_format_context = nullptr; if (avformat_alloc_output_context2(&output_format_context, nullptr, "mp4", nullptr) < 0) { std::cerr << "Could not create output context" << std::endl; avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); return 1; } // 添加视频流 AVStream* output_stream = avformat_new_stream(output_format_context, codec); if (!output_stream) { std::cerr << "Could not create output stream" << std::endl; avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); avformat_free_context(output_format_context); return 1; } output_stream->id = output_format_context->nb_streams - 1; if (avcodec_parameters_copy(output_stream->codecpar, input_format_context->streams[video_stream_index]->codecpar) < 0) { std::cerr << "Could not copy codec parameters" << std::endl; avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); avformat_free_context(output_format_context); return 1; } // 打开输出文件 if (!(output_format_context->oformat->flags & AVFMT_NOFILE)) { if (avio_open(&output_format_context->pb, output_filename.c_str(), AVIO_FLAG_WRITE) < 0) { std::cerr << "Could not open output file: " << output_filename << std::endl; avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); avformat_free_context(output_format_context); return 1; } } // 写入头部信息 if (avformat_write_header(output_format_context, nullptr) < 0) { std::cerr << "Error occurred when writing header" << std::endl; avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); avformat_free_context(output_format_context); return 1; } // 换数据 AVPacket packet; av_init_packet(&packet); while (true) { AVStream* stream = input_format_context->streams[video_stream_index]; if (av_read_frame(input_format_context, &packet) < 0) { break; } if (packet.stream_index != video_stream_index) { av_packet_unref(&packet); continue; } packet.stream_index = output_stream->index; AVFrame* frame = av_frame_alloc(); if (!frame) { std::cerr << "Could not allocate frame" << std::endl; av_packet_unref(&packet); break; } int ret = avcodec_send_packet(codec_context, &packet); if (ret < 0) { std::cerr << "Error sending packet to codec" << std::endl; av_frame_free(&frame); av_packet_unref(&packet); break; } while (ret >= 0) { ret = avcodec_receive_frame(codec_context, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { av_frame_free(&frame); break; } else if (ret < 0) { std::cerr << "Error during decoding" << std::endl; av_frame_free(&frame); break; } if (avcodec_send_frame(codec_context, frame) < 0) { std::cerr << "Error sending frame to codec" << std::endl; av_frame_free(&frame); break; } while (avcodec_receive_packet(codec_context, &packet) == 0) { packet.stream_index = output_stream->index; av_write_frame(output_format_context, &packet); av_packet_unref(&packet); } av_frame_free(&frame); } av_packet_unref(&packet); } // 写入尾部信息 av_write_trailer(output_format_context); // 释放资源 avcodec_free_context(&codec_context); avformat_close_input(&input_format_context); avformat_free_context(output_format_context); return 0; } ``` 该示例代码中,我们从命令行获取输入和输出文件的名字,然后使用 FFmpeg 解析输入文件并找到视频流。接着,我们打开 H.264 编码器,并创建一个 MP4 格式的输出文件。然后,我们使用 FFmpeg 解码输入文件并将解码后的帧编码为 H.264 格式,并将编码后的帧写入输出文件。最后,我们释放所有资源并退出程序。 请注意,这只是一个基础的示例代码,仅供参考。在实际应用中,你可能需要添加更多的错误处理和参数设置,以适应不同的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值