柴_笔记 2024-03-07 22:51 采纳率: 15.4%
浏览 102
已结题

ffmpeg6.0在Qt中实现推流

将ffmpeg 拉流取到的图像推流给另一个视频流地址
代码或者项目案例
或者推流本地mp4文件

  • 写回答

13条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-07 22:51
    关注

    引自免费微信小程序:皆我百晓生

    当然,为了在Qt中使用FFmpeg 6.0实现视频流的拉取和推送,你需要确保已经正确安装了FFmpeg库,并将其与你的Qt项目集成。以下是一个基本的示例代码片段,展示如何通过FFmpeg从一个RTSP源拉流并推送到另一个RTMP服务器:

    #include <QCoreApplication>
    extern "C" {
    #include <libavformat/avformat.h>
    }
    
    // FFmpeg错误处理宏
    #define CHECK_ERROR(condition, message) if (condition) { av_log(NULL, AV_LOG_ERROR, "%s\n", message); goto error; }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        // 初始化FFmpeg
        av_register_all();
        avformat_network_init();
    
        // 源RTSP流参数
        AVFormatContext *inputFormatContext = NULL;
        const char *inputUrl = "rtsp://your_input_stream_address";
    
        // 打开输入流
        if (avformat_open_input(&inputFormatContext, inputUrl, NULL, NULL) != 0)
            CHECK_ERROR(true, "Failed to open input stream");
    
        // 查找流信息
        if (avformat_find_stream_info(inputFormatContext, NULL) < 0)
            CHECK_ERROR(true, "Failed to retrieve input stream info");
    
        // 遍历找到视频流索引
        int videoStreamIndex = -1;
        for (unsigned int i = 0; i < inputFormatContext->nb_streams; ++i) {
            if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                videoStreamIndex = i;
                break;
            }
        }
        CHECK_ERROR(videoStreamIndex == -1, "No video stream found in the input");
    
        // 输出RTMP流参数
        AVFormatContext *outputFormatContext = NULL;
        const char *outputUrl = "rtmp://your_output_stream_address/live/stream_key";
    
        // 创建输出格式上下文
        AVOutputFormat *outputFormat = av_guess_format(NULL, outputUrl, NULL);
        CHECK_ERROR(!outputFormat, "Could not deduce output format from URL");
    
        if (avformat_alloc_output_context2(&outputFormatContext, outputFormat, NULL, outputUrl) < 0)
            CHECK_ERROR(true, "Failed to allocate output format context");
    
        // 添加输出视频流
        AVStream *outVideoStream = avformat_new_stream(outputFormatContext, NULL);
        CHECK_ERROR(!outVideoStream, "Failed to create output video stream");
        if (avcodec_parameters_copy(outVideoStream->codecpar, inputFormatContext->streams[videoStreamIndex]->codecpar) < 0)
            CHECK_ERROR(true, "Failed to copy codec parameters");
    
        // 打开输出流
        if (avio_open(&outputFormatContext->pb, outputUrl, AVIO_FLAG_WRITE) < 0)
            CHECK_ERROR(true, "Failed to open output URL");
    
        // 写入文件头信息
        if (avformat_write_header(outputFormatContext, NULL) < 0)
            CHECK_ERROR(true, "Failed to write header to output file");
    
        AVPacket packet;
        while (true) {
            // 读取一帧数据
            if (av_read_frame(inputFormatContext, &packet) < 0) {
                // 如果遇到EOF或其他错误,退出循环
                break;
            }
    
            // 只处理视频流
            if (packet.stream_index == videoStreamIndex) {
                // 将该帧写入输出流
                if (av_interleaved_write_frame(outputFormatContext, &packet) < 0) {
                    CHECK_ERROR(true, "Error writing interleaved frame to output");
                }
                av_packet_unref(&packet);
            }
        }
    
        // 写入文件尾信息
        av_write_trailer(outputFormatContext);
    
    error:
        // 清理资源
        if (inputFormatContext) {
            avformat_close_input(&inputFormatContext);
            avformat_free_context(inputFormatContext);
        }
        if (outputFormatContext) {
            av_write_trailer(outputFormatContext);
            avio_closep(&outputFormatContext->pb);
            avformat_free_context(outputFormatContext);
        }
    
        return a.exec();
    }
    

    请注意,以上代码并未包含错误处理的全部细节,你可能需要根据实际环境进行适当的调整和优化。同时,对于本地MP4文件的推流,只需将inputUrl指向本地文件路径,并相应地调整输入流打开方式即可。

    此外,在实际项目中,你可能还需要考虑线程同步、性能优化以及FFmpeg版本兼容性问题。记得在项目中链接必要的FFmpeg库,并且由于FFmpeg API更新频繁,请确保所使用的API与你的FFmpeg版本对应。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(12条)

报告相同问题?

问题事件

  • 系统已结题 3月16日
  • 已采纳回答 3月8日
  • 创建了问题 3月7日