3

I looked at the following link: Trim audio file using start and stop times

But this doesn't completely answer my question. My problem is: I have an audio file such as abc.mp3 or abc.wav. I also have a text file containing start and end timestamps:

0.0 1.0 silence 1.0 5.0 music 6.0 8.0 speech 

I want to split the audio into three parts using Python and sox/ffmpeg, thus resulting in three seperate audio files.

How do I achieve this using either sox or ffmpeg?

Later I want to compute the MFCC corresponding to those portions using librosa.

I have Python 2.7, ffmpeg, and sox on an Ubuntu Linux 16.04 installation.

2

1 Answer 1

5

I've just had a quick go at it, very little in the way of testing so maybe it'll be of help. Below relies on ffmpeg-python, but it wouldn't be a challenge to write with subprocess anyway.

At the moment the time input file is just treated as pairs of times, start and end, and then an output name. Missing names are replaced as 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() 
1
  • 1
    my upvote will appear once I reach 15 points, sorry about that new member difficulties! Commented Feb 1, 2018 at 22:44

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.