当前位置: 首页 > news >正文

2023-04-06:拥抱Golang,优化FFmpeg音频编码器,探究encode_audio.c的内部结构。

2023-04-06:拥抱Golang,优化FFmpeg音频编码器,探究encode_audio.c的内部结构。

答案2023-04-06:

见moonfdd/ffmpeg-go库。

这段代码是一个示例程序,用于将音频 PCM 数据编码为 MP2 格式的音频文件。下面是代码的详细步骤:

1.导入 ffmpeg-go 和 os 等 Go 库;

2.定义一些变量,包括输出文件名、音频编解码器、音频编解码上下文、音频帧、音频数据包等;

3.查找 MP2 编码器并分配音频编解码上下文;

4.配置音频编解码参数,设置音频采样率、通道数、位率等;

5.打开音频编解码器;

6.创建输出文件;

7.开始编码过程,并将编码后的音频数据写入输出文件中。

具体地,编码过程包括以下几个步骤:

1.初始化音频帧;

2.将音频 PCM 数据填充到音频帧中;

3.发送音频帧到编解码器中进行编码;

4.从编解码器中读取编码后的音频数据包;

5.将编码后的音频数据包写入输出文件中。

最后,释放内存空间并关闭文件和编码器。在该示例程序中,我们需要手动设置 FFmpeg 库的路径,以便正确加载库文件。

命令如下:

go run ./examples/internalexamples/encode_audio/main.go ./out/encode_audio.mp2./lib/ffplay ./out/encode_audio.mp2

golang代码如下:

package mainimport ("fmt""math""os""unsafe""github.com/moonfdd/ffmpeg-go/ffcommon""github.com/moonfdd/ffmpeg-go/libavcodec""github.com/moonfdd/ffmpeg-go/libavutil"
)func main0() (ret ffcommon.FInt) {var filename stringvar codec *libavcodec.AVCodecvar c *libavcodec.AVCodecContextvar frame *libavutil.AVFramevar pkt *libavcodec.AVPacketvar i, j, k ffcommon.FIntvar f *os.Filevar samples *ffcommon.FUint16Tvar t, tincr ffcommon.FFloatif len(os.Args) <= 1 {fmt.Printf("Usage: %s <output file>\n", os.Args[0])return 0}filename = os.Args[1]/* find the MP2 encoder */codec = libavcodec.AvcodecFindEncoder(libavcodec.AV_CODEC_ID_MP2)if codec == nil {fmt.Printf("Codec not found\n")os.Exit(1)}c = codec.AvcodecAllocContext3()if c == nil {fmt.Printf("Could not allocate audio codec context\n")os.Exit(1)}/* put sample parameters */c.BitRate = 64000/* check that the encoder supports s16 pcm input */c.SampleFmt = libavutil.AV_SAMPLE_FMT_S16if check_sample_fmt(codec, c.SampleFmt) == 0 {fmt.Printf("Encoder does not support sample format %s",libavutil.AvGetSampleFmtName(c.SampleFmt))os.Exit(1)}/* select other audio parameters supported by the encoder */c.SampleRate = select_sample_rate(codec)c.ChannelLayout = uint64(select_channel_layout(codec))c.Channels = libavutil.AvGetChannelLayoutNbChannels(c.ChannelLayout)/* open it */if c.AvcodecOpen2(codec, nil) < 0 {fmt.Printf("Could not open codec\n")os.Exit(1)}f, _ = os.Create(filename)if f == nil {fmt.Printf("Could not open %s\n", filename)os.Exit(1)}/* packet for holding encoded output */pkt = libavcodec.AvPacketAlloc()if pkt == nil {fmt.Printf("could not allocate the packet\n")os.Exit(1)}/* frame containing input raw audio */frame = libavutil.AvFrameAlloc()if frame == nil {fmt.Printf("Could not allocate audio frame\n")os.Exit(1)}frame.NbSamples = c.FrameSizeframe.Format = int32(c.SampleFmt)frame.ChannelLayout = c.ChannelLayout/* allocate the data buffers */ret = frame.AvFrameGetBuffer(0)if ret < 0 {fmt.Printf("Could not allocate audio data buffers\n")os.Exit(1)}/* encode a single tone sound */t = 0tincr = float32(2 * libavutil.M_PI * 440.0 / float64(c.SampleRate))for i = 0; i < 200; i++ {/* make sure the frame is writable -- makes a copy if the encoder* kept a reference internally */ret = frame.AvFrameMakeWritable()if ret < 0 {os.Exit(1)}samples = (*ffcommon.FUint16T)(unsafe.Pointer(frame.Data[0]))for j = 0; j < c.FrameSize; j++ {*(*ffcommon.FUint16T)(unsafe.Pointer(uintptr(unsafe.Pointer(samples)) + uintptr(2*j*2))) = ffcommon.FUint16T(math.Sin(float64(t)) * 10000)for k = 1; k < c.Channels; k++ {*(*ffcommon.FUint16T)(unsafe.Pointer(uintptr(unsafe.Pointer(samples)) + uintptr((2*j+k)*2))) = *(*ffcommon.FUint16T)(unsafe.Pointer(uintptr(unsafe.Pointer(samples)) + uintptr(2*j*2)))}t += tincr}encode(c, frame, pkt, f)}/* flush the encoder */encode(c, nil, pkt, f)f.Close()libavutil.AvFrameFree(&frame)libavcodec.AvPacketFree(&pkt)libavcodec.AvcodecFreeContext(&c)return 0
}/* check that a given sample format is supported by the encoder */
func check_sample_fmt(codec *libavcodec.AVCodec, sample_fmt libavutil.AVSampleFormat) ffcommon.FInt {p := codec.SampleFmtsfor *p != libavutil.AV_SAMPLE_FMT_NONE {if *p == sample_fmt {return 1}p = (*libavutil.AVSampleFormat)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(8)))}return 0
}/* just pick the highest supported samplerate */
func select_sample_rate(codec *libavcodec.AVCodec) ffcommon.FInt {var p *ffcommon.FIntvar best_samplerate ffcommon.FIntif codec.SupportedSamplerates == nil {return 44100}p = codec.SupportedSampleratesfor *p != 0 {if best_samplerate == 0 || int32(math.Abs(float64(44100-*p))) < int32(math.Abs(float64(44100-best_samplerate))) {best_samplerate = *p}p = (*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(4)))}return best_samplerate
}/* select layout with the highest channel count */
func select_channel_layout(codec *libavcodec.AVCodec) ffcommon.FInt {var p *ffcommon.FUint64Tvar best_ch_layout ffcommon.FUint64Tvar best_nb_channels ffcommon.FIntif codec.ChannelLayouts == nil {return libavutil.AV_CH_LAYOUT_STEREO}p = codec.ChannelLayoutsfor *p != 0 {nb_channels := libavutil.AvGetChannelLayoutNbChannels(*p)if nb_channels > best_nb_channels {best_ch_layout = *pbest_nb_channels = nb_channels}p = (*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(8)))}return ffcommon.FInt(best_ch_layout)
}func encode(ctx *libavcodec.AVCodecContext, frame *libavutil.AVFrame, pkt *libavcodec.AVPacket, output *os.File) {var ret ffcommon.FInt/* send the frame for encoding */ret = ctx.AvcodecSendFrame(frame)if ret < 0 {fmt.Printf("Error sending the frame to the encoder\n")os.Exit(1)}/* read all the available output packets (in general there may be any* number of them */for ret >= 0 {ret = ctx.AvcodecReceivePacket(pkt)if ret == -libavutil.EAGAIN || ret == libavutil.AVERROR_EOF {return} else if ret < 0 {fmt.Printf("Error encoding audio frame\n")os.Exit(1)}output.Write(ffcommon.ByteSliceFromByteP(pkt.Data, int(pkt.Size)))pkt.AvPacketUnref()}
}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}}main0()
}

在这里插入图片描述

相关文章:

2023-04-06:拥抱Golang,优化FFmpeg音频编码器,探究encode_audio.c的内部结构。

2023-04-06&#xff1a;拥抱Golang&#xff0c;优化FFmpeg音频编码器&#xff0c;探究encode_audio.c的内部结构。 答案2023-04-06&#xff1a; 见moonfdd/ffmpeg-go库。 这段代码是一个示例程序&#xff0c;用于将音频 PCM 数据编码为 MP2 格式的音频文件。下面是代码的详细…...

归排、计排深度理解

归并排序&#xff1a;是创建在归并操作上的一种有效的排序算法。算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用&#xff0c;且各层分治递归可以同时进行。归并排序思路简单&#xff0c;速度仅次于快速排序&#xff0c;为稳定排序算法&#…...

设计原则(单一职责原则 开放封闭原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则)

设计原则单一职责原则(SRP)从三大特性角度看原则:应用的设计模式&#xff1a;开放封闭原则(OCP)从三大特性角度看原则:应用的设计模式&#xff1a;里氏替换原则(LSP)从三大特性角度看原则:应用的设计模式&#xff1a;依赖倒置原则(DIP)从三大特性角度看原则:应用的设计模式&…...

好像模拟了一个引力场

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 做一个网络让输入只有3个节点&#xff0c;每个训练集里有4张图片&#xff0c;让B的训练集全为0&#xff0c;排列组合A&#xff0c;观察迭代次数平均值的变化。 A-B 迭代次数 0 1 0 2*0*0*7-0*0*0*0 12957.31 0 0 0 2*0*0*7-0*0…...

MySQL优化——Explain分析执行计划详解

文章目录前言一. 查看SQL执行频率二. 定位低效率执行SQL三. explain分析执行计划3.1 id3.2 select_type3.3 table3.4 type3.5 key3.6 rows3.7 extra四. show profile分析SQL前言 在应用的的开发过程中&#xff0c;由于初期数据量小&#xff0c;开发人员写 SQL 语句时更重视功能…...

xcode 14.3 file not found libarclite_iphoneos.a

最近升级到xcode 14.3 版本的同学&#xff0c;会遇到这个一个问题 File not found: /Users/johnson/Downloads/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a 解决方法(亲测有效) 在podfile文件中&#xff0c;增…...

基于AI+数据驱动的慢查询索引推荐

目前&#xff0c;美团内部每天产生的慢查询数量已经超过上亿条。如何高效准确地为慢查询推荐缺失的索引来改善其执行性能&#xff0c;是美团数据库研发中心面临的一项挑战。为此&#xff0c;我们与华东师范大学开展了科研合作&#xff0c;在AI领域对索引推荐进行了探索和实践&a…...

【ESP32】嵌入式FreeRtos--Task

FreeRTOS中文数据手册&#xff1a;https://www.freertos.org/zh-cn-cmn-s/RTOS.html 任务函数 任务函数描述xTaskCreate()使用动态的方法创建一个任务xTaskCreateStatic()使用静态的方法创建一个任务xTaskCreatePinnedToCore指定任务运行的核心(最后一个参数)vTaskDelete()删…...

【操作系统】面试官都爱问的进程调度算法

【操作系统】面试官都爱问的进程调度算法 文章目录【操作系统】面试官都爱问的进程调度算法先来先服务调度算法最短作业优先调度算法高响应比优先调度算法时间片轮转调度算法最高优先级调度算法多级反馈队列调度算法进程调度算法也称 CPU 调度算法&#xff0c;毕竟进程是由 CPU…...

Spring-Web spi机制解析

org.springframework.web.SpringServletContainerInitializer#onStartup 在这里打个断点&#xff0c;查看程序是否会进来 可以发现程序进来了&#xff1a;主要spi机制&#xff0c;看看这里做了什么操作&#xff1f; 去寻找所有实现了WebApplicationInitializer的类 将符合条件…...

数据结构|将链表中小于0的数全部放在大于0的数的前面

题1&#xff1a; 某带头结点的非空单链表L中所有元素为整数&#xff0c;结点类型定义如下&#xff1a; typedef struct node { int data; struct node *next; } LinkNode; 设计一个尽可能高效的算法&#xff0c;将所有小于零的结点移到所有大于等于零的结点的前面。 分…...

分享106个ASP影音娱乐源码,总有一款适合您

分享106个ASP影音娱乐源码&#xff0c;总有一款适合您 106个ASP影音娱乐源码下载链接&#xff1a;https://pan.baidu.com/s/13k8UaJrCci_z4Q0gQbtDtg?pwdjq44 提取码&#xff1a;jq44 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 我的博客地址&#xff1a;亚…...

win10 PyCharm Anaconda过程记录

1、Anaconda用来配置不同的虚拟环境 进入 Anaconda Prompt 输入conda activate Hui&#xff08;此为自己创建的放置虚拟环境的文件夹&#xff09; 编译运行过程中出现No module named seaborn后 pip install seaborn...

Chrome扩展程序导出备份与本地导入浏览器

现在即使在国内下载个chrome&#xff0c;转个插件也千难万难。现在科学上网也越来越难&#xff0c;由于众所周知的原因&#xff0c;连qiang这个话题都是敏感词。哀默于心死&#xff0c;还是回避这个话题 只要把之前装的chrome打包&#xff0c;然后再重新安装一遍。操作步骤如下…...

mysql常用运算符

mysql常用运算符一、去重和空值1.distinct2.null参与运算3.用ifnull函数解决问题二、比较运算符三、dual伪表和数值运算1.常规运算2.比较运算符3.<>安全相等四、常用正则相关的比较运算符1.基本运算符2.模糊查询3.正则表达式五、逻辑运算符六、位运算总结一、去重和空值 …...

PyTorch 深度学习框架:优雅而简洁的代码实现

PyTorch 是由 Facebook 发布的深度学习框架&#xff0c;旨在为研究人员和工程师提供快速、灵活和简单的实验平台。与其他框架相比&#xff0c;PyTorch 具有简洁的 API 和灵活的动态计算图&#xff0c;使得构建和训练深度神经网络变得更加优雅和简洁。本文将介绍 PyTorch 的基本…...

【SpringMVC】请求重定向和转发

forward&#xff1a;表示转发 处理器方法返回ModelAndView,实现转发forward 语法&#xff1a; setViewName("forward:视图文件完整路径") forward特点&#xff1a; 不和视图解析器一同使用&#xff0c;就当项目中没有视图解析器redirect&#xff1a;表示重定向 处理…...

Vue中@click的常见修饰符

在 Vue 的click事件中&#xff0c;可以使用以下修饰符&#xff1a; .stop&#xff1a;阻止事件继续传播。.prevent&#xff1a;阻止默认事件。.capture&#xff1a;使用事件捕获模式。.self&#xff1a;只当事件是从侦听器绑定的元素本身触发时才触发回调。.once&#xff1a;只…...

软件测试面试复盘:技术面没有难倒我,hr面被虐的体无完肤

一般提到面试&#xff0c;肯定都会想问一下面试结果&#xff0c;我就大概的说一下面试结果&#xff0c;哈哈&#xff0c;其实不太想说&#xff0c;因为挺惨的&#xff0c;并没有像很多大佬一样 ”已拿字节阿里腾讯各大厂offer”&#xff0c;但是毕竟是自己的经历&#xff0c;无…...

vue实现鼠标移入移出事件+解决鼠标事件没有反应

鼠标移入移出事件代码 <div mouseenter"onMouseOver(item)" mouseleave"onMouseOut"></div> methods methods:{// 鼠标移入onMouseOver(item){console.log(item, 鼠标进来了);},// 鼠标移出onMouseOut(){console.log(鼠标出去了);}, }, 这…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...