如何使用 ffmpeg 可靠地同时改变音高和速度

Posted

技术标签:

【中文标题】如何使用 ffmpeg 可靠地同时改变音高和速度【英文标题】:How to change pitch and tempo together, reliably with ffmpeg 【发布时间】:2016-11-12 15:34:38 【问题描述】:

我知道如何用 atempo 改变速度,但是音频文件有点失真,我找不到改变音高的可靠方法。 (比如说,将节奏和音高一起提高 140%)

Sox 有一个速度选项,但会截断音量并且不像 ffmpeg 那样广泛可用。 mplayer 有一个速度选项,效果很好,但如果没有额外的库,我就无法输出。

我似乎明白 ffmpeg 没有办法改变音高(也许最近有?)但是有没有办法改变频率或其他一些标志来模拟改变音高?看得很远,找不到合适的解决方案。

编辑:asetrate:48k*1.4(假设最初是 48k)似乎不起作用,失真和音高仍然没有太大变化。

Edit2:https://superuser.com/a/1076762 这个答案有点效果,但质量比sox speed 1.4 选项低很多

【问题讨论】:

【参考方案1】:

ffmpeg -i <input file name> -filter:a "asetrate=<new frequency>" -y <output file name> 似乎对我有用。我用 ffprobe 检查了输入和输出文件的属性,似乎没有任何可能影响其质量的差异。虽然我确实运行了几次,其中一些生成的文件有一些工件,即使代码行相同,所以它可能是由一些 ffmpeg 错误引起的;如果您对质量不满意,请尝试再次运行它。

【讨论】:

你说得对,这似乎确实有效。也许是因为在我也用asetrate 接触atempo 之前,它似乎单独工作。质量似乎确实比 sox 或 mplayer 差一点,但我想它已经足够接近了。谢谢您的帮助。你知道是否有一种方法可以在不先检查的情况下设置原始的乘法 ?就像我可以只放 1.4 而不是 48k*1.4 那样,它会将 asetrate 的频率提高 1.4? 嗯我不知道是否有直接的方法可以做到这一点,我唯一能想到的就是使用 ffprobe 获取原始频率的值 - 只是该值,并删除所有额外的info 以便您可以将其作为变量传递给原始代码行。你可以这样做:ffmpeg -i <input file name> -filter:a "asetrate=$(ffprobe -v error -show_entries stream=sample_rate -of default=noprint_wrappers=1:nokey=1 <input file name>)*1.4" -y <output file name>【参考方案2】:

截至 2022 年(尽管 contributed in 2015),FFmpeg 有一个开箱即用的 rubberband 过滤器,没有任何上述丑陋、据称缓慢、质量差和不直观的解决方法。要将两个属性更改为相同的因子,请将tempopitch 指定为相同的值。除非进行统计测量,否则质量下降是难以察觉的。

【讨论】:

以上是关于如何使用 ffmpeg 可靠地同时改变音高和速度的主要内容,如果未能解决你的问题,请参考以下文章

如何通过改变音高和速度 iOS 保存音频?

MPlayer:独立改变音高和速度

在不改变音高的情况下减慢音频文件的播放速度?

使用音轨 android studio 改变音高

更改“发声器”的音频音高

使用 DirectSound 进行音高转换