2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。
2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。
答案2023-03-05:
使用 github.com/moonfdd/ffmpeg-go 库。
先启动lal流媒体服务器软件,然后再执行命令:
go run ./examples/leixiaohua1020/simplest_ffmpeg_streamer/main.go
参考了雷霄骅的最简单的基于FFmpeg的推流器(推送RTMP),代码用golang编写。代码如下:
// https://github.com/leixiaohua1020/simplest_ffmpeg_streamer/blob/master/simplest_ffmpeg_streamer/simplest_ffmpeg_streamer.cpp
package mainimport ("fmt""os""os/exec""time""github.com/moonfdd/ffmpeg-go/ffcommon""github.com/moonfdd/ffmpeg-go/libavcodec""github.com/moonfdd/ffmpeg-go/libavformat""github.com/moonfdd/ffmpeg-go/libavutil"
)func main0() (ret ffcommon.FInt) {var ofmt *libavformat.AVOutputFormat//Input AVFormatContext and Output AVFormatContextvar ifmt_ctx, ofmt_ctx *libavformat.AVFormatContextvar pkt libavcodec.AVPacketvar in_filename, out_filename stringvar i ffcommon.FIntvar videoindex ffcommon.FInt = -1var frame_index ffcommon.FInt = 0var start_time ffcommon.FInt64T = 0var err error//in_filename = "cuc_ieschool.mov";//in_filename = "cuc_ieschool.mkv";//in_filename = "cuc_ieschool.ts";//in_filename = "cuc_ieschool.mp4";//in_filename = "cuc_ieschool.h264";in_filename = "./out/cuc_ieschool.flv" //输入URL(Input file URL)//in_filename = "shanghai03_p.h264";_, err = os.Stat(in_filename)if err != nil {if os.IsNotExist(err) {fmt.Println("create flv file")exec.Command("./lib/ffmpeg", "-i", "./resources/big_buck_bunny.mp4", "-vcodec", "copy", "-acodec", "copy", in_filename).Output()}}out_filename = "rtmp://localhost/publishlive/livestream" //输出 URL(Output URL)[RTMP]//out_filename = "rtp://233.233.233.233:6666";//输出 URL(Output URL)[UDP]libavformat.AvRegisterAll()//Networklibavformat.AvformatNetworkInit()//Inputret = libavformat.AvformatOpenInput(&ifmt_ctx, in_filename, nil, nil)if ret < 0 {fmt.Printf("Could not open input file.")goto end}ret = ifmt_ctx.AvformatFindStreamInfo(nil)if ret < 0 {fmt.Printf("Failed to retrieve input stream information")goto end}for i = 0; i < int32(ifmt_ctx.NbStreams); i++ {if ifmt_ctx.GetStream(uint32(i)).Codec.CodecType == libavutil.AVMEDIA_TYPE_VIDEO {videoindex = ibreak}}ifmt_ctx.AvDumpFormat(0, in_filename, 0)//Outputlibavformat.AvformatAllocOutputContext2(&ofmt_ctx, nil, "flv", out_filename) //RTMP//avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpegts", out_filename);//UDPif ofmt_ctx == nil {fmt.Printf("Could not create output context\n")ret = libavutil.AVERROR_UNKNOWNgoto end}ofmt = ofmt_ctx.Oformatfor i = 0; i < int32(ifmt_ctx.NbStreams); i++ {//Create output AVStream according to input AVStreamin_stream := ifmt_ctx.GetStream(uint32(i))out_stream := ofmt_ctx.AvformatNewStream(in_stream.Codec.Codec)if out_stream == nil {fmt.Printf("Failed allocating output stream\n")ret = libavutil.AVERROR_UNKNOWNgoto end}//Copy the settings of AVCodecContextret = libavcodec.AvcodecCopyContext(out_stream.Codec, in_stream.Codec)if ret < 0 {fmt.Printf("Failed to copy context from input to output stream codec context\n")goto end}out_stream.Codec.CodecTag = 0if ofmt_ctx.Oformat.Flags&libavformat.AVFMT_GLOBALHEADER != 0 {out_stream.Codec.Flags |= libavcodec.AV_CODEC_FLAG_GLOBAL_HEADER}}//Dump Format------------------ofmt_ctx.AvDumpFormat(0, out_filename, 1)//Open output URLif ofmt.Flags&libavformat.AVFMT_NOFILE == 0 {ret = libavformat.AvioOpen(&ofmt_ctx.Pb, out_filename, libavformat.AVIO_FLAG_WRITE)if ret < 0 {fmt.Printf("Could not open output URL '%s'", out_filename)goto end}}//Write file headerret = ofmt_ctx.AvformatWriteHeader(nil)if ret < 0 {fmt.Printf("Error occurred when opening output URL\n")goto end}start_time = libavutil.AvGettime()for {var in_stream, out_stream *libavformat.AVStream//Get an AVPacketret = ifmt_ctx.AvReadFrame(&pkt)if ret < 0 {break}//FIX:No PTS (Example: Raw H.264)//Simple Write PTSif pkt.Pts == libavutil.AV_NOPTS_VALUE {//Write PTStime_base1 := ifmt_ctx.GetStream(uint32(videoindex)).TimeBase//Duration between 2 frames (us)calc_duration := int64(libavutil.AV_TIME_BASE / libavutil.AvQ2d(ifmt_ctx.GetStream(uint32(videoindex)).RFrameRate))//Parameterspkt.Pts = int64(float64(frame_index) * float64(calc_duration) / (libavutil.AvQ2d(time_base1) * libavutil.AV_TIME_BASE))pkt.Dts = pkt.Ptspkt.Duration = int64(float64(calc_duration) / (libavutil.AvQ2d(time_base1) * libavutil.AV_TIME_BASE))}//Important:Delayif pkt.StreamIndex == uint32(videoindex) {time_base := ifmt_ctx.GetStream(uint32(videoindex)).TimeBasetime_base_q := libavutil.AVRational{1, libavutil.AV_TIME_BASE}pts_time := libavutil.AvRescaleQ(pkt.Dts, time_base, time_base_q)now_time := libavutil.AvGettime() - start_timeif pts_time > now_time {libavutil.AvUsleep(uint32(pts_time - now_time))}}in_stream = ifmt_ctx.GetStream(pkt.StreamIndex)out_stream = ofmt_ctx.GetStream(pkt.StreamIndex)/* copy packet *///Convert PTS/DTSpkt.Pts = libavutil.AvRescaleQRnd(pkt.Pts, in_stream.TimeBase, out_stream.TimeBase, libavutil.AV_ROUND_NEAR_INF|libavutil.AV_ROUND_PASS_MINMAX)pkt.Dts = libavutil.AvRescaleQRnd(pkt.Dts, in_stream.TimeBase, out_stream.TimeBase, libavutil.AV_ROUND_NEAR_INF|libavutil.AV_ROUND_PASS_MINMAX)pkt.Duration = libavutil.AvRescaleQ(pkt.Duration, in_stream.TimeBase, out_stream.TimeBase)pkt.Pos = -1//Print to Screenif pkt.StreamIndex == uint32(videoindex) {fmt.Printf("Send %8d video frames to output URL\n", frame_index)frame_index++}//ret = av_write_frame(ofmt_ctx, &pkt);ret = ofmt_ctx.AvInterleavedWriteFrame(&pkt)if ret < 0 {fmt.Printf("Error muxing packet\n")break}pkt.AvFreePacket()}//Write file trailerofmt_ctx.AvWriteTrailer()
end:libavformat.AvformatCloseInput(&ifmt_ctx)/* close output */if ofmt_ctx != nil && ofmt.Flags&libavformat.AVFMT_NOFILE == 0 {ofmt_ctx.Pb.AvioClose()}ofmt_ctx.AvformatFreeContext()if ret < 0 && ret != libavutil.AVERROR_EOF {fmt.Printf("Error occurred.\n")return -1}return 0
}func main() {os.Setenv("Path", os.Getenv("Path")+";./lib")ffcommon.SetAvutilPath("./lib/avutil-56.dll")ffcommon.SetAvcodecPath("./lib/avcodec-58.dll")ffcommon.SetAvdevicePath("./lib/avdevice-58.dll")ffcommon.SetAvfilterPath("./lib/avfilter-56.dll")ffcommon.SetAvformatPath("./lib/avformat-58.dll")ffcommon.SetAvpostprocPath("./lib/postproc-55.dll")ffcommon.SetAvswresamplePath("./lib/swresample-3.dll")ffcommon.SetAvswscalePath("./lib/swscale-5.dll")genDir := "./out"_, err := os.Stat(genDir)if err != nil {if os.IsNotExist(err) {os.Mkdir(genDir, 0777) // Everyone can read write and execute}}go func() {time.Sleep(1000)exec.Command("./lib/ffplay.exe", "rtmp://localhost/publishlive/livestream").Output()if err != nil {fmt.Println("play err = ", err)}}()main0()
}

相关文章:
2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。
2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。 答案2023-03-05: 使用 github.com/moonfdd/ffmpeg-go 库。 先启动lal流媒体服务器软件,然后再执行命令: go…...
MathType7最新版免费数学公式编辑器
话说我也算是 MathType准资深(DB)用户了,当然自从感觉用DB不好之后,我基本上已经抛弃它了,只是前不久因为个别原因又捡起来用了用,30天试用期间又比较深入的折腾了下,也算是变成半个MathType砖家,coco玛奇朵简单介绍一下这款软件:在很可能看到这儿的你还没有出生的某个年月&…...
一文带你入门angular(中)
一、angular中的dom操作原生和ViewChild两种方式以及css3动画 1.原生操作 import { Component } from angular/core;Component({selector: app-footer,templateUrl: ./footer.component.html,styleUrls: [./footer.component.scss] }) export class FooterComponent {flag: b…...
单例设计模式共享数据问题分析、解决(c++11)设计多线程。
系列文章目录 单例设计模式共享数据问题分析、解决; 文章目录系列文章目录前言一、单例模式1.1 基本概念1.2 单例设计模式共享数据问题分析、解决1.3 std::call_once()介绍二、代码案例1.代码示例总结前言 关键内容:c11、多线程、共享数据、单例类 本章内容参考git…...
Embedding-based Retrieval in Facebook Search
facebook的社交网络检索与传统的搜索检索的差异是,除了考虑文本,还要考虑搜索者的背景。通用搜索主要考虑的是文本匹配,并没有涉及到个性化。像淘宝,youtube这些其实都是涉及到了用户自身行为的,除了搜索还有推荐&…...
xmu 离散数学 卢杨班作业详解【8-12章】
文章目录第八章 树23456810第九章46811第十章24567第十一章14571116第十二章131317第八章 树 2 (2) 设有k片树叶 2∗m2∗43∗3k2*m2*43*3k2∗m2∗43∗3k n23kn23kn23k mn−1mn-1mn−1 联立解得k9 T中有9片树叶 3 有三颗非同构的生成树 4 (1) c --abc e–abed f–dgf…...
Linux入门篇-权限管理
简介 用户管理也是和权限相关的知识点。权限的作用 权限对于普通文件和目录文件作用是不一样的 。[kioskfoundation0 ~]$ ls -l total 264 -rw-rw-r--. 2 kiosk kiosk 31943 May 29 2019 ClassPrep.txt -rw-rw-r--. 2 kiosk kiosk 7605 Jun 14 2019 ClassRHAPrep.txt -rw-rw-r…...
Linux(基于 Centos7) 常用操作
1.Linux 简介Linux 是一种 免费使用、自由传播的类 Unix 操作系统Linux操作系统内核,由林纳斯托瓦兹在1991年10月5日首次发布...Linux 是一套开源操作系统,它有稳定、消耗资源小、安全性高等特点大多数人都是直接使用 Linux 发行版(就是将 Li…...
Math类详解与Random类、三种随机数生成方式(java)
文章目录📖前言:🎀认识Random类🎀三种随机数生成方式🎀Math类的用途🎀Math类的方法📖前言: 本篇博客主要以介绍Math类的常用方法及认识Random类,及三种随机数生成方式 …...
Mac编译QT程序出现Undefined symbols for architecture x86_64
在Mac编写日志服务类, Logging_d.h内容如下 #pragma once #include <QLoggingCategory> Q_DECLARE_LOGGING_CATEGORY(hovering) Q_DECLARE_LOGGING_CATEGORY(creation) Q_DECLARE_LOGGING_CATEGORY(mouseevents) Q_DECLARE_LOGGING_CATEGORY(state) Q_DECLARE_LOGGING_C…...
蓝桥杯-李白打酒加强版
蓝桥杯-李白打酒加强版1、问题描述2、解题思路3、代码实现1、问题描述 话说大诗人李白, 一生好饮。幸好他从不开车。 一天, 他提着酒显, 从家里出来, 酒显中有酒 2 斗。他边走边唱: 无事街上走,提显去打酒。 逢店加一倍, 遇花喝一斗。 这一路上, 他一共遇到店 N 次…...
AtCoder Beginner Contest 292 (A - E) 记录第一场ABC
AtCoder Beginner Contest 292 A - E前言Q1 A - CAPS LOCKQ2 Yellow and Red CardQ3 Four VariablesQ4 D - Unicyclic ComponentsQ5 E - Transitivity前言 本来晚上在打Acwing周赛,最后一题Trie想不出来咋写,看群里有人说ABC要开始了,想着没…...
ubuntu安装使用putty
一、安装 安装虚拟机串口 sudo apt-get install putty sudo apt install -y setserial 二、使用 虚拟机连接串口 sudo setserial -g /dev/ttyS* 查看硬件对应串口 找到不是unknown的串口 sudo putty...
【CS144】Lab5与Lab6总结
Lab5与Lab6Lab汇总Lab5概述Lab6概述由于Lab5和Lab6相对比较简单(跟着文档一步一步写就行),于是放在一起做一个简单概述(主要是懒得写了…) Lab汇总 Lab5概述 lab5要求实现一个IP与Ethernet(以太网&#x…...
GDScript 导出变量 (Godot4.0)
概述 导出变量的功能在3.x版本中也是有的,但是4.0版本对其进行了语法上的改进。 导出变量在日常的游戏制作中提供节点的自定义参数化调节功能时非常有用,除此之外还用于自定义资源。 本文是(Bilibili巽星石)在4.0官方文档《GDScr…...
shell:#!/usr/bin/env python作用是什么
我们经常会在别人的脚本文件里看到第一行是下面这样 #!/usr/bin/python或者 #!/usr/bin/env python 那么他们有什么用呢? 要理解它,得把这一行语句拆成两部分。 第一部分是 #! 第二部分是 /usr/bin/python 或者 /usr/bin/env python 关于 #! 这个…...
计算机行业AIGC算力时代系列报告-ChatGPT芯片算力:研究框架
报告下载: 计算机行业AIGC算力时代系列报告-ChatGPT芯片算力:研究框架 简介 “AI算力时代已经来临,计算机行业正在经历着一场前所未有的变革!” 这是一个充满活力和兴奋的时代,人工智能(AI)已…...
『MyBatis技术内幕』源码调试前提
准备源代码包 下载源代码 3.4.6 版本 https://github.com/mybatis/mybatis-3/releases?page2 通过 idea 导入然后回自动下载所有依赖,根据 3.4.6 版本的 pom.xml 找到依赖的 mybatis-parent 版本 <parent><groupId>org.mybatis</groupId><ar…...
# Linux最新2022年面试题大汇总,附答案
# Linux最新2022年面试题大汇总,附答案 ### [1、cp(copy单词缩写,复制功能)](最新2021年面试题大汇总,附答案.md#1cpcopy单词缩写复制功能) cp /opt/java/java.log /opt/logs/ ;把java.log 复制到/opt/logs/下 cp /…...
css中重难点整理
一、vertical-align 在学习vertical-align的时候,可能会很困惑。即使网上有一大推文章讲veitical-align,感觉看完好像懂了,等自己布局的时候用到vertical-align的时候好像对它又很陌生。这就是我在布局的时候遇到的问题。 本来vertical-align就很不好理…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
