在 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 的封装,可以更方便地将其集成到自己的项目中,提升开发效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/64840.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cesium 常见的 entity 列表

Cesium 是一个用于创建3D地球和地图的开源JavaScript库。它允许开发者在Web浏览器中展示地理空间数据,并且支持多种类型的空间实体(entities)。 Entities是Cesium中用于表示地面上或空中的对象的一种高层次、易于使用的接口。它们可以用来表示点、线、多边形、模型等,并且可…

在Visual Studio 2022中配置C++计算机视觉库Opencv

本文主要介绍下载OpenCV库以及在Visual Studio 2022中配置、编译C计算机视觉库OpenCv的方法 1.Opencv库安装 ​ 首先&#xff0c;我们需要安装OpenCV库&#xff0c;作为一个开源库&#xff0c;我们可以直接在其官网下载Releases - OpenCV&#xff0c;如果官网下载过慢&#x…

【Java基础面试题035】什么是Java泛型的上下界限定符?

回答重点 Java泛型的上下界限定符用于对泛型类型参数进行范围限制&#xff0c;主要有上界限定符和下届限定符。 1&#xff09;上界限定符 (? extends T)&#xff1a; 定义&#xff1a;通配符?的类型必须是T或者T的子类&#xff0c;保证集合元素一定是T或者T的子类作用&…

WPF+MVVM案例实战与特效(四十七)-实现一个路径绘图的自定义按钮控件

文章目录 1、案例效果2、创建自定义 PathButton 控件1、定义 PathButton 类2、设计样式与控件模板3、代码解释3、控件使用4、直接在 XAML 中绑定命令3、源代码获取4、总结1、案例效果 2、创建自定义 PathButton 控件 1、定义 PathButton 类 首先,我们需要创建一个新的类 Pat…

共模电感的工作原理

共模电感也称为共模扼流线圈&#xff0c;是一种抑制共模干扰的器件&#xff0c;它是由两个尺寸相同&#xff0c;匝数相同的线圈对称地绕制在同一个铁氧体环形磁芯上&#xff0c;形成的一个四端器件。当共模电流流过共模电感时&#xff0c;磁芯上的两个线圈产生的磁通相互叠加&a…

外连接转AntiJoin的应用场景与限制条件 | OceanBase SQL 查询改写系列

在《SQL 改写系列&#xff1a;外连接转内连接的常见场景与错误》一文中&#xff0c;我们了解到谓词条件可以过滤掉连接结果中的 null 情形的&#xff0c;将外连接转化为内连接的做法是可行的&#xff0c;正如图1中路径(a)所示。此时&#xff0c;敏锐的你或许会进一步思考&#…

二、windows环境下vscode使用wsl教程

本篇文件介绍了在windows系统使用vscode如何连接使用wsl&#xff0c;方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode&#xff0c;按快捷键CtrlShiftX打开插件市场&#xff0c;搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…

因子问题(真EASY)

描述 任给两个正整数N、M&#xff0c;求一个最小的正整数a&#xff0c;使得a和(M-a)都是N的因子。 输入描述 包括两个整数N、M。N不超过1,000,000。 输出描述 输出一个整数a&#xff0c;表示结果。如果某个案例中满足条件的正整数不存在&#xff0c;则在对应行输出-1 用例…

2024 高频 Java 面试合集整理 (1000 道附答案解析)

2024 年马上就快要过去了&#xff0c;总结了上半年各类 Java 面试题&#xff0c;初中级和中高级都有&#xff0c;包括 Java 基础&#xff0c;JVM 知识面试题库&#xff0c;开源框架面试题库&#xff0c;操作系统面试题库&#xff0c;多线程面试题库&#xff0c;Tcp 面试题库&am…

(2024.12)Ubuntu20.04安装openMVS<成功>.colmap<成功>和openMVG<失败>记录

一、安装openMVS 官方文档&#xff1a;https://github.com/cdcseacave/openMVS/wiki/Building sudo apt-get -y install git mercurial cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev eigen git clone https://gitlab.com/libeigen/eigen --branch 3.4 mkdi…

自动控制系统综合与LabVIEW实现

自动控制系统综合是为了优化系统性能&#xff0c;确保其可靠性、稳定性和灵活性。常用方法包括动态性能优化、稳态误差分析、鲁棒性设计等。结合LabVIEW&#xff0c;可以通过图形化编程、高效数据采集与处理来实现系统综合。本文将阐述具体方法&#xff0c;并结合硬件选型提供实…

【恶意软件检测】一种基于API语义提取的Android恶意软件检测方法(期刊等级:CCF-B、Q2)

一种基于API语义提取的Android恶意软件检测方法 A novel Android malware detection method with API semantics extraction 摘要 由于Android框架和恶意软件的持续演变&#xff0c;使用过时应用程序训练的传统恶意软件检测方法在有效识别复杂演化的恶意软件方面已显不足。为…

FLTK - build fltk-1.1.10 on vs2019

文章目录 FLTK - build fltk-1.1.10 on vs2019概述笔记buildtest测试程序运行 END FLTK - build fltk-1.1.10 on vs2019 概述 看书上用到了fltk-1.1.10, 用vs2019试试能否正常编译使用? 笔记 build 从官网下载fltk-1.1.10-source.tar.bz2 用7zip解开 fltk-1.1.10-source.…

业财融合,决策有据:工程项目管理的财务新视角

在工程项目管理领域&#xff0c;业财融合正开启全新篇章。传统模式下&#xff0c;业务与财务各自为政&#xff0c;常导致信息滞后、决策盲目。如今&#xff0c;借助先进理念与技术&#xff0c;二者紧密相连。 在项目规划阶段&#xff0c;财务部门依据业务需求与市场趋势&#…

汽车IVI中控开发入门及进阶(44):杰发科智能座舱芯片

概述: 杰发科技自成立以来,一直专注于汽车电子芯片及相关系统的研发与设计。 产品布局: 合作伙伴: 杰发科技不断提升产品设计能力和产品工艺,确保产品达 到更高的质量标准。目前杰发科技已通过ISO9001质 量管理体系与CMMIL3认证。 杰发科技长期合作的供应商(芯片代工厂、…

算法专题——双指针

目录 前言 1、移动0 2、复写零 3、快乐数 4、盛最多水的容器 5、有效三⻆形的个数 6、和为s的两个数字 7、三数之和 8、四数之和 前言 本文主要介绍一些用到双指针的常见算法题。 1、移动0 链接&#xff1a;https://leetcode.cn/problems/move-zeroes/description/…

人工智能与云计算的结合:如何释放数据的无限潜力?

引言&#xff1a;数据时代的契机 在当今数字化社会&#xff0c;数据已成为推动经济与技术发展的核心资源&#xff0c;被誉为“21世纪的石油”。从个人消费行为到企业运营决策&#xff0c;再到城市管理与国家治理&#xff0c;每个环节都在生成和积累海量数据。然而&#xff0c;数…

【Chrome Extension】一、CSDN计时扩展设计

【Chrome Extension】一、CSDN计时扩展设计 重点内容内容脚本 content_scripts 文件目录1、整体目录2、manifest.json3、scripts/content.js4、css/content.css 重点内容 内容脚本 content_scripts 1、manifest.json文件配置 {"manifest_version": 3, # *依赖Chro…

javaEE-线程的常用方法-4

目录 一.start():启动一个线程 调用start()方法 start()方法只能调用一次&#xff1a; java中的API: start()和run()的区别: 二.中断一个线程 中断线程方法1:引入标志位 中断线程方法2:调⽤interrupt()⽅法 抛出的异常: 三.等待一个线程 join() 四、获取线程引用 五…

AI的进阶之路:从机器学习到深度学习的演变(四)

AI的进阶之路&#xff1a;从机器学习到深度学习的演变&#xff08;三&#xff09; 五、深度学习的应用领域 深度学习的应用领域广泛&#xff0c;涵盖了计算机视觉、自然语言处理、语音识别和推荐系统等多个方面。以下将详细探讨这些关键应用领域&#xff0c;展示深度学习在不同…