使用实际录音滤除视频中的噪音
Using an actual audio recording to filter out noise from a video
我使用我的笔记本电脑(Ubuntu 戴尔 XPS13 上的 18.04 LTS 衍生产品)使用 OBS 录制视频(这些只是旁白的演示文稿)。演示完成后(.flv 格式),我使用 ffmpeg 处理它,使用过滤器尝试减少背景噪音、减小视频大小、将编码更改为 .mp4、插入水印等。几个月后,这个系统效果很好。
然而,我的笔记本电脑现在开始显示它的年龄(它已经 4 岁了)。这意味着风扇的声音会变大——声音大到足以在录音中引起注意,但又不会大到你在工作时注意到。因此,即使在 ffmpeg 中过滤低频后,视频中仍会残留点击和其他类型的声音。我是一名科学家,但不是 audio/video 专家。所以,我在想——是否可以简单地记录下我的机器在不演示时发出的噪音,然后使用该录音过滤掉我的机器在演示期间发出的噪音?
过滤掉音频频谱的某些范围等一揽子方法不太可能奏效,因为噪声的功率谱可能有很多峰值,而且这些峰值也可能扩展到人声范围(我能听到)。此外,这是一个移动的目标——笔记本电脑正在老化,无论如何,它发出的噪音的数量和类型取决于负载和它运行了多长时间。算法:
- 在我不录音时记录 实际 电脑噪音(加上背景噪音的额外好处)。理想情况下,就在开始录制演示文稿之前。这可以采用 1-2 分钟音频样本的形式。
- 在 OBS 上录制演示文稿。
- 使用 1 作为过滤器去除 2 中的噪声。我想这将涉及对 1 进行傅里叶分析,然后在每个时间段从 2 的光谱中去除这些峰值。
我研究了 sox,这是人们在没有提供任何细节的情况下轻率地向您指出的内容。我不知道如何从视频中分离出音频通道,然后将它们交织在一起(不是这里的软件专家)。除了 RTFM,还有什么有用的建议可以提供吗?我已经搜索过,但没能找到 HOWTO。我认为这可能是我搜索的错误,因为我拒绝相信这是一个新想法 - 它是许多领域(包括天文学)用于消除噪音的标准方法。
我没有足够的声誉来发表评论,所以这是我的答案,因为它适用于我的情况,我自己也在寻找答案。它可能适用于您的情况,也可能不适用,因为我使用 ffmpeg
录制我的屏幕(这可以很好地录制屏幕上的所有内容,但对于单个 program/window 或一部分来说不是一个很好的选择屏幕,这可以完成,但我不认为有一个视觉指示正在记录屏幕的哪一部分。
我遇到了 afftdn
过滤器(https://ffmpeg.org/ffmpeg-filters.html#afftdn,@Gyan 在对 OP 问题的评论中也提到了它)并且能够成功使用它。
该过程可能仅适用于 ffmpeg
制作的现场录音 - 至少我想不出用预先录制的内容进行此操作的方法。以下过程也适用于仅音频输入,但您需要修改 ffmpeg
命令以仅录制音频。它是这样工作的:
- 运行
ffmpeg
命令记录你的 audio/screen.
- 指示
afftdn
录制背景噪音并静坐片刻。
- 指示
afftdn
停止录制背景噪音并继续进行语音评论和演示文稿的实际录制。
- 从输出文件中丢弃录音的开头部分,其中仅包含背景噪音的录音。
对于第 1 步。我 运行
ffmpeg -f pulse -i <my_input_device> -f x11grab -s 1920x1080 -framerate 30 -i :0.0 -s 1280x720 -filter_complex afftdn=tn=enabled /home/my_user_name/Videos/my_output_file.mp4
列出您的输入设备运行
pactl list short sources
并选择要使用的输入设备的名称 - 我的是 alsa_input.pci-000_00_1b.0.analog-stereo
。上面 ffmpeg
命令的第一个 -s 参数 (-s 1920x1080
) 是我的屏幕分辨率(相应地调整,您也可以将其设置为小于屏幕分辨率以仅记录屏幕的一部分 - 结合这个使用偏移量参数将记录的部分从屏幕的左上象限移动),参数 -i :0.0
表示默认屏幕的左上角像素 - 如果您不想记录整个,则可以使用其他偏移量屏幕(如果您更改此偏移量,则相应地更改您的输入分辨率)。第二个 -s 参数 (-s 1280x780
) 是输出视频分辨率。
第 2 步:点击 c
告诉 ffmpeg
您正在向过滤器发出命令。 ffmpeg
应该通过输出 Enter command: <target>|all <time>| -1 <command>[ <argument>]
提示您输入。类型:
afftdn -1 start
过滤器正在记录您的背景噪音。
第 3 步:点击 c
告诉 ffmpeg
您再次向过滤器发出命令,并在出现提示时键入:
afftdn -1 stop
过滤器现在应该过滤音频中的背景噪音(在我的例子中,它需要几秒钟才能启动 - 我怀疑这可能取决于噪音记录的长度 - 你可能需要稍微试验一下以便更好地了解何时开始实际录制)。继续录制。
第 4 步。播放 audio/video 以找到去除噪音的实际视频的开始时间。然后告诉 ffmpeg
删除那个时间之前的所有内容:
ffmpeg -ss <duration> -i /home/my_user_name/Videos/my_output_file.mp4 /home/my_user_name/Videos/my_output_file_with_noise_removed.mp4
将 <duration>
替换为要从输入文件中删除的秒数(您还可以提供 HH:mm:ss.d
格式的持续时间,小时 HH 和十进制 .d 是可选的),例如:
ffmpeg -ss 30.5 -i /home/my_user_name/Videos/my_output_file.mp4 /home/my_user_name/Videos/my_output_file_with_noise_removed.mp4
当然可以使用您喜欢的文件名 - 我喜欢只导航到工作目录并发出以下形式的命令
ffmpeg -ss 30.5 -i input_file.mp4 noiseless_output_file.mp4
我使用我的笔记本电脑(Ubuntu 戴尔 XPS13 上的 18.04 LTS 衍生产品)使用 OBS 录制视频(这些只是旁白的演示文稿)。演示完成后(.flv 格式),我使用 ffmpeg 处理它,使用过滤器尝试减少背景噪音、减小视频大小、将编码更改为 .mp4、插入水印等。几个月后,这个系统效果很好。
然而,我的笔记本电脑现在开始显示它的年龄(它已经 4 岁了)。这意味着风扇的声音会变大——声音大到足以在录音中引起注意,但又不会大到你在工作时注意到。因此,即使在 ffmpeg 中过滤低频后,视频中仍会残留点击和其他类型的声音。我是一名科学家,但不是 audio/video 专家。所以,我在想——是否可以简单地记录下我的机器在不演示时发出的噪音,然后使用该录音过滤掉我的机器在演示期间发出的噪音?
过滤掉音频频谱的某些范围等一揽子方法不太可能奏效,因为噪声的功率谱可能有很多峰值,而且这些峰值也可能扩展到人声范围(我能听到)。此外,这是一个移动的目标——笔记本电脑正在老化,无论如何,它发出的噪音的数量和类型取决于负载和它运行了多长时间。算法:
- 在我不录音时记录 实际 电脑噪音(加上背景噪音的额外好处)。理想情况下,就在开始录制演示文稿之前。这可以采用 1-2 分钟音频样本的形式。
- 在 OBS 上录制演示文稿。
- 使用 1 作为过滤器去除 2 中的噪声。我想这将涉及对 1 进行傅里叶分析,然后在每个时间段从 2 的光谱中去除这些峰值。
我研究了 sox,这是人们在没有提供任何细节的情况下轻率地向您指出的内容。我不知道如何从视频中分离出音频通道,然后将它们交织在一起(不是这里的软件专家)。除了 RTFM,还有什么有用的建议可以提供吗?我已经搜索过,但没能找到 HOWTO。我认为这可能是我搜索的错误,因为我拒绝相信这是一个新想法 - 它是许多领域(包括天文学)用于消除噪音的标准方法。
我没有足够的声誉来发表评论,所以这是我的答案,因为它适用于我的情况,我自己也在寻找答案。它可能适用于您的情况,也可能不适用,因为我使用 ffmpeg
录制我的屏幕(这可以很好地录制屏幕上的所有内容,但对于单个 program/window 或一部分来说不是一个很好的选择屏幕,这可以完成,但我不认为有一个视觉指示正在记录屏幕的哪一部分。
我遇到了 afftdn
过滤器(https://ffmpeg.org/ffmpeg-filters.html#afftdn,@Gyan 在对 OP 问题的评论中也提到了它)并且能够成功使用它。
该过程可能仅适用于 ffmpeg
制作的现场录音 - 至少我想不出用预先录制的内容进行此操作的方法。以下过程也适用于仅音频输入,但您需要修改 ffmpeg
命令以仅录制音频。它是这样工作的:
- 运行
ffmpeg
命令记录你的 audio/screen. - 指示
afftdn
录制背景噪音并静坐片刻。 - 指示
afftdn
停止录制背景噪音并继续进行语音评论和演示文稿的实际录制。 - 从输出文件中丢弃录音的开头部分,其中仅包含背景噪音的录音。
对于第 1 步。我 运行
ffmpeg -f pulse -i <my_input_device> -f x11grab -s 1920x1080 -framerate 30 -i :0.0 -s 1280x720 -filter_complex afftdn=tn=enabled /home/my_user_name/Videos/my_output_file.mp4
列出您的输入设备运行
pactl list short sources
并选择要使用的输入设备的名称 - 我的是 alsa_input.pci-000_00_1b.0.analog-stereo
。上面 ffmpeg
命令的第一个 -s 参数 (-s 1920x1080
) 是我的屏幕分辨率(相应地调整,您也可以将其设置为小于屏幕分辨率以仅记录屏幕的一部分 - 结合这个使用偏移量参数将记录的部分从屏幕的左上象限移动),参数 -i :0.0
表示默认屏幕的左上角像素 - 如果您不想记录整个,则可以使用其他偏移量屏幕(如果您更改此偏移量,则相应地更改您的输入分辨率)。第二个 -s 参数 (-s 1280x780
) 是输出视频分辨率。
第 2 步:点击 c
告诉 ffmpeg
您正在向过滤器发出命令。 ffmpeg
应该通过输出 Enter command: <target>|all <time>| -1 <command>[ <argument>]
提示您输入。类型:
afftdn -1 start
过滤器正在记录您的背景噪音。
第 3 步:点击 c
告诉 ffmpeg
您再次向过滤器发出命令,并在出现提示时键入:
afftdn -1 stop
过滤器现在应该过滤音频中的背景噪音(在我的例子中,它需要几秒钟才能启动 - 我怀疑这可能取决于噪音记录的长度 - 你可能需要稍微试验一下以便更好地了解何时开始实际录制)。继续录制。
第 4 步。播放 audio/video 以找到去除噪音的实际视频的开始时间。然后告诉 ffmpeg
删除那个时间之前的所有内容:
ffmpeg -ss <duration> -i /home/my_user_name/Videos/my_output_file.mp4 /home/my_user_name/Videos/my_output_file_with_noise_removed.mp4
将 <duration>
替换为要从输入文件中删除的秒数(您还可以提供 HH:mm:ss.d
格式的持续时间,小时 HH 和十进制 .d 是可选的),例如:
ffmpeg -ss 30.5 -i /home/my_user_name/Videos/my_output_file.mp4 /home/my_user_name/Videos/my_output_file_with_noise_removed.mp4
当然可以使用您喜欢的文件名 - 我喜欢只导航到工作目录并发出以下形式的命令
ffmpeg -ss 30.5 -i input_file.mp4 noiseless_output_file.mp4