ZBLOG

ffmpeg 读取mp4文件 编码为h265 存储为h265文件 c++

你可以使用FFmpeg库来读取MP4文件并将其编码为H.265格式,然后存储为H.265文件。下面是一个简单的C++示例代码:

#include <iostream>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}

int main() {
    const char* inputFileName = "input.mp4";
    const char* outputFileName = "output.h265";

    // 注册所有的编解码器和文件格式
    av_register_all();

    AVFormatContext* formatContext = nullptr;

    // 打开输入文件
    if (avformat_open_input(&formatContext, inputFileName, nullptr, nullptr) != 0) {
        std::cerr << "无法打开输入文件" << std::endl;
        return -1;
    }

    // 查找流信息
    if (avformat_find_stream_info(formatContext, nullptr) < 0) {
        std::cerr << "无法获取流信息" << std::endl;
        avformat_close_input(&formatContext);
        return -1;
    }

    AVCodecParameters* codecParams = nullptr;
    
    // 查找视频流
    int videoStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
    
    if (videoStreamIndex >= 0) {
        codecParams = formatContext->streams[videoStreamIndex]->codecpar;

        AVCodec* codec = avcodec_find_encoder_by_name("libx265");
        
        if (!codec) {
            std::cerr << "找不到H.265编码器" << std::endl;
            avformat_close_input(&formatContext);
            return -1;
        }

        AVCodecContext* codecContext = avcodec_alloc_context3(codec);

        // 配置编码器参数
        codecContext->width = codecParams->width;
        codecContext->height = codecParams->height;
        codecContext->sample_aspect_ratio = codecParams->sample_aspect_ratio;

        // 设置H.265特有的参数
        av_opt_set(codecContext->priv_data, "preset", "fast", 0);  // 编码速度设置为快速模式

        // 打开编码器
        if (avcodec_open2(codecContext, codec, nullptr) < 0) {
            std::cerr << "无法打开编码器" << std::endl;
            avcodec_free_context(&codecContext);
            avformat_close_input(&formatContext);
            return -1;
        }

        AVPacket packet;

        FILE* outputFile = fopen(outputFileName, "wb");

		// 初始化格式转换上下文
		SwsContext* swsCtx = sws_getCachedContext(nullptr, 
												 codecParams->width, codecParams->height, (AVPixelFormat)codecParams->format,
                                                 codecParams->width, codecParams->height, AV_PIX_FMT_YUV420P,
                                                 SWS_BICUBIC, nullptr, nullptr, nullptr);

		// 初始化输入帧和输出帧
		AVFrame* inputFrame = av_frame_alloc();
		uint8_t* pictureBuffer = new uint8_t[av_image_get_buffer_size(AV_PIX_FMT_YUV420P,
                                                                      codecParams->width, codecParams->height,
                                                                      32)];
		
		av_image_fill_arrays(inputFrame->data, inputFrame->linesize,
                             pictureBuffer,
                             AV_PIX_FMT_YUV420P,
                             codecParams->width, codecParams->height, 32);

        while (av_read_frame(formatContext, &packet) >= 0) {
            if (packet.stream_index == videoStreamIndex) {
				// 将输入帧从原始格式转换为YUV420P
				AVFrame* convertedFrame = av_frame_alloc();
				av_image_fill_arrays(convertedFrame->data, convertedFrame->linesize,
                                     pictureBuffer,
                                     AV_PIX_FMT_YUV420P,
                                     codecParams->width, codecParams->height, 32);
				
				sws_scale(swsCtx, packet.data, packet.linesize,
                          0, codecParams->height,
                          convertedFrame->data, convertedFrame->linesize);

                // 发送视频帧给编码器
                if (avcodec_send_frame(codecContext, convertedFrame) < 0) {
                    std::cerr << "无法发送视频帧给编码器" << std::endl;
                    av_packet_unref(&packet);
                    break;
                }

                // 接收编码后的数据包
                while (true) {
                    if (avcodec_receive_packet(codecContext, &packet) < 0)
                        break;

                    // 写入H.265文件
                    fwrite(packet.data, 1, packet.size, outputFile);

                    av_packet_unref(&packet);
                }
                
                av_frame_free(&convertedFrame);
            }

            av_packet_unref(&packet);
        }

        fclose(outputFile);

        delete[] pictureBuffer;

		sws_freeContext(swsCtx);
		av_frame_free(&inputFrame);

        avcodec_free_context(&codecContext);
    }
    
    avformat_close_input(&formatContext);

    return 0;
}

这段代码使用libx265作为H.265编码器,打开输入的MP4文件,查找视频流,并将其编码为H.265格式,然后将编码后的数据包写入到输出文件中。请注意,你需要安装FFmpeg库并链接相应的依赖项来运行此代码。

希望这个示例对你有所帮助!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=5054

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?