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就很不好理…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

[大语言模型]在个人电脑上部署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 #:…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...