基于FFMPEG的视频拉流并传给OPENCV显示

news2024/11/20 10:33:40

基于FFMPEG的视频拉流并传给OPENCV显示

  • 依赖文件解压
  • 代码编写
  • 依赖配置
  • 编译运行

依赖文件解压

将ffmpeg-master-latest-win64-gpl-shared解压,得到如下所示文件夹:
在这里插入图片描述
将其中的bin目录下的.dll文件复制到C:\Windows\System32目录下。

代码编写

基于FFMPEG的拉流代码如下所示,修改添加拉流地址即可。

#include <iostream>
#include <opencv2/opencv.hpp>
extern "C"   //ffmpeg是采用c语言实现的 c++工程种 导入c语言
{
    //avcodec:编解码(最重要的库)
    #include <libavcodec/avcodec.h>
    //avformat:封装格式处理
    #include <libavformat/avformat.h>
    //swscale:视频像素数据格式转换
    #include <libswscale/swscale.h>
    //avdevice:各种设备的输入输出
    #include <libavdevice/avdevice.h>
    //avutil:工具库(大部分库都需要这个库的支持)
    #include <libavutil/avutil.h>

    #include <libavutil/imgutils.h>

}


int main() {
    // Initialize FFmpeg
    //av_register_all();//在新版本4.0以后,不需要调用该方法,可以直接使用所有模块。
    avformat_network_init();
    std::cout << "start work" << std::endl;

    // Open RTSP stream
    AVFormatContext* formatContext = nullptr;
    if (avformat_open_input(&formatContext, "rtsp://xxx", nullptr, nullptr) != 0) {//拉流地址
        std::cerr << "Failed to open RTSP stream." << std::endl;
        return -1;
    }

    // Find stream info
    if (avformat_find_stream_info(formatContext, nullptr) < 0) {
        std::cerr << "Failed to find stream info." << std::endl;
        return -1;
    }

    // Find video stream index
    int videoStreamIndex = -1;
    for (unsigned int i = 0; i < formatContext->nb_streams; ++i) {
        if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }

    if (videoStreamIndex == -1) {
        std::cerr << "Failed to find video stream." << std::endl;
        return -1;
    }

    // Get codec parameters for the video stream
    AVCodecParameters* codecParameters = formatContext->streams[videoStreamIndex]->codecpar;

    // Find video decoder
    const AVCodec* codec = avcodec_find_decoder(codecParameters->codec_id);
    if (codec == nullptr) {
        std::cerr << "Failed to find video decoder." << std::endl;
        return -1;
    }

    // Allocate codec context
    AVCodecContext* codecContext = avcodec_alloc_context3(codec);
    if (avcodec_parameters_to_context(codecContext, codecParameters) < 0) {
        std::cerr << "Failed to allocate codec context." << std::endl;
        return -1;
    }

    // Open codec
    if (avcodec_open2(codecContext, codec, nullptr) < 0) {
        std::cerr << "Failed to open codec." << std::endl;
        return -1;
    }
  
    // Prepare image conversion context
    //SwsContext* swsContext = sws_getContext(codecContext->width, codecContext->height,
    //    codecContext->pix_fmt,
    //    codecContext->width, codecContext->height,
    //    //AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr);
    //    AV_PIX_FMT_YUV420P, SWS_BILINEAR, nullptr, nullptr, nullptr);


    // Create OpenCV window for displaying frames
    cv::namedWindow("RTSP Stream", cv::WINDOW_NORMAL);

    AVPacket packet;
    cv::Mat frame;

    frame = cv::Mat(codecContext->height, codecContext->width, CV_8UC3);

    AVFrame* pFrameRGB = av_frame_alloc();
    uint8_t* buffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, codecContext->width, codecContext->height, 1));
    av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AV_PIX_FMT_RGB24, codecContext->width, codecContext->height, 1);

    struct SwsContext* sws_ctx = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt,
        codecContext->width, codecContext->height, AV_PIX_FMT_RGB24,
        SWS_BILINEAR, nullptr, nullptr, nullptr);

    while (av_read_frame(formatContext, &packet) >= 0) {
        if (packet.stream_index == videoStreamIndex) {
            // Decode video frame
            avcodec_send_packet(codecContext, &packet);
            AVFrame* avFrame = av_frame_alloc();
            int ret = avcodec_receive_frame(codecContext, avFrame);

            if (ret == 0) {
                // Convert frame to RGB
                sws_scale(sws_ctx, avFrame->data, avFrame->linesize, 0, codecContext->height, pFrameRGB->data, pFrameRGB->linesize);
                frame.data = pFrameRGB->data[0];
                // Display frame
                cv::imshow("RTSP Stream", frame);
                cv::waitKey(1);
            }

            av_frame_free(&avFrame);
        }

        av_packet_unref(&packet);
    }

    // Clean up
    avformat_close_input(&formatContext);
    avformat_network_deinit();
    avcodec_free_context(&codecContext);
    sws_freeContext(sws_ctx);

    return 0;
}

依赖配置

opencv的依赖在此不做赘述

  1. 打开项目的属性管理器,在“包含目录”和“库目录”中加入解压得到的ffmpeg的include和lib路径,如下所示:
    在这里插入图片描述

我这的包含目录路径是:E:\ffmpeg-master-latest-win64-gpl-shared\ffmpeg-master-latest-win64-gpl-shared\include
库目录路径是:E:\ffmpeg-master-latest-win64-gpl-shared\ffmpeg-master-latest-win64-gpl-shared\lib
2. 在属性页的链接器的输入部分的附加依赖项中添加库
在这里插入图片描述
添加如下库即可:

avcodec.lib
avdevice.lib
avfilter.lib
avformat.lib
avutil.lib
postproc.lib
swresample.lib
swscale.lib

编译运行

设为启动项目,编译运行即可,会使用opencv弹出窗口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/694067.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode 的终端不识别npm 命令

1.问题描述 在vscode终端输入npm指令无法识别 但是在cmd就可以 在PowerShell输入npm同样无法识别 2.解决办法 点击火狐浏览器可以看到有一个路径 没有火狐浏览器点击vscode同样可以看到路径 注&#xff1a;箭头指向的就是 然后在我的电脑找到该路径 下的npm文件 删除该…

SaaS架构方案

四大架构体系&#xff08;业务架构&#xff08;省略&#xff09;、系统架构、技术架构、布署架构&#xff09; 1.业务架构&#xff08;省略&#xff09; 2.系统架构 3.技术架构图 4.布署架构

Kubernetes核心概念汇总—Kubernetes 架构

一、概述 此页面是 Kubernetes 的概述。 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态&#xff0c;其服务、支持和工具的使用范围相当广泛。 Kub…

杂记 | Linux服务器使用docker安装keycloak(docker-compose)

文章目录 01 关于keycloak02 准备工作2.1 安装docker2.2 安装docekr-compose2.3 获取https证书 03 编写docker-compose.yml04 访问keycloak 01 关于keycloak Keycloak是一个开源的身份和访问管理解决方案&#xff0c;由RedHat公司开发和维护。它提供了一套全面的工具和功能&am…

centos 安装 nginx

1.下载nginx安装包 wget -c https://nginx.org/download/nginx-1.24.0.tar.gz 下载到了当前目录下 2.解压安装包 解压后的结果 3.安装依赖 yum -y install gcc gcc-c make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel 4. ./configure --prefix/usr/lo…

雷达侦察系统

文章目录 前言 一、系统组成 二、数字信道化侦察接收机 三、信号处理器 总结 前言 本人主要从事电子侦察中辐射源目标定位的研究工作&#xff0c;下面简单介绍传统雷达侦察系统的简单系统组成&#xff0c;希望有研究相同方向的同行可以私信交流。 一、系统组成 典型雷达侦察…

python机器学习—— 数据预处理 算法初步

目录 数据预处理1.获取数据2.处理缺失值3.划分数据集4.数据预处理和PCA降维5.算法实现&#xff1a;估计器 数据预处理 1.获取数据 from sklearn.datasets import load_iris liload_iris() print("获取特征值") print(li.data) print("目标值",li.target)#…

千万级规模微服务稳定性技术揭秘:隔离策略

随着当今云原生的发展&#xff0c;无状态微服务系统通过其良好的设计理念和相关技术栈的成熟&#xff0c;成为越来越多企业建设系统的首选&#xff0c;但不可避免的是随着微服务拆分系统增多&#xff0c;稳定性慢慢会被重视&#xff0c;如何保证服务7*24小时不间断服务&#xf…

数据结构---循环链表

数据结构—循环链表 循环单链表 typedef struct LNode {ElemType data;struct LNode* next; }LNode, *LinkList;循环单链表初始化 bool InitList(LinkList &L) {L (LNode*)malloc(sizeof(LNode));if (L NULL) return false;L->next L; //头结点next指向头结点retur…

Postman:mock server简单使用,自定义获取response body

一.mock server的作用 创建一个虚假的服务器接口&#xff0c;只要访问就可以返回设定好的response. 可用于接口调试和接口自动化测试。 二.操作步骤 首先创建一个mock server 指定response body 创建成功后Collections那里会自动多一个跟mock server 对应的接口 接下来…

前端Vue自定义银行卡号格式化组件 中间卡号文本转星号

前端Vue自定义银行卡号格式化组件 中间卡号文本转星号, 下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13230 效果图如下: # cc-format-card #### 使用方法 使用方法 <!-- cardNo:银行卡号 isStar: 是否转星号 --> <cc…

基于Debian 12 “Bookworm “的SparkyLinux 7.0 “Orion Belt” 正式发布

导读SparkyLinux 开发人员今天宣布&#xff0c;SparkyLinux 7.0 “Orion Belt “已经发布并全面上市&#xff0c;这是这个基于Debian的GNU/Linux发行版的最新稳定更新。 基于最近发布的Debian 12 “Bookworm “操作系统系列&#xff0c;并与2023年7月15日的资料库同步&#xff…

bug汇集-三

1、 2、async...await 同步执行 方法一&#xff08;推荐&#xff09;&#xff1a;使用 async...await 同步执行 方法二: 不用async...await&#xff0c;就是异步处理&#xff0c;需要每一步 都加提示

如何不注册Oracle登录账号而下载Oracle11g客户端

注册非常烦人。简单的事情本来一个安装包就搞定的事情&#xff0c;结果搞得比上天还复杂。 进入这个界面&#xff1a; Instant Client for Windows 32-bithttps://www.oracle.com/database/technologies/instant-client/microsoft-windows-32-downloads.html打开界面后。用浏…

【安全】使用docker安装Nessus

目录 一、准备docker环境服务器&#xff08;略&#xff09; 二、安装 2.1 搜索镜像 2.2 拉取镜像 2.3 启动镜像 三、离线更新插件 3.1 获取challenge 3.2 官方注册获取激活码 3.3 使用challenge码和激活码获取插件下载地址 3.4 下载的插件以及许可协议复制到容器内 四…

数字逻辑与模拟电子技术-部分知识点(3)——数电部分-基本逻辑运算、复合逻辑运算

目录 基本逻辑运算 与逻辑运算 或逻辑运算 非逻辑运算 复合逻辑运算 与非逻辑 或非逻辑 与或非逻辑 异或逻辑 同或逻辑 基本逻辑运算 逻辑代数中只有三种基本逻辑运算,即 “与”、“或”、“非”。 与逻辑运算 定义&#xff1a;只有决定一事件的全部条件都具备时&…

怎么学习网络安全相关知识? - 易智编译EaseEditing

学习网络安全相关知识是一个系统性的过程&#xff0c;以下是一些学习网络安全的方法和建议&#xff1a; 学习基础知识&#xff1a; 了解计算机网络、操作系统、网络协议等基础知识。掌握网络的工作原理、常见的网络攻击方式和防御策略。 学习安全技术&#xff1a; 学习各种网…

Spark 3.4.x Server Client模式下的数据传输实现

背景 在Spark中python和jvm的通信杂谈–ArrowConverter中&#xff0c;我们提到Spark 3.4.x中是Client和Server之间的数据传输是采用Arrow IPC的&#xff0c;那具体是怎么实现的呢&#xff1f; 分析 直接上代码ClientE2ETestSuite test("createDataFrame from complex t…

nginxconfig-部属

一、下载源码&#xff08;master&#xff09; GitHub - digitalocean/nginxconfig.io: ⚙️ NGINX config generator on steroids &#x1f489; 二、编译 npm install npm run build 三、将编译后的dist目录下的文件拷贝到nginx托管服务器下的目录&#xff1a;/data/wwwroot…

zabbix微信告警

环境&#xff1a;点击查看 注册一个企业微信&#xff08;官网&#xff09; 进入后台管理 拉一个用户 创建一个应用 下载脚本&#xff08;这步保留个人看法&#xff09; [rootchenshuyi requests-2.18.3]# wget https://github.com/X-Mars/Zabbix-Alert-WeChat.git --2021-0…