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

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 开发工具&#xff1a;visual studio 2019 播放&#xff0c;采用ffmpeg工具集里的ffplay.exe, 执行命令 ffplay udp://238.1.1.10:6016 主要代码如下: #include "pch.h" #include <iostream&g…...

助力工业物联网,工业大数据之服务域:油站主题分析【二十六】

文章目录 07&#xff1a;服务域&#xff1a;油站主题分析08&#xff1a;服务域&#xff1a;油站主题实现 07&#xff1a;服务域&#xff1a;油站主题分析 目标&#xff1a;掌握油站主题的需求分析 路径 step1&#xff1a;需求step2&#xff1a;分析 实施 需求&#xff1a;统计…...

MySql之索引

MySql之索引 1.索引概述 MySql官方对索引的定义为&#xff1a;索引是帮助MySql高效获取数据的数据结构。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用数据&#xff0c;这样就可以在这些数据结构上实现高级查找…...

adb调试

连不上 adb 如果还遇到5037端口被占用的问题&#xff0c;就找出进程号用taskkill命令杀死该进程即可 1、查找5037端口对应的进程&#xff1a;netstat -ano|findstr 5037 2、杀死该进程&#xff1a;taskkill /F /PID pid 连接unity profiler 打开发包&#xff0c;并安装在手机…...

ElasticSearch_学习笔记

一、初始elasticsearch 什么是elasticsearch&#xff1f; 一个开源的分布式搜索引擎&#xff0c;可以用来时限搜素、日志统计、分析、系统监控等功能。什么是elasitc stack&#xff08;ELK&#xff09;&#xff1f; 是以elasticsearch为核心的技术栈&#xff0c;包括 beats、L…...

Portraiture 4.0.3 for windows/Mac简体中文版(ps人像磨皮滤镜插件)

Imagenomic Portraiture系列插件作为PS磨皮美白必备插件&#xff0c;可以说是最强&#xff0c;今天它更新到了4.0.3版本。但是全网都没有汉化包&#xff0c;经过几个日夜汉化&#xff0c;终于汉化完成可能是全网首个Portraiture 4的汉化包&#xff0c;请大家体验&#xff0c;有…...

Java精品项目源码第152期火车票预订系统(编号M062)

Java精品项目源码第152期火车票预订系统&#xff08;编号M062&#xff09; 大家好&#xff0c;小辰今天给大家介绍一个基于Spring Springboot MyBatis实现的火车票预订系统&#xff0c;演示视频文章末尾公众号对号查询观看即可 文章目录 Java精品项目源码第152期火车票预订系…...

嵌入式软件C/C++(技术面试题)

一&#xff0c;网络 1&#xff0c;TCP窗口机制 TCP&#xff08;传输控制协议&#xff09;是一种可靠的、面向连接的传输层协议。其中的窗口机制是TCP协议中的一项重要功能&#xff0c;用于控制数据在发送和接收之间的流程。 TCP窗口机制是利用滑动窗口的方式来进行拥塞控制和…...

Idea中侧面栏不见了,如何设置?

一、打开idea点击File然后点击Setting 二、点击Appearance,然后划到最下面&#xff0c;勾选Show tool windows bars和Side-by-side layout on the left 三、侧面栏目正常显示...

构建高效读写分离MySQL主从复制架构,应对高可用挑战!

前言 在现代数据库架构中&#xff0c;MySQL主从复制技术扮演着重要角色。它不仅可以提升数据库性能和可扩展性&#xff0c;还赋予系统卓越的高可用性和灾难恢复能力。本文将深入剖析MySQL主从复制的内部机制&#xff0c;同时通过一个实际案例&#xff0c;展示其在实际场景中的…...

Stable Diffusion系列课程二:ControlNet

AUTOMATIC1111/stable-diffusion-webui参考B站Nenly视频《零基础学会Stable Diffusion》、视频课件推荐网站&#xff1a;stable-diffusion-art、Civitai&#xff08;魔法&#xff09; 、libilibi、AI艺术天堂推荐Stable Diffusion整合资料&#xff1a; NovelAI资源整合、《AI绘…...

【css】使用float实现水平导航栏

该实例使用float 浮动实现元素浮动在水平方向&#xff0c;从而实现水平导航栏效果。 overflow: hidden&#xff1a;当不给父级元素设置高度的时候&#xff0c;其内部元素浮动后会导致下面的元素顶上去&#xff0c;这是因为子元素浮动后&#xff0c;子元素脱离标准流&#xff0…...

IDEA超强XSD文件编辑插件-XSD / WSDL Visualizer

前言 XSD / WSDL Visualizer可以简化XML架构定义(XSD)和WSDL文件编辑过程; 通过使用与IntelliJ无缝集成的可视化编辑器&#xff0c;转换处理XSD和WSDL文件的方式。告别导航复杂和难以阅读的代码的挫败感&#xff0c;迎接流线型和直观的体验。 插件安装 在线安装 IntelliJ IDE…...

Nodejs 第三章(Npm Package json)

npm npm&#xff08;全称 Node Package Manager&#xff09;是 Node.js 的包管理工具&#xff0c;它是一个基于命令行的工具&#xff0c;用于帮助开发者在自己的项目中安装、升级、移除和管理依赖项。 https://www.npmjs.com/ 类似于 PHP 的工具&#xff1a;Composer。它是 …...

Tool Documentation Enables Zero-Shot Tool-Usage with Large Language Models

本文是LLM系列文章的内容&#xff0c;针对《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&#xff0c;意思是点击提交按钮后&#xff0c;就会跳转到user/login地址&#xff0c;然后只要用Controller类的RequsetMapping去接这个地址就行了。 <body class"text-center"><form cl…...

数据结构-栈队列链表树

1 栈 概念 栈是⼀个线性结构&#xff0c;在计算机中是⼀个相当常⻅的数据结构。栈的特点是只能在某⼀端添加或删除数据&#xff0c;遵循先进后出的原则 实现 每种数据结构都可以⽤很多种⽅式来实现&#xff0c;其实可以把栈看成是数组的⼀个⼦集&#xff0c;所以这⾥使⽤数…...

clickhouse功能使用

离线聚合 物化视图 clickhouse需在AggregatingMergeTree之上建立物化视图来完成聚合的效果。以小时聚合为例说明 首先创建表,此处是本地表,且没有副本 #创建表 CREATE TABLE datasets.bt_stats (`btname` String,`record` UInt64,`EventTime` DateTime...

java中使用Jsoup和Itext实现将html转换为PDF

1.在build.gradle中安装所需依赖&#xff1a; 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 )

高精地图是无人驾驶中的重要一环&#xff0c;对环境感知、规划与定位等都有重要的作用。 高精地图的特点&#xff1a; 可视化、静态目标、地图信息、点云数据 高精地图与导航地图的区别 High Definition Map Navigation Map Precision cm m Information 3D lane info Mo…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

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# 如果存在&#xff0…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

在Zenodo下载文件 用到googlecolab googledrive

方法&#xff1a;Figshare/Zenodo上的数据/文件下载不下来&#xff1f;尝试利用Google Colab &#xff1a;https://zhuanlan.zhihu.com/p/1898503078782674027 参考&#xff1a; 通过Colab&谷歌云下载Figshare数据&#xff0c;超级实用&#xff01;&#xff01;&#xff0…...