1

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.

3

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()
  • my upvote will appear once I reach 15 points, sorry about that new member difficulties! – DJ_Stuffy_K Feb 1 '18 at 22:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.