在 Go 中利用 ffmpeg 进行视频和音频处理
在 Go 中利用 ffmpeg 进行视频和音频处理
- ffmpegutil 包概述
- 主要功能介绍
- 1. 视频格式转换
- 2. 提取音频
- 3. 获取视频信息
- 4. 创建视频缩略图
- 5. 提取随机帧
- 无线程版本:
- 多线程版本:
- 总结
ffmpeg 是一款功能强大的多媒体处理工具,支持视频和音频的编码、解码、转码,以及帧提取和流处理等功能。它已经成为开发人员处理多媒体内容的首选工具。在本文中,我们将通过一个 Go 封装包 ffmpegutil 来展示如何与 ffmpeg 进行交互,从而简化视频和音频的处理。
我们将介绍一些常见的使用场景,如视频格式转换、音频提取、缩略图创建和帧提取,并探讨如何高效地在 Go 中与 ffmpeg 进行交互。
ffmpegutil 包概述
ffmpegutil 包旨在封装常见的 ffmpeg 操作,为 Go 提供更简洁易用的接口。它包含了以下几个功能:
- 视频格式转换
- 从视频中提取音频
- 获取视频信息和元数据
- 创建视频缩略图
- 在随机时间戳提取帧
该包依赖于 ffmpeg-go 这一 Go 语言的 ffmpeg 封装库,使得 ffmpeg 的功能能够更方便地集成到 Go 项目中。
主要功能介绍
1. 视频格式转换
视频格式转换是 ffmpeg 最常见的应用之一。在 ffmpegutil 中,ConvertVideo 函数通过简单的接口调用,可以将输入的视频文件转换成指定格式。
// ConvertVideo 将视频从一种格式转换为另一种格式
func ConvertVideo(inputFile, outputFile string, key, value string) error {err := ffmpeg.Input(inputFile).Output(outputFile, ffmpeg.KwArgs{key: value}).OverWriteOutput().ErrorToStdOut().Run()if err != nil {return fmt.Errorf("error converting video: %w", err)}log.Debugf("Video conversion complete: %s -> %s", inputFile, outputFile)return nil
}
通过 ffmpeg.Input(inputFile).Output(outputFile, ffmpeg.KwArgs{key: value}),可以设置输入输出文件路径和转换参数。ffmpeg-go 会自动处理转换过程。
2. 提取音频
从视频中提取音频是常见的需求,尤其是在处理视频文件时。ExtractAudio 函数使用 ffmpeg 来实现这一操作。
// ExtractAudio 从视频文件中提取音频
func ExtractAudio(inputFile, outputFile string) error {err := ffmpeg.Input(inputFile).Output(outputFile, ffmpeg.KwArgs{"vn": ""}).Run()if err != nil {return fmt.Errorf("error extracting audio: %w", err)}log.Debugf("Audio extraction complete: %s -> %s", inputFile, outputFile)return nil
}
在 ffmpeg.KwArgs{“vn”: “”} 中,vn 参数表示不处理视频流,仅提取音频流。
3. 获取视频信息
获取视频的基本信息是另一个常见操作。在 ffmpegutil 中,GetVideoInfo 函数通过 ffmpeg.Probe 来获取视频的详细信息。
// GetVideoInfo 获取视频文件的基本信息
func GetVideoInfo(inputFile string) (string, error) {probeData, err := ffmpeg.Probe(inputFile)if err != nil {return "", fmt.Errorf("error getting video info: %w", err)}log.Debugf("Video Info: %v", probeData)return probeData, nil
}
ffmpeg.Probe 返回的视频文件元数据包含格式、时长、码率等信息,可以用于后续的处理。
4. 创建视频缩略图
视频缩略图的生成是视频处理中的常见需求,特别是在多媒体平台上展示视频时。CreateThumbnail 函数从视频中提取一帧作为缩略图。
// CreateThumbnail 为视频创建缩略图
func CreateThumbnail(inputFile, outputFile string) error {err := ffmpeg.Input(inputFile).Output(outputFile, ffmpeg.KwArgs{"vframes": "1", "vf": "scale=800:600"}).Run()if err != nil {return fmt.Errorf("error creating thumbnail: %w", err)}log.Debugf("Thumbnail created: %s -> %s", inputFile, outputFile)return nil
}
该函数通过设置 vframes=1 来提取视频的第一帧,并通过 scale=800:600 来调整缩略图的尺寸。
5. 提取随机帧
提取视频中的随机帧是一个高级操作,通常用于视频分析或生成视频预览图。在 ffmpegutil 中,有两个版本的 ExtractRandomFrames 函数,一个是单线程版本,另一个是多线程版本。
无线程版本:
// ExtractRandomFramesNoThread 提取视频中的随机帧(无线程)
func ExtractRandomFramesNoThread(inputFile, outputDir, filePrefix string, numFrames int) error {// 确保输出目录存在err := os.MkdirAll(outputDir, os.ModePerm)if err != nil {return fmt.Errorf("failed to create output directory: %w", err)}format, err := GetVideoFormat(inputFile)if err != nil {return fmt.Errorf("error getting video format: %w", err)}duration, err := strconv.ParseFloat(format.Format.Duration, 64)if err != nil {return fmt.Errorf("error parsing duration: %w", err)}randSource := rand.NewSource(time.Now().UnixNano())randGen := rand.New(randSource)timestamps := generateRandomTimestamps(duration, numFrames, randGen)for i, timestamp := range timestamps {outputFile := filepath.Join(outputDir, fmt.Sprintf("%s_%03d.jpg", filePrefix, i+1))err := extractFrameAtTimestamp(inputFile, outputFile, timestamp)if err != nil {log.Errorf("Error extracting frame: %v", err)} else {log.Tracef("Frame extracted: %s -> %s", inputFile, outputFile)}}return nil
}
多线程版本:
// ExtractRandomFrames 提取视频中的随机帧(多线程)
func ExtractRandomFrames(inputFile, outputDir, filePrefix string, numFrames, numThreads int) error {// 确保输出目录存在err := os.MkdirAll(outputDir, os.ModePerm)if err != nil {return fmt.Errorf("failed to create output directory: %w", err)}format, err := GetVideoFormat(inputFile)if err != nil {return fmt.Errorf("error getting video format: %w", err)}duration, err := strconv.ParseFloat(format.Format.Duration, 64)if err != nil {return fmt.Errorf("error parsing duration: %w", err)}randSource := rand.NewSource(time.Now().UnixNano())randGen := rand.New(randSource)timestamps := generateRandomTimestamps(duration, numFrames, randGen)var wg sync.WaitGroupsem := make(chan struct{}, numThreads)for i, timestamp := range timestamps {wg.Add(1)go func(index int, ts float64) {defer wg.Done()sem <- struct{}{} // acquire semaphoreoutputFile := filepath.Join(outputDir, fmt.Sprintf("%s_%03d.jpg", filePrefix, index+1))err := extractFrameAtTimestamp(inputFile, outputFile, ts)if err != nil {log.Errorf("Error extracting frame: %v", err)} else {log.Tracef("Frame extracted: %s -> %s", inputFile, outputFile)}<-sem // release semaphore}(i, timestamp)}wg.Wait()return nil
}
总结
通过 ffmpegutil 包,Go 开发者可以轻松实现视频和音频的常见处理任务,如格式转换、音频提取、缩略图生成和随机帧提取。利用 ffmpeg-go 封装库,结合 Go 的并发特性,可以高效地处理大量视频数据,满足复杂的多媒体处理需求。
无论是用于视频分析、音频处理,还是为视频平台生成缩略图,ffmpeg 都是一款必不可少的工具。而通过 Go 对 ffmpeg 的封装,可以更方便地将其集成到自己的项目中,提升开发效率。
相关文章:

在 Go 中利用 ffmpeg 进行视频和音频处理
在 Go 中利用 ffmpeg 进行视频和音频处理 ffmpegutil 包概述主要功能介绍1. 视频格式转换2. 提取音频3. 获取视频信息4. 创建视频缩略图5. 提取随机帧无线程版本:多线程版本: 总结 ffmpeg 是一款功能强大的多媒体处理工具,支持视频和音频的编…...

【机器学习】探索机器学习与人工智能:驱动未来创新的关键技术
探索机器学习与人工智能:驱动未来创新的关键技术 前言:人工智能的核心技术深度学习:自然语言处理(NLP):计算机视觉: 机器学习与人工智能的驱动创新医疗健康领域金融行业智能制造与工业互联网智慧…...

React Refs 完整使用指南
React Refs 完整使用指南 1. Refs 基础用法 1.1 创建和访问 Refs // 类组件中使用 createRef class MyComponent extends React.Component {constructor(props) {super(props);this.myRef React.createRef();}componentDidMount() {// 访问 DOM 节点console.log(this.myRef…...

程控电阻箱应用中需要注意哪些安全事项?
程控电阻箱是一种用于精确控制电路中电流和电压的电子元件,广泛应用于电子实验、测试设备以及精密测量仪器中。在应用程控电阻箱时,为确保安全和设备的正常运行,需要注意以下几个安全事项: 1. 正确连接:确保电阻箱与电…...

C/C++基础知识复习(43)
1) 什么是运算符重载?如何在 C 中进行运算符重载? 运算符重载是指在 C 中为现有的运算符定义新的行为,使得它们能够用于用户定义的数据类型(如类或结构体)。通过运算符重载,可以让自定义类型像内置数据类型…...

苍穹外卖-day05redis 缓存的学习
苍穹外卖-day05 课程内容 Redis入门Redis数据类型Redis常用命令在Java中操作Redis店铺营业状态设置 学习目标 了解Redis的作用和安装过程 掌握Redis常用的数据类型 掌握Redis常用命令的使用 能够使用Spring Data Redis相关API操作Redis 能够开发店铺营业状态功能代码 功能实…...

VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
名人说:一点浩然气,千里快哉风。—— 苏轼《水调歌头》 创作者:Code_流苏(CSDN) 目录 一、Java开发环境搭建二、VScode下载及安装三、VSCode配置Java环境四、运行测试五、背景图设置 很高兴你打开了这篇博客,更多详细的安装教程&…...

PHP MySQL 插入多条数据
PHP MySQL 插入多条数据 在Web开发中,PHP和MySQL的组合是非常常见的。PHP是一种服务器端脚本语言,而MySQL是一种流行的数据库管理系统。在许多情况下,我们可能需要一次性向MySQL数据库插入多条数据。这可以通过几种不同的方法实现࿰…...

Oracle安装报错:将配置数据上载到资料档案库时出错
环境:联想服务器 windows2022安装Oracle11g 结论:禁用多余网卡先试试,谢谢。 以下是问题描述和处理过程: 网上处理方式: hosts文件添加如下: 关闭防火墙 暂时无法测试通过。 发现ping不是本地状态,而是…...

JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
目录 JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码) 一、为什么要使用Array.sort() 二、Array.sort() 的使用与技巧 1、基础语法 2、返回值 3、…...

Deformable DETR:Deformable Transformers for End-to-End Object Detection论文学习
1. 为什么提出了Deformable DETR? 因为DETR本身的计算量大,收敛速度慢。其次是小目标检测效果差。主要原因是Attention模块每次只关注一小部分采样点,导致需要很多轮数才能学习到真实需要关注的目标。 Deformable DETR注意力模块只关注一个…...

机器学习-43-可解释性机器学习库LIME
文章目录 1 LIME1.1 LIME的特点1.2 LIME的步骤2 应用LIME2.1 分类模型2.1.1 创建模型和解释器2.1.2 解释样本2.2 回归模型2.2.1 创建模型和解释器2.2.2 解释样本2.3 文本模型2.3.1 创建模型和解释器2.3.2 解释样本2.4 图像模型2.4.1 创建模型和解释器2.4.2 解释样本3 附录3.1 l…...

【Unity功能集】TextureShop纹理工坊(五)选区
项目源码:在终章发布 索引 选区PS选区选区功能点提炼 TextureShop选区方形区域中间镂空边框的流动虚线SelectedRegion类选择选区更新选区 选区 选区,也既是在当前选中图层中,已选择的编辑区域,我们后续的所有图像编辑操作&#x…...

Spring Cloud OpenFeign快速入门demo
一、应用场景 Spring Cloud OpenFeign 是一个声明式的 HTTP 客户端,旨在简化微服务之间的通信。它使得开发者能够通过简单的接口定义和注解来调用 RESTful API,极大地减少了样板代码。以下是一些典型的应用场景: 微服务间调用:在…...

研发效能DevOps: Vite 使用 Element Plus
目录 一、实验 1.环境 2.初始化前端项目 3.安装 vue-route 4.安装 pinia 5.安装 axios 6.安装 Element Plus 7.gitee创建工程 8. 配置路由映射 9.Vite 使用 Element Plus 二、问题 1.README.md 文档推送到gitee未自动换行 2.访问login页面显示空白 3.表单输入账户…...

sfnt-pingpong -测试网络性能和延迟的工具
sfnt-pingpong 是一个用于测试网络性能和延迟的工具,通常用于测量不同网络环境下的数据包传输性能、吞吐量、延迟等指标。 它通常是基于某种网络协议(如 TCP)执行“ping-pong”式的测试,即客户端和服务器之间相互发送数据包&…...

Kubernetes、Docker 和 Docker Registry 关系是是什么?
Kubernetes(常简称为 k8s)、Docker 和 Docker Registry 是现代云原生应用中三个关键的组件,它们各自承担不同的职责,但在容器化部署和管理过程中紧密协作。以下是它们之间关系的详细解释: 一、核心概念简介 1. Docker…...

docker部署微信小程序自动构建发布和更新
通过 Jenkins 和 Docker 部署微信小程序,并实现自动构建、发布和版本更新,主要涉及以下几个步骤: 设置 Jenkins 环境配置 GitLab 与 Jenkins 的集成构建 Docker 镜像部署和发布微信小程序配置 Jenkins 自动构建 以下是详细的步骤说明&#…...

模仿elementui的Table,实现思路
vue2子组件使用render,给子子组件插槽传值 和elementui的Table一样使用render 在 Vue 2 中,子组件使用render函数向子子组件插槽传值可以通过以下步骤实现: 1、创建子组件 首先创建一个子组件,在子组件中使用render函数来渲染内容…...

Unity中使用环形缓冲区平滑抖动值
环形缓冲数据结构,就是如下图一样的一个收尾相接的列表 在index指针指到4时,再往里添加数据,index就会指向0,并覆盖已有数据。 如何绘制Sin函数,请看下面一篇文章 Unity中如何实现绘制Sin函数图像-CSDN博客 接下来要…...

【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
文章目录 前言问题描述问题分析问题解决1.允许所有用户上传驱动文件2.如果是想只上传白名单的驱动 前言 该方法适合永洪BI系列产品,包括不限于vividime desktop,vividime z-suit,vividime x-suit产品。 问题描述 当我们连接数据源的时候&a…...

SpringBoot使用 AOP 实现自定义日志记录并保存在Mysql
本文主要介绍在 Spring Boot 中使用 AOP 实现自定义日志记录并保存在 Mysql 的方法。先阐述记录日志的重要性及传统方式的弊端,提出新方式,即通过创建自定义注解、切面类等,将重要日志存到数据库,还给出了创建日志表、注解类、切面…...

谷歌开源最强天气预报AI模型 GenCast
谷歌 DeepMind 开源新一代天气预测 AI 模型 GenCast,GenCast 以最先进的精度预测天气和极端条件的风险 天气预报对人们生活和决策至关重要,但传统 NWP 模型存在不确定性,且计算资源需求大、运行慢。机器学习在天气预报中虽有进展,…...

C++打造局域网聊天室第十课: 客户端编程及数据发送
文章目录 前言一、补充内容,设置显示框换行二、客户端编程三、封装消息发送函数四、所处的身份状态总结 前言 C打造局域网聊天室第十课: 客户端编程及数据发送 一、补充内容,设置显示框换行 编辑框的显示内容默认是不会换行的,这…...

Nginx整合Lua脚本
Nginx-Lua Nginx整合Lua脚本 Lua环境搭建 下载地址 linux环境下 yum install lua安装后验证 lua -vLua脚本执行 lua xxx.luaNginx整合Lua nginx需要添加lua模块 嵌入内容 示例如下 修改nginx.conf如下 location /lua {default_type text/plain;content_by_lua ngx.sa…...

【C++】C++11 STL容器emplace方法原理剖析
在 C 11 STL 容器中,push/insert > emplace 新的方法,push 和 emplace 的区别在于: 1. push push 通常用于将一个元素添加到容器的末尾(在 std::vector、std::deque 等序列容器中),或者在关联容器中插入…...

QT-简单视觉框架代码
文章目录 简介1. 整体架构2. 关键类功能概述3. 详细代码实现hikcameraworker.h 和 hikcameraworker.cpp(海康相机工作线程类)imageviewerwidget.h 和 imageviewerwidget.cpp(图像查看部件类)构造函数 ImageViewerWidget析构函数 ~…...

AI新书推荐:深度学习和大模型原理与实践(清华社)
本书简介 在这个信息爆炸、技术革新日新月异的时代,深度学习作为人工智能领域的重要分支,正引领着新一轮的技术革命。《深度学习和大模型原理与实践》一书,旨在为读者提供深度学习及其大模型技术的全面知识和实践应用的指南。 本书特色在于…...

[spring]处理器
我们可以通过spring来管理我们的类,之后我们可以通过spring的容器来获取我们所需要的Bean类对象。Spring的处理器是Spring对外开发的重要扩展点,它允许我们介入到Bean的整个实例化流程中来,可以动态添加、修改BeanDefinition、动态修改Bean 首…...

重温设计模式--中介者模式
中介者模式介绍 定义:中介者模式是一种行为设计模式,它通过引入一个中介者对象来封装一系列对象之间的交互。中介者使得各个对象之间不需要显式地相互引用,从而降低了它们之间的耦合度,并且可以更方便地对它们的交互进行管理和协调…...