c++调用ffmpeg api将视频文件内容进行udp推流
代码及工程见https://download.csdn.net/download/daqinzl/88156926
开发工具:visual studio 2019
播放,采用ffmpeg工具集里的ffplay.exe, 执行命令 ffplay udp://238.1.1.10:6016
主要代码如下:
#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[])
{
AVOutputFormat* ofmt = NULL;
//输入对应一个AVFormatContext,输出对应一个AVFormatContext
//(Input AVFormatContext and Output AVFormatContext)
AVFormatContext* ifmt_ctx = NULL, * ofmt_ctx = NULL;
AVPacket pkt;
const char* in_filename, * out_filename;
int ret, i;
int videoindex = -1;
int frame_index = 0;
int64_t start_time = 0;
in_filename = "udp://238.1.1.11:1234";//可以为本地文件或者其他形式的直播流、设备等
in_filename = "d:/mv/test.mp4";
out_filename = "udp://238.1.1.10:6016";
av_register_all();
//Network
avformat_network_init();
if (true) {
}
else {
end:
avformat_close_input(&ifmt_ctx);
/* close output */
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_close(ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
if (ret < 0 && ret != AVERROR_EOF) {
printf("Error occurred.\n");
return -1;
}
return 0;
}
AVDictionary* inputdic = NULL;
//如果不设置的话,在输入源是直播流的时候,会花屏。单位bytes
av_dict_set(&inputdic, "buffer_size", "10485760", 0);
av_dict_set(&inputdic, "reuse", "1", 0);
//输入(Input)
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, &inputdic)) < 0) {
printf("Could not open input file.");
goto end;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
printf("Failed to retrieve input stream information");
goto end;
}
for (i = 0; i < ifmt_ctx->nb_streams; i++)
if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoindex = i;
break;
}
av_dump_format(ifmt_ctx, 0, in_filename, 0);
//输出(Output)
avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpegts", out_filename);//UDP
if (!ofmt_ctx) {
printf("Could not create output context\n");
ret = AVERROR_UNKNOWN;
goto end;
}
ofmt = ofmt_ctx->oformat;
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
//根据输入流创建输出流(Create output AVStream according to input AVStream)
AVStream* in_stream = ifmt_ctx->streams[i];
AVStream* out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
if (!out_stream) {
printf("Failed allocating output stream\n");
ret = AVERROR_UNKNOWN;
goto end;
}
//复制AVCodecContext的设置(Copy the settings of AVCodecContext)
//tanzhenwen
ret = avcodec_parameters_copy(out_stream->codecpar, ifmt_ctx->streams[i]->codecpar);
if (ret < 0) {
printf("Failed to copy parameters from input to output stream codec context\n");
goto end;
}
/* ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
if (ret < 0) {
printf("Failed to copy context from input to output stream codec context\n");
goto end;
}*/
out_stream->codec->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
//Dump Format------------------
av_dump_format(ofmt_ctx, 0, out_filename, 1);
//打开输出URL(Open output URL)
if (!(ofmt->flags & AVFMT_NOFILE)) {
AVDictionary* dic = NULL;
av_dict_set(&dic, "pkt_size", "1316", 0); //Maximum UDP packet size
//av_dict_set(&dic, "fifo_size", "18800", 0);
//av_dict_set(&dic, "buffer_size", "1000000", 0);
//av_dict_set(&dic, "bitrate", "11000000", 0);
//av_dict_set(&dic, "buffer_size", "1000000", 0);//1316
av_dict_set(&dic, "reuse", "1", 0);
ret = avio_open2(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE, NULL, &dic);
//ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
printf("Could not open output URL '%s'", out_filename);
goto end;
}
}
//av_opt_set(ofmt_ctx->priv_data, "muxrate", "11000000", 0);
av_opt_set(ofmt_ctx->priv_data, "MpegTSWrite", "1", 0);
av_opt_set(ofmt_ctx->priv_data, "pes_payload_size", "300", 0);
//写文件头(Write file header)
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
printf("Error occurred when opening output URL\n");
goto end;
}
start_time = av_gettime();
int64_t deltpts = 0;
while (1) {
AVStream* in_stream, * out_stream;
//获取一个AVPacket(Get an AVPacket)
ret = av_read_frame(ifmt_ctx, &pkt);
if (ret < 0)
break;
//FIX:No PTS (Example: Raw H.264)
//Simple Write PTS
if (pkt.pts == AV_NOPTS_VALUE) {
//Write PTS
AVRational time_base1 = ifmt_ctx->streams[videoindex]->time_base;
//Duration between 2 frames (us)
int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(ifmt_ctx->streams[videoindex]->r_frame_rate);
//Parameters
pkt.pts = (double)(frame_index * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE);
pkt.dts = pkt.pts;
pkt.duration = (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE);
}
//Important:Delay
if (pkt.stream_index == videoindex) {
AVRational time_base = ifmt_ctx->streams[videoindex]->time_base;
AVRational time_base_q = { 1,AV_TIME_BASE };
int64_t pts_time = av_rescale_q(pkt.dts, time_base, time_base_q);
int64_t now_time = av_gettime() - start_time;
static bool first = true;
if (first)
{
deltpts = pts_time;
first = false;
}
if (pts_time - deltpts > now_time)
av_usleep(pts_time - deltpts - now_time);
}
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[pkt.stream_index];
//if (pkt.stream_index == videoindex) {
// out_stream->time_base = AVRational{ 1, 25 };
//}
/* copy packet */
//转换PTS/DTS(Convert PTS/DTS)
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;
//Print to Screen
if (pkt.stream_index == videoindex) {
//printf("Send %8d video frames to output URL\n", frame_index);
frame_index++;
}
//ret = av_write_frame(ofmt_ctx, &pkt);
ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
if (ret < 0) {
printf("Error muxing packet\n");
break;
}
av_free_packet(&pkt);
}
//写文件尾(Write file trailer)
av_write_trailer(ofmt_ctx);
//end:
avformat_close_input(&ifmt_ctx);
/* close output */
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_close(ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
if (ret < 0 && ret != AVERROR_EOF) {
printf("Error occurred.\n");
return -1;
}
return 0;
}
相关文章:
c++调用ffmpeg api将视频文件内容进行udp推流
代码及工程见https://download.csdn.net/download/daqinzl/88156926 开发工具:visual studio 2019 播放,采用ffmpeg工具集里的ffplay.exe, 执行命令 ffplay udp://238.1.1.10:6016 主要代码如下: #include "pch.h" #include <iostream&g…...
助力工业物联网,工业大数据之服务域:油站主题分析【二十六】
文章目录 07:服务域:油站主题分析08:服务域:油站主题实现 07:服务域:油站主题分析 目标:掌握油站主题的需求分析 路径 step1:需求step2:分析 实施 需求:统计…...
MySql之索引
MySql之索引 1.索引概述 MySql官方对索引的定义为:索引是帮助MySql高效获取数据的数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据,这样就可以在这些数据结构上实现高级查找…...
adb调试
连不上 adb 如果还遇到5037端口被占用的问题,就找出进程号用taskkill命令杀死该进程即可 1、查找5037端口对应的进程:netstat -ano|findstr 5037 2、杀死该进程:taskkill /F /PID pid 连接unity profiler 打开发包,并安装在手机…...
ElasticSearch_学习笔记
一、初始elasticsearch 什么是elasticsearch? 一个开源的分布式搜索引擎,可以用来时限搜素、日志统计、分析、系统监控等功能。什么是elasitc stack(ELK)? 是以elasticsearch为核心的技术栈,包括 beats、L…...
Portraiture 4.0.3 for windows/Mac简体中文版(ps人像磨皮滤镜插件)
Imagenomic Portraiture系列插件作为PS磨皮美白必备插件,可以说是最强,今天它更新到了4.0.3版本。但是全网都没有汉化包,经过几个日夜汉化,终于汉化完成可能是全网首个Portraiture 4的汉化包,请大家体验,有…...
Java精品项目源码第152期火车票预订系统(编号M062)
Java精品项目源码第152期火车票预订系统(编号M062) 大家好,小辰今天给大家介绍一个基于Spring Springboot MyBatis实现的火车票预订系统,演示视频文章末尾公众号对号查询观看即可 文章目录 Java精品项目源码第152期火车票预订系…...
嵌入式软件C/C++(技术面试题)
一,网络 1,TCP窗口机制 TCP(传输控制协议)是一种可靠的、面向连接的传输层协议。其中的窗口机制是TCP协议中的一项重要功能,用于控制数据在发送和接收之间的流程。 TCP窗口机制是利用滑动窗口的方式来进行拥塞控制和…...
Idea中侧面栏不见了,如何设置?
一、打开idea点击File然后点击Setting 二、点击Appearance,然后划到最下面,勾选Show tool windows bars和Side-by-side layout on the left 三、侧面栏目正常显示...
构建高效读写分离MySQL主从复制架构,应对高可用挑战!
前言 在现代数据库架构中,MySQL主从复制技术扮演着重要角色。它不仅可以提升数据库性能和可扩展性,还赋予系统卓越的高可用性和灾难恢复能力。本文将深入剖析MySQL主从复制的内部机制,同时通过一个实际案例,展示其在实际场景中的…...
Stable Diffusion系列课程二:ControlNet
AUTOMATIC1111/stable-diffusion-webui参考B站Nenly视频《零基础学会Stable Diffusion》、视频课件推荐网站:stable-diffusion-art、Civitai(魔法) 、libilibi、AI艺术天堂推荐Stable Diffusion整合资料: NovelAI资源整合、《AI绘…...
【css】使用float实现水平导航栏
该实例使用float 浮动实现元素浮动在水平方向,从而实现水平导航栏效果。 overflow: hidden:当不给父级元素设置高度的时候,其内部元素浮动后会导致下面的元素顶上去,这是因为子元素浮动后,子元素脱离标准流࿰…...
IDEA超强XSD文件编辑插件-XSD / WSDL Visualizer
前言 XSD / WSDL Visualizer可以简化XML架构定义(XSD)和WSDL文件编辑过程; 通过使用与IntelliJ无缝集成的可视化编辑器,转换处理XSD和WSDL文件的方式。告别导航复杂和难以阅读的代码的挫败感,迎接流线型和直观的体验。 插件安装 在线安装 IntelliJ IDE…...
Nodejs 第三章(Npm Package json)
npm npm(全称 Node Package Manager)是 Node.js 的包管理工具,它是一个基于命令行的工具,用于帮助开发者在自己的项目中安装、升级、移除和管理依赖项。 https://www.npmjs.com/ 类似于 PHP 的工具:Composer。它是 …...
Tool Documentation Enables Zero-Shot Tool-Usage with Large Language Models
本文是LLM系列文章的内容,针对《Tool Documentation Enables Zero-Shot Tool-Usage with Large Language Models》的翻译。 工具文档赋能大模型零样本的工具使用 摘要1 引言2 相关工作3 实验设置3.1 常规的工作流3.2 工具使用提示方法3.3 评估任务 4 实证研究结果4…...
16 Springboot——登录功能实现
16.1 修改index.html中表单跳转的地址 将action的地址改为user/login,意思是点击提交按钮后,就会跳转到user/login地址,然后只要用Controller类的RequsetMapping去接这个地址就行了。 <body class"text-center"><form cl…...
数据结构-栈队列链表树
1 栈 概念 栈是⼀个线性结构,在计算机中是⼀个相当常⻅的数据结构。栈的特点是只能在某⼀端添加或删除数据,遵循先进后出的原则 实现 每种数据结构都可以⽤很多种⽅式来实现,其实可以把栈看成是数组的⼀个⼦集,所以这⾥使⽤数…...
clickhouse功能使用
离线聚合 物化视图 clickhouse需在AggregatingMergeTree之上建立物化视图来完成聚合的效果。以小时聚合为例说明 首先创建表,此处是本地表,且没有副本 #创建表 CREATE TABLE datasets.bt_stats (`btname` String,`record` UInt64,`EventTime` DateTime...
java中使用Jsoup和Itext实现将html转换为PDF
1.在build.gradle中安装所需依赖: implementation group: com.itextpdf, name: itextpdf, version: 5.5.13 implementation group: com.itextpdf.tool, name: xmlworker, version: 5.5.13 implementation group: org.jsoup, name: jsoup, version: 1.15.32.创建工具…...
无人驾驶实战-第七课(高精地图和V2X )
高精地图是无人驾驶中的重要一环,对环境感知、规划与定位等都有重要的作用。 高精地图的特点: 可视化、静态目标、地图信息、点云数据 高精地图与导航地图的区别 High Definition Map Navigation Map Precision cm m Information 3D lane info Mo…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
