Split audio into several pieces based on timestamps from a text file with sox or ffmpeg

5,520

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()
Share:
5,520
DJ_Stuffy_K
Author by

DJ_Stuffy_K

Updated on September 18, 2022

Comments

  • DJ_Stuffy_K
    DJ_Stuffy_K over 1 year

    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.

  • DJ_Stuffy_K
    DJ_Stuffy_K over 6 years
    my upvote will appear once I reach 15 points, sorry about that new member difficulties!