Saya melihat tautan berikut:Pangkas file audio menggunakan waktu mulai dan berhenti
Tapi ini tidak sepenuhnya menjawab pertanyaan saya. Masalah saya adalah:Saya memiliki file audio seperti abc.mp3
atau abc.wav
. Saya juga memiliki file teks yang berisi stempel waktu mulai dan berakhir:
0.0 1.0 silence
1.0 5.0 music
6.0 8.0 speech
Saya ingin membagi audio menjadi tiga bagian menggunakan Python dan sox
/ffmpeg
, sehingga menghasilkan tiga file audio terpisah.
Bagaimana cara mencapai ini menggunakan sox
atau ffmpeg
?
Nanti saya ingin menghitung MFCC yang sesuai dengan bagian-bagian itu menggunakan librosa
.
Saya memiliki Python 2.7
, ffmpeg
, dan sox
pada instalasi Ubuntu Linux 16.04.
Jawaban yang Diterima:
Saya baru saja mencobanya, sangat sedikit dalam cara pengujian jadi mungkin itu akan membantu. Di bawah ini bergantung pada ffmpeg-python, tetapi menulis dengan subprocess
bukanlah hal yang sulit bagaimanapun juga.
Saat ini file input waktu hanya diperlakukan sebagai pasangan waktu, awal dan akhir, dan kemudian nama output. Nama yang hilang diganti sebagai linecount.wav
import ffmpeg
from sys import argv
""" split_wav `audio file` `time listing`
`audio file` is any file known by local FFmpeg
`time listing` is a file containing multiple lines of format:
`start time` `end time` output name
times can be either MM:SS or S*
"""
_in_file = argv[1]
def make_time(elem):
# allow user to enter times on CLI
t = elem.split(':')
try:
# will fail if no ':' in time, otherwise add together for total seconds
return int(t[0]) * 60 + float(t[1])
except IndexError:
return float(t[0])
def collect_from_file():
"""user can save times in a file, with start and end time on a line"""
time_pairs = []
with open(argv[2]) as in_times:
for l, line in enumerate(in_times):
tp = line.split()
tp[0] = make_time(tp[0])
tp[1] = make_time(tp[1]) - tp[0]
# if no name given, append line count
if len(tp) < 3:
tp.append(str(l) + '.wav')
time_pairs.append(tp)
return time_pairs
def main():
for i, tp in enumerate(collect_from_file()):
# open a file, from `ss`, for duration `t`
stream = ffmpeg.input(_in_file, ss=tp[0], t=tp[1])
# output to named file
stream = ffmpeg.output(stream, tp[2])
# this was to make trial and error easier
stream = ffmpeg.overwrite_output(stream)
# and actually run
ffmpeg.run(stream)
if __name__ == '__main__':
main()