将ffmpeg 拉流取到的图像推流给另一个视频流地址
代码或者项目案例
或者推流本地mp4文件
13条回答 默认 最新
关注引自免费微信小程序:皆我百晓生
当然,为了在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版本对应。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录