当前位置: 首页 > news >正文

c++调用ffmpeg api录屏 并进行udp组播推流

代码及工程见https://download.csdn.net/download/daqinzl/88155241

开发工具:visual studio 2019

播放,采用ffmpeg工具集里的ffplay.exe, 执行命令 ffplay udp://224.1.1.1:5001

主要代码如下:


#include "pch.h"
#include <iostream>
using namespace std;

#include <stdio.h>

#define __STDC_CONSTANT_MACROS

extern "C"
{
#include "include/libavcodec/avcodec.h"
#include "include/libavformat/avformat.h"
#include "include/libswscale/swscale.h"
#include "include/libavdevice/avdevice.h"
#include "include/libavutil/imgutils.h"
#include "include/libavutil/opt.h"
#include "include/libavutil/imgutils.h"
#include "include/libavutil/mathematics.h"
#include "include/libavutil/time.h"
};


#pragma comment (lib,"avcodec.lib")
#pragma comment (lib,"avdevice.lib")
#pragma comment (lib,"avfilter.lib")
#pragma comment (lib,"avformat.lib")
#pragma comment (lib,"avutil.lib")
#pragma comment (lib,"swresample.lib")
#pragma comment (lib,"swscale.lib")


int main(int argc, char* argv[])
{

            AVFormatContext* m_fmt_ctx = NULL;
        AVInputFormat* m_input_fmt = NULL;
        int video_stream = -1;
        avdevice_register_all();
        avcodec_register_all();
        const char* deviceName =  "desktop";
        const char* inputformat = "gdigrab";
        int FPS = 23;  //15
        m_fmt_ctx = avformat_alloc_context();
        m_input_fmt = av_find_input_format(inputformat);
        AVDictionary* deoptions = NULL;
        av_dict_set_int(&deoptions, "framerate", FPS, AV_DICT_MATCH_CASE);
        av_dict_set_int(&deoptions, "rtbufsize", 3041280 * 100 * 5, 0);

        //如果不设置的话,在输入源是直播流的时候,会花屏。单位bytes
        //av_dict_set(&deoptions, "buffer_size", "10485760", 0);
        //av_dict_set(&deoptions, "reuse", "1", 0);

        int ret = avformat_open_input(&m_fmt_ctx, deviceName, m_input_fmt, &deoptions);
        if (ret != 0) {
            
                return ret;
        }
        av_dict_free(&deoptions);
        ret = avformat_find_stream_info(m_fmt_ctx, NULL);
        if (ret < 0) {
            
                return ret;
        }
        av_dump_format(m_fmt_ctx, 0, deviceName, 0);
        video_stream = av_find_best_stream(m_fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
        if (video_stream < 0) {
            
                return -1;
        }

        AVCodecContext * _codec_ctx = m_fmt_ctx->streams[video_stream]->codec;
        AVCodec* _codec = avcodec_find_decoder(_codec_ctx->codec_id);
        if (_codec == NULL) {
            
                return -1;
        }
        ret = avcodec_open2(_codec_ctx, _codec, NULL);
        if (ret != 0) {
            
                return -1;
        }
        int width = m_fmt_ctx->streams[video_stream]->codec->width;
        int height = m_fmt_ctx->streams[video_stream]->codec->height;
        int fps = m_fmt_ctx->streams[video_stream]->codec->framerate.num > 0 ? m_fmt_ctx->streams[video_stream]->codec->framerate.num : 25;
        AVPixelFormat videoType = m_fmt_ctx->streams[video_stream]->codec->pix_fmt;
        std::cout << "avstream timebase : " << m_fmt_ctx->streams[video_stream]->time_base.num << " / " << m_fmt_ctx->streams[video_stream]->time_base.den << endl;
            AVDictionary* enoptions = 0;
        //av_dict_set(&enoptions, "preset", "superfast", 0);
        //av_dict_set(&enoptions, "tune", "zerolatency", 0);
        av_dict_set(&enoptions, "preset", "ultrafast", 0);
        av_dict_set(&enoptions, "tune", "zerolatency", 0); 

        //TODO
        //av_dict_set(&enoptions, "pkt_size", "1316", 0);    //Maximum UDP packet size
        av_dict_set(&dic, "fifo_size", "18800", 0);
        av_dict_set(&enoptions, "buffer_size", "0", 1);
        av_dict_set(&dic, "bitrate", "11000000", 0);
        av_dict_set(&dic, "buffer_size", "1000000", 0);//1316
        //av_dict_set(&enoptions, "reuse", "1", 0);

        AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
        if (!codec)
        {
            
                std::cout << "avcodec_find_encoder failed!" << endl;
            return NULL;
        }
        AVCodecContext* vc = avcodec_alloc_context3(codec);
        if (!vc)
        {
            
                std::cout << "avcodec_alloc_context3 failed!" << endl;
            return NULL;
        }
        std::cout << "avcodec_alloc_context3 success!" << endl;
        vc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
        vc->codec_id = AV_CODEC_ID_H264;
        vc->codec_type = AVMEDIA_TYPE_VIDEO;
        vc->pix_fmt = AV_PIX_FMT_YUV420P;
        vc->width = width;
        vc->height = height;
        vc->time_base.num = 1;
        vc->time_base.den = FPS;
        vc->framerate = { FPS,1 };
        vc->bit_rate = 10241000;
        vc->gop_size = 120;
        vc->qmin = 10;
        vc->qmax = 51;
        vc->max_b_frames = 0;
        vc->profile = FF_PROFILE_H264_MAIN;                
        ret = avcodec_open2(vc, codec, &enoptions);
        if (ret != 0)
        {
            return ret;
        }
        std::cout << "avcodec_open2 success!" << endl;
        av_dict_free(&enoptions);
        SwsContext *vsc = nullptr;
        vsc = sws_getCachedContext(vsc,
            width, height, (AVPixelFormat)videoType, //源宽、高、像素格式
            width, height, AV_PIX_FMT_YUV420P,//目标宽、高、像素格式
            SWS_BICUBIC, // 尺寸变化使用算法
            0, 0, 0
        );
        if (!vsc)
        {
            
                cout << "sws_getCachedContext failed!";
            return false;
        }
        AVFrame* yuv = av_frame_alloc();
        yuv->format = AV_PIX_FMT_YUV420P;
        yuv->width = width;
        yuv->height = height;
        yuv->pts = 0;
        ret = av_frame_get_buffer(yuv, 32);
        if (ret != 0)
        {
            
                return ret;
        }
        //const char* rtmpurl = "rtmp://192.168.0.105:1935/live/desktop";
        const char* rtmpurl = "udp://224.1.1.1:5001";
        AVFormatContext * ic = NULL;
        //ret = avformat_alloc_output_context2(&ic, 0, "flv", rtmpurl);
        ret = avformat_alloc_output_context2(&ic, NULL, "mpegts", rtmpurl);//UDP
        if (ret < 0)
        {
            
                return ret;
        }
        AVStream* st = avformat_new_stream(ic, NULL);
        if (!st)
        {
            
                return -1;
        }
        st->codecpar->codec_tag = 0;
        avcodec_parameters_from_context(st->codecpar, vc);
        av_dump_format(ic, 0, rtmpurl, 1);
        ret = avio_open(&ic->pb, rtmpurl, AVIO_FLAG_WRITE);
        if (ret != 0)
        {
            
                return ret;
        }
        ret = avformat_write_header(ic, NULL);
        if (ret != 0)
        {
            
                return ret;
        }
        AVPacket* packet = av_packet_alloc();
        AVPacket* Encodepacket = av_packet_alloc();
        int frameIndex = 0;
        int EncodeIndex = 0;
        AVFrame* rgb = av_frame_alloc();
        AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
        long long startpts = m_fmt_ctx->start_time;
        long long lastpts = 0;
        long long duration = av_rescale_q(1, { 1,FPS }, { 1,AV_TIME_BASE });
        int got_picture = 0;
        while (frameIndex < 2000000)
        {
            
                ret = av_read_frame(m_fmt_ctx, packet);
            if (ret < 0) {
                
                    break;
            }
            if (packet->stream_index == video_stream)
            {
                
                    ret = avcodec_decode_video2(_codec_ctx, rgb, &got_picture, packet);
                if (ret < 0) {
                    
                        printf("Decode Error.\n");
                    return ret;
                }
                if (got_picture) {
                    
                        int h = sws_scale(vsc, rgb->data, rgb->linesize, 0, height, //源数据
                            yuv->data, yuv->linesize);
                    int guesspts = frameIndex * duration;
                    yuv->pts = guesspts;
                    frameIndex++;
                    ret = avcodec_encode_video2(vc, Encodepacket, yuv, &got_picture);
                    if (ret < 0) {
                        
                            printf("Failed to encode!\n");
                        break;
                    }
                    if (got_picture == 1) {
                        
                            Encodepacket->pts = av_rescale_q(EncodeIndex, vc->time_base, st->time_base);
                        Encodepacket->dts = Encodepacket->pts;
                        std::cout << "frameindex : " << EncodeIndex << " pts : " << Encodepacket->pts << " dts: " << Encodepacket->dts << " encodeSize:" << Encodepacket->size << " curtime - lasttime " << Encodepacket->pts - lastpts << endl;
                            lastpts = Encodepacket->pts;
                        ret = av_interleaved_write_frame(ic, Encodepacket);
                        EncodeIndex++;
                        av_packet_unref(Encodepacket);
                    }
                }
            }
            av_packet_unref(packet);
        }
        ret = avcodec_send_frame(vc, NULL);
        while (ret >= 0) {
            
                ret = avcodec_receive_packet(vc, Encodepacket);
            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                
                    break;
            }
            if (ret < 0) {
                
                    break;
            }
            ret = av_interleaved_write_frame(ic, Encodepacket);
            EncodeIndex++;
        }
        av_write_trailer(ic);
        av_packet_free(&packet);
        av_packet_free(&Encodepacket);
        av_frame_free(&rgb);
        av_frame_free(&yuv);
        av_bitstream_filter_close(h264bsfc);
        h264bsfc = NULL;
        if (vsc)
        {
            
                sws_freeContext(vsc);
            vsc = NULL;
        }
        if (_codec_ctx)
            avcodec_close(_codec_ctx);
        _codec_ctx = NULL;
        _codec = NULL;
        if (vc)
            avcodec_free_context(&vc);
        if (m_fmt_ctx)
            avformat_close_input(&m_fmt_ctx);
        if (ic && !(ic->flags & AVFMT_NOFILE))
            avio_closep(&ic->pb);
        if (ic) {
            
                avformat_free_context(ic);
            ic = NULL;
        }
        m_input_fmt = NULL;
        return 0;
    }
    

相关文章:

c++调用ffmpeg api录屏 并进行udp组播推流

代码及工程见https://download.csdn.net/download/daqinzl/88155241 开发工具&#xff1a;visual studio 2019 播放&#xff0c;采用ffmpeg工具集里的ffplay.exe, 执行命令 ffplay udp://224.1.1.1:5001 主要代码如下: #include "pch.h" #include <iostream>…...

war包方式安装linux和windows的geoserver

注意&#xff1a; 从Java 9开始&#xff0c;Oracle已经不再单独提供JRE&#xff08;Java Runtime Environment&#xff09;了&#xff0c;而是直接将JRE集成在JDK&#xff08;Java Development Kit&#xff09;中。这是因为JRE包含了运行Java程序所需的环境&#xff0c;而JDK除…...

安装CUDA与CUDNN与Pytorch(最新超级详细图文版本2023年8月最新)

一、安装CUDA 1.1、下载安装包 cuda可以认为就是Nvidia为了显卡炼丹搞的一个软件&#xff0c;其下载地址为&#xff1a;CUDA Toolkit 12.2 Update 1 Downloads | NVIDIA Developer 当你点进这个链接的时候&#xff0c;你需要依次选择 1是选择系统&#xff0c;这里选windows…...

内存快照:宕机后,Redis如何实现快速恢复?RDB

AOF的回顾 回顾Redis 的AOF的持久化机制。 Redis 避免数据丢失的 AOF 方法。这个方法的好处&#xff0c;是每次执行只需要记录操作命令&#xff0c;需要持久化的数据量不大。一般而言&#xff0c;只要你采用的不是 always 的持久化策略&#xff0c;就不会对性能造成太大影响。 …...

Linux之 Ubuntu 安装常见服务 (二) Tomcat

安装TomCat 服务 1、安装JDK环境 https://www.oracle.com/java/technologies/downloads/ 下载的官网 wget https://download.oracle.com/java/20/latest/jdk-20_linux-x64_bin.deb (sha256) 使用dpkg进行软件安装时&#xff0c;提示&#xff1a;dpkg&#xff1a;处理软件包XX…...

docker 配置 Mysql主从集群

Docker version 20.10.17, build 100c701 MySQL Image version: 8.0.32 Docker container mysql-master is source. mys ql-replica is replication. master source. replica slave.名称叫法不一样而已。 Choose one of the way&#xff0c;与replica同步数据两种情况&…...

Layui实现OA会议系统之会议管理模块总合

目录 一、项目背景 二、项目概述 1. 概述 2. 环境搭建 3. 工具类引用 4. 功能设计 4.1 会议发布 4.2 我的会议 4.3 会议审批 4.4 会议通知 4.5 待开会议 4.6 历史会议 4.7 所有会议 5. 性能优点 5.1 兼容性好 5.2 可维护性和可扩展性 5.3 轻量灵活 5.4 模块化设计…...

fishing之踩坑篇捕获数据不齐全

文章目录 一、问题记录二、解决方法三、更新钓鱼模板四、进行点击邮件五、查看仪表盘免责声明 一、问题记录 通过点击邮件内的链接&#xff0c;提交数据&#xff0c;但是只记录密码&#xff0c;无法记录username 二、解决方法 对于需要被捕获的表单数据&#xff0c;除了inp…...

ppt使用笔记

文章目录 如何让文档好看纯文字绝对不可行多用流程图和效果图切换动画母版音乐视频 作品渐变星空放大镜随机抽奖 其他快捷键 作为一个开发&#xff0c;对这种表现类型的软件一直不太上心&#xff0c;但有些场景要用到ppt&#xff0c;例如述职和项目案例分享。 很直观的体验就是…...

java中的hashmap和concurrenthashmap解析

hashmap的初始化数组大小为16&#xff0c;如果发生哈希冲突的时候在当前的索引后面采用头插法以链表的形式继续插入节点。 concurrenthashmap的结构图如下所示&#xff1a; 本身不是16个节点吗&#xff1f;这里分为两个长度为4的数组&#xff0c;变成了4*4总共16个节点&#x…...

元素2D转3D 椭圆形旋转实现

椭圆旋转功能展示 transform-style: preserve-3d;&#xff08;主要css代码&#xff09; gif示例&#xff08;背景图可插入透明以此实现边框线的旋转&#xff09; 导致的无法点击遮挡问题可以参考我的另一个文章 穿透属性-----------------------css穿透属性 实时代码展示...

Centos7.9 制作openssh9.2p2 rpm升级包和升级实战

一、背景说明 Centos7.9 默认安装的openssh 版本为7.4p1&#xff0c;经绿盟扫描&#xff0c;存在高危漏洞&#xff0c;需要升级到最新。 官网只提供编译安装包&#xff0c;为了方便升级&#xff0c;先通过编译安装包&#xff0c;制作rpm包&#xff0c;并进行升级 如下为做好…...

JavaScript学习(3)

Web API 是开发人员的梦想。 它可以扩展浏览器的功能它可以极大简化复杂的功能它可以为复杂的代码提供简单的语法 什么是 Web API&#xff1f; API 指的是应用程序编程接口&#xff08;Application Programming Interface&#xff09;。 Web API 是 Web 的应用程序编程接口…...

2023华为OD机试真题Java实现【寻找最大价值的矿堆/深度优先搜索】

前言 本题使用Java实现,如果需要Python代码,请点击以下链接 点我 题目 我们规定,0表示空地,1表示银矿、2表示金矿,矿堆表示由相邻的金矿或银矿连接形成的地图。 银矿价值是1 ,金矿价值是2 ,你的目标是找出地图中最大价值的矿堆,并且输出该矿堆的价值 示例1 输入:…...

MyCat概述

1.MyCat概述 MyCat是阿里巴巴的产品&#xff0c;他是开源的、基于Java语言编写的MySQL数据库中间件。可以像使用mysql一样来使用mycat&#xff0c;对于开发人员来说根本感觉不到mycat的存在。 MyCat下载地址&#xff1a;http://dl.mycat.org.cn/ MyCat官网&#xff1a;http:/…...

【LeetCode】【数据结构】单链表OJ常见题型(一)

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负。 目录 前言&#xff1a; 【LeetCode】203.移除链表元素 【LeetCo…...

QGraphicsView实现简易地图3『局部加载-地图缩放』

前文链接&#xff1a;QGraphicsView实现简易地图2『瓦片经纬度』 第一篇文章提到过&#xff0c;当地图层级较大时&#xff0c;暴力全加载地图会造成程序卡顿&#xff0c;因此需要实现地图的局部加载。 实现思路&#xff1a;以地图窗口&#xff08;以下称为视口&#xff09;为地…...

bash的特性(二)IO重定向与管道

bash的I/O重定向及管道 一、概述 在shell中&#xff0c;最常使用的fd(file descriptor)有三个&#xff0c;标准输入&#xff0c;标准输出&#xff0c;错误输出。进程用文件描述符来管理打开的文件。 名称 文件描述符 标准输入&#xff08;stdin) 0 键盘&#xff0c;也可以…...

elb 直接配置到后端服务器组

出现上图报错的原因是&#xff0c;前面elb配置了https证书&#xff0c;后端的nginx也配置了证书&#xff0c;导致冲突。 需要修改后端的nginx配置文件&#xff0c;将证书配置注释掉。 如果出现健康检查异常&#xff0c;需要在对应服务器的安全组上配置elb所在的网段的访问权限…...

安卓:BottomNavigationBar——底部导航栏控件

目录 一、BottomNavigationBar介绍 二、BottomNavigationBar的常用方法及其常用类 &#xff08;一&#xff09;、常用方法 1. 添加菜单项 2. 移除菜单项 3. 设置选中监听器 4. 设置当前选中项 5. 设置徽章 6. 样式和颜色定制 7. 动画效果 8. 隐藏底部导航栏。 9、设…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...