使用 sox 和 python 根据时间戳列表静音音频区域

silence out regions of audio based on a list of time stamps , using sox and python

我有一个音频文件。
我有一堆 [start, end] 时间戳片段。

我想要达到的目标: 假设音频长 6:00 分钟。
我的段是:[[0.0,4.0]、[8.0,12.0]、[16.0,20.0]、[24.0,28.0]]

我将这两个传递给 sox + python 后,输出应该是 6 分钟长的音频,但只有在片段经过的时间内才有音频。

即我想将 time stamps 和原始音频传递给 SOX + python 这样就生成了除了与传递的片段相对应的那些部分之外的所有内容都被静音的音频

我无法达到上述目标,但有点接近相反的结果,经过几天的谷歌搜索,我得到了这个:

已更新,更简洁的代码 + 示例:
像这样进行填充和修剪的 sox 命令

SOX__SILENCE = 'sox "{inputaudio}" -c 1 "{outputaudio}" {padding}{trimming}'

用于测试的随机片段:

# random segments:
A= [[0.0,16.0]]
b=[[1.0,2.0]]
z= [[1.6, 8.3], [13.2, 33.7], [35.0,38.0], [42.0,51.0], [70.2,73.7], [90.0,99.2], [123.0,131.1]]
q= [[0.0,4.0], [8.0,12.0], [16.0,20.0], [24.0,28.0]]

一个小的 python 脚本来生成填充和修剪。

填充:

def get_pad_pattern_from_timestamps(my_segments):
        padding = 'pad'
        for segment in my_segments:
            duration = str(segment[1] - segment[0])
            padding = padding + ' ' + duration + '@' + str(segment[0])
        return padding
​
print get_pad_pattern_from_timestamps(A)
print get_pad_pattern_from_timestamps(b)
print get_pad_pattern_from_timestamps(z)
print get_pad_pattern_from_timestamps(q)

输出自 ^:

pad 16.0@0.0
pad 1.0@1.0
pad 6.7@1.6 20.5@13.2 3.0@35.0 9.0@42.0 3.5@70.2 9.2@90.0 8.1@123.0
pad 4.0@0.0 4.0@8.0 4.0@16.0 4.0@24.0 4.0@32.0 4.0@40.0

修剪:

def get_trimm_pattern_from_timestamps(my_segments):
        trimming = ''
        for segment in my_segments:
            duration = str(segment[1] - segment[0])
            trimming = trimming + ' trim 0 ' + str(segment[0]) + ' 0 ' + duration + ' ' + duration
        return trimming

print get_trimm_pattern_from_timestamps(A)
print get_trimm_pattern_from_timestamps(b)
print("\n")
print get_trimm_pattern_from_timestamps(z)
print("\n")
print get_trimm_pattern_from_timestamps(q)
print("\n")

修剪后的输出:

trim 0 0.0 0 16.0 16.0
 trim 0 1.0 0 1.0 1.0


 trim 0 1.6 0 6.7 6.7 trim 0 13.2 0 20.5 20.5 trim 0 35.0 0 3.0 3.0 trim 0 42.0 0 9.0 9.0 trim 0 70.2 0 3.5 3.5 trim 0 90.0 0 9.2 9.2 trim 0 123.0 0 8.1 8.1


 trim 0 0.0 0 4.0 4.0 trim 0 8.0 0 4.0 4.0 trim 0 16.0 0 4.0 4.0 trim 0 24.0 0 4.0 4.0 trim 0 32.0 0 4.0 4.0 trim 0 40.0 0 4.0 4.0

运行 SOX 使用关于终端的输出:

Padding:  

    sox dinners.mp3 -c 1 testlongpad.mp3 pad 4.0@0.0 4.0@8.0 4.0@16.0 4.0@24.0

Trimming:  

    sox dinners.mp3 -c 1 testrim.mp3 trim 0 0.0 0 16.0 16.0

Padd and trimm: 

    sox dinners.mp3 -c 1 testlongpadtrim.mp3 pad 4.0@0.0 4.0@8.0 4.0@16.0 4.0@24.0 trim 0 0.0 0 4.0 4.0 trim 0 8.0 0 4.0 4.0 trim 0 16.0 0 4.0 4.0 trim 0 24.0 0 4.0 4.0

如果 S 是我的段,那么 NS 就是其他一切。在 ^ 方法中,我传递 NS ,并且 NS 正在从音频中删除。

我想要实现的仍然是相同的,但方式不同,即我想传递 S,以便仅保留与 S 对应的音频部分。

PS:我的问题很具体,我是音频处理的新手,不确定如何进行。请不要因为过于宽泛或其他原因而关闭问题。 我很乐意提供更多详细信息以进行澄清。 最后,这不是硬件问题。这是个人项目。

示例音频:https://www.dropbox.com/s/1p27nfwney42ka2/LAZY_SALON_-03-_Hot_Dinners.mp3?dl=0

示例片段[[开始,结束],[] ] : [[1.6, 8.3], [13.2, 33.7], [35.0,38.0], [42.0,51.0], [70.2,73.7], [90.0,99.2], [123.0,131.1]]

因此,当这些时间戳与音频一起传递给 sox/python 时,除了提供的片段中的那些部分之外,音频中的所有内容都应该被静音。

我能够通过解决方法实施。

参见:

我所做的是创建一个包含段之间区域的新列表,然后将其传递给 sox。目前,我传递给 sox 的任何内容都会被删除。所以我计算了要删除的区域,然后将其传递给 sox。效果很好。

解决方案仍然是 inverted ,但我不必更改 sox 中的任何内容。

我不会接受我的回答作为答案。希望有人能够提出一个解决方案,其中涉及修改 sox 命令,而不必像我那样重新计算段。

我可能会用 zsh 脚本和 awk.

来解决这个问题

如果时间是这样给出的:

1.6 8.3
13.2 33.7
35.0 38.0
42.0 51.0
70.2 73.7
90.0 99.2
123.0 131.1

像这样计算静默位:

awk '{ print , ,  - p; p =  }' bits

输出:

1.6 8.3 1.6
13.2 33.7 4.9
35.0 38.0 1.3
42.0 51.0 4
70.2 73.7 19.2
90.0 99.2 16.3
123.0 131.1 23.8

您现在可以使用如下内容生成所需的命令行:

args="sox "
m=file.mp3
awk '{ print , ,  - p; p =  }' bits |
while read s e n; do
  args+="\"|sox -n -p trim 0 $n\" "
  args+="\"|sox $m -p trim $s =$e remix 1\" "
done
args+="out.wav"
echo "$args"

通过管道输入 /bin/sh 以执行:

... | sh

sox 的输出现在应该在 out.wav.