Ich habe mir den folgenden Link angesehen:Audiodatei mit Start- und Stoppzeiten trimmen
Aber das beantwortet meine Frage nicht ganz. Mein Problem ist:Ich habe eine Audiodatei wie abc.mp3
oder abc.wav
. Ich habe auch eine Textdatei mit Start- und Endzeitstempeln:
0.0 1.0 silence
1.0 5.0 music
6.0 8.0 speech
Ich möchte das Audio mit Python und sox
in drei Teile aufteilen /ffmpeg
, wodurch drei separate Audiodateien entstehen.
Wie erreiche ich dies entweder mit sox
oder ffmpeg
?
Später möchte ich den MFCC, der diesen Teilen entspricht, mit librosa
berechnen .
Ich habe Python 2.7
, ffmpeg
, und sox
auf einer Ubuntu Linux 16.04-Installation.
Akzeptierte Antwort:
Ich habe es nur kurz ausprobiert, sehr wenig zum Testen, also wird es vielleicht hilfreich sein. Unten basiert auf ffmpeg-python, aber es wäre keine Herausforderung, mit subprocess
zu schreiben sowieso.
Im Moment wird die Zeiteingabedatei nur als Zeitpaare, Start und Ende und dann als Ausgabename behandelt. Fehlende Namen werden durch linecount.wav
ersetzt
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()