golang使用ffmpeg的那些坑(整理后)

2023-05-16

因业务需求需要用到golang调用ffmpeg,期间遇到各种曲折离奇的事情,例如服务运行时崩溃,流解析出错等等,还好最终拨开云雾见日出

1、静态编译问题

(1)常规使用

  • go1.11.2版本之前
   go build -ldflags -extldflags=-static
  • go1.11.2

可以直接在声明C或C++代码区域添加-static

//#cgo CFLAGS: -D_REENTRANT
//#cgo LDFLAGS:-static 
//#cgo pkg-config: libavutil
import "C"

(2)go调用ffmpeg

正常情况以上办法就可以编译生成静态可执行文件,但是go调用ffmpeg时就不行了,因为要用到glibc只能进行动态链接,解决办法是修改ffmpeg编译后生成的pkgconfig中的相关*.pc文件。

-Wl,-Bstatic:ffmpeg接口强制静态链接, -Wl,-Bdynamic -lc :glibc强制动态链接 ,将libav-开头的.pc文件改过就好。

Conflicts:
Libs: -L${libdir} -Wl,-Bstatic -lavutil -lm -Wl,-Bdynamic -lc 

注:本人使用过程中发现要先进行动态编译后再进行以上操作才可,原因未明。

2、找到合适的ffmpeg包

本人在原先go-libav包的基础上做了很多改动,不知这个包为什么有那么多star,结果确连example都跑不起来,最后无奈进行了些许改动,例如超时函数的实现,音频数据的处理等。修改后的包看glibav,暂无时间写example,因项目紧任务重,未来得及进行重新架构,本人的项目主要功能是处理各种视频stream生成jpg和wav数据然后发送到kafka,已经上线使用。

3、项目性能调优

在实际应用中发现服务性能与完全用C编写性能差距还是很大的,最后使用多个goroutine勉强达到业务需求。以下列举一些性能调优的常用命令:

1、goTool之pprof的使用
//生成cpu profile
go test -run=^$ -bench=. -cpuprofile=profile.out
//生成memery profile
go test -run=^$ -bench=. -memprofile=profile.out
//使用原生pprof启动Web UI
pprof -http=:8080 profile.out
2、代码优化--goreporter
goreporter -p [projectRelativePath] -r [reportPath] -e [exceptPackagesName] -f [json / html / text] {-t templatePathIfHtml}

问题汇总

获取输入流帧率

videoFPS 即输入流的帧率,下面是在原代码例子上改的,可以参考原示例对照,https://github.com/imkira/go-libav

func (si *SIConf) openInputVideoStream(ctx *avContext) error {
	var err error

	// find first video stream
	if ctx.decStream = videoStream(ctx.decFmt); ctx.decStream == nil {
		logger.Error("Could not find a video stream. Aborting...")
		return fmt.Errorf("Could not find a video stream")
	}

	codecCtx := ctx.decStream.CodecContext()
	codecPar := ctx.decStream.CodecParameters()
	codec := avcodec.FindDecoderByID(codecCtx.CodecID())

	rat := ctx.decFmt.GuessFrameRate(ctx.decStream, nil)

	si.videoFPS = float32(rat.Numerator()) / float32(rat.Denominator())

	if codec == nil {
		logger.Error("Could not find decoder:", codecCtx.CodecID())
	}
	if ctx.decCodec, err = avcodec.NewContextWithCodec(codec); err != nil {
		logger.Error("Failed to create codec context:", err)
	}

	if err := codecCtx.CopyTo(ctx.decCodec, codecPar); err != nil {
		logger.Error("Failed to copy codec context:", err)
	}
	if err := ctx.decCodec.SetInt64Option("refcounted_frames", 1); err != nil {
		logger.Error("Failed to copy codec context:", err)
	}
	//设置多线程
	options := avutil.NewDictionary()
	defer options.Free()
	if err := options.Set("threads", "auto"); err != nil {
		logger.Error("Failed to set input options:", err)
	}
	if err := ctx.decCodec.OpenWithCodec(codec, options); err != nil {
		logger.Error("Failed to open codec:", err)
	}

	//set time base
	ctx.decCodec.SetTimeBase(ctx.decStream.TimeBase())

	// we need a v	log.Println(ctx.decCodec.Width(), ctx.decCodec.Height(), ctx.decCodec.PixelFormat(), ctx.decCodec.TimeBase())ideo filter to push the decoded frames to
	ctx.srcFilter = addFilter(ctx, "buffer", "in")
	if err = ctx.srcFilter.SetImageSizeOption("video_size", ctx.decCodec.Width(), ctx.decCodec.Height()); err != nil {
		logger.Error("Failed to set filter option:", err)
	}
	if err = ctx.srcFilter.SetPixelFormatOption("pix_fmt", ctx.decCodec.PixelFormat()); err != nil {
		logger.Error("Failed to set filter option:", err)
	}
	if err = ctx.srcFilter.SetRationalOption("time_base", ctx.decStream.TimeBase()); err != nil {
		logger.Error("Failed to set filter option:", err)
	}
	//log.Println(ctx.decCodec.Width(), ctx.decCodec.Height(), ctx.decCodec.PixelFormat(), ctx.decStream.TimeBase())

	if err = ctx.srcFilter.Init(); err != nil {
		logger.Error("Failed to initialize buffer filter:", err)
	}
	return nil
}

因厌烦csdn的各种垃圾广告,建了个个人博客站点,欢迎访问:https://robinsea.github.io/post/golang使用ffmpeg的那些坑/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

golang使用ffmpeg的那些坑(整理后) 的相关文章

  • 如何使用 ffmpeg 将两个视频/音频流混合为一个

    我有两个视频 v1 flv 和 v2 flv 想要创建 v3 flv 其中包含来自 v1 flv 的视频流以及来自 v1 flv 和 v2 flv 的 混合 音频流 使用 ffmpeg 命令可以实现类似的操作吗 谢谢 我认为使用 ffmpe
  • 如何仅在使用 ffmpeg 添加相同速度的分离音频流时更改视频速度?

    我正在使用 ffmpeg 作为视频过滤器 但是 当我改变视频速度时 我遇到了问题 音频比视频长 ffmpeg i INPUT mp4 filter v setpts 0 5 PTS shortest y preset ultrafast O
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • Windows 上的 ffmpeg-android ndk

    我正在尝试编译 bash 文件 带有 android ndk 的 ffmpeg 我收到如下错误 arm linux androideabi gcc 无法创建可执行文件 C 编译器测试失败 Makefile 2 config mak 没有这样
  • FFMPEG:使用具有复杂滤波器的视频滤波器

    我正在使用fluent ffmpeg用于对视频文件执行批量操作的 Node js 库 视频过滤器裁剪 16 9 输入 添加填充并将字幕刻录到填充中 在下一步中 我想使用复杂的滤镜来覆盖图像作为水印 ff input video mp4 ff
  • 使用 xuggle 将 mp3 转换为 wav 出现异常

    我正在尝试将 mp3 转换为 wav 代码在这里 String mp3 F work pic2talk38512 mp3 String wav F work pic2talk38512 wav TranscodeAudioAndVideo
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • 如何使用 ffmpeg 设置默认流

    我有一些 m4v 文件 我想用 ffmpeg 添加字幕 我知道我需要映射流以将它们放入输出文件中 但如何确保此字幕流将是默认流 字幕是 srt 人们似乎说它们与 mp4 容器不兼容 我需要先将字幕转换为什么 另外 各种流的顺序重要吗 视频流
  • 如何在 RTMP 流中嵌入 pic_timing SEI 挂钟时间码?

    我需要将我的桌面流式传输到 AWS MediaLive 服务 并且根据要求 我必须在流中包含挂钟时间码 AWS 支持人员善意地通知我 对于 h 264 编码流 我需要提供时间码作为 pic timing SEI 消息 我在 Windows
  • 连接 2 个迷你音频文件并循环播放并添加背景音乐

    我需要用循环连接 2 个小音频文件并在单个命令中添加背景音乐 我能够将两个音频文件与背景音乐连接起来 我上面给出的代码正在运行 ffmpeg i 1 mp3 i 2 mp3 i background mp3 filter complex 0
  • FFMPEG - 具有持续时间过滤器问题的连接解复用器

    我正在尝试使用图像生成视频ffmpeg concat 解复用器 我正在创建一个带有图像文件路径的文本文件 由于图像的持续时间可能不同 我正在使用duration过滤器指定每个图像的持续时间 示例文本文件如下 文件1 jpg 持续时间3 文件
  • 将循环视频添加到声音 ffmpeg

    我开始使用 ffmpeg 这是我的第一个疑问 我有一个声音文件 example mp3 持续时间 1 分钟 我想添加一个循环视频 example mp4 x 秒持续时间 在这种情况下 我想生成 1 分钟的 mp4 视频并循环该视频 3 次
  • 有没有更有效的方法通过ffmpeg批量添加水印和加入视频?

    我有这个批处理文件 使用 ffmpeg 在我的视频中添加徽标 然后添加简介 但需要 10 小时到一天的时间 具体取决于我需要添加水印的数量 是否有更有效的方法来实现此目的 视频有时具有不同的分辨率 因此我无法删除到 1280 720 尺寸的
  • C#中图像制作视频的工作方式

    有人有已知的可靠方法来从一系列图像文件创建视频吗 在你因为我在发布问题之前没有寻找答案而对我进行批评之前 以及在你发出诸如 使用 FFMPEG 之类的简单消息之前 请阅读此消息的其余部分 我正在尝试从一系列图像 jpg bmp 等 创建视频
  • 图像序列到视频质量[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我一直在尝试从一系列图像创建视频 当我使用建议的 ffmpeg 方法时 ffmpeg f image2 i image d jpg video mpg
  • 用于 Windows Phone 开发的 FFmpeg

    我在 ASP Net 基于 Web 的应用程序中使用了 FFmpeg 现在我想用它来进行Windows Phone开发 可以使用吗 如果是 那么如何 Windows Phone 7 根本不支持 FFmpeg 而且据我在网上找到的信息 Win
  • 在 Mac 操作系统上使用 ffmpeg 录制视频

    我想在 mac OS 上使用 ffmpeg 以任何格式录制实时网络摄像头视频 我尝试了很多 但无法找到用于重新编码视频的命令 所以请任何人都可以告诉我 ffmpeg 命令用于使用 Mac 操作系统的网络摄像头捕获视频 提前致谢 对于 Mac
  • FFmpeg 代码无法在用于缩略图提取的 http url 上工作

    我正在尝试从 sharepoint 2013 视频库中提取缩略图 我找到了一个可以使用 ffmpeg 提取的链接 这是链接 如何将视频的第一帧保存为图像 https stackoverflow com questions 3575311 h
  • 推荐用于视频编码的最佳质量/性能 H264 编码器?

    我正在寻找一种速度快 需要较少 CPU 功率并生成质量非常好的 mp4 视频的视频编码器 输入视频可以是任何格式并由用户上传 我唯一知道的是 FFMPEG 库 还有其他更好的吗 该程序必须有一个我感兴趣的批处理实用程序 exe 如果您愿意分
  • 如何在 FFMPEG 中的多个视频之间创建交叉淡入淡出过渡?

    我目前正在通过 FFMPEG 循环播放带有音频的 MP4 视频 这是代码 del intermediate1 ts del f txt echo file intermediate1 ts gt f txt echo file interm

随机推荐