Dividir o áudio em várias partes com base em registros de data e hora de um arquivo de texto com sox ou ffmpeg

1

Eu olhei para o seguinte link: Aparar arquivo de áudio usando os horários de início e parada

Mas isso não responde completamente a minha pergunta. Meu problema é: eu tenho um arquivo de áudio como abc.mp3 ou abc.wav . Eu também tenho um arquivo de texto contendo timestamps de início e fim:

0.0 1.0 silence  
1.0 5.0 music  
6.0 8.0 speech    

Eu quero dividir o áudio em três partes usando Python e sox / ffmpeg , resultando em três arquivos de áudio separados.

Como faço para isso usando sox ou ffmpeg ?

Mais tarde, quero calcular o MFCC correspondente às partes que usam librosa .

Eu tenho Python 2.7 , ffmpeg e sox em uma instalação do Ubuntu Linux 16.04.

    
por DJ_Stuffy_K 30.01.2018 / 23:44

1 resposta

2

Acabei de dar uma rápida olhada nisso, muito pouco em termos de testes, então talvez seja de ajuda. Abaixo se baseia em ffmpeg-python , mas não seria um desafio escrever com subprocess de qualquer maneira.

No momento, o arquivo de entrada de tempo é tratado apenas como pares de vezes, iniciar e terminar e, em seguida, um nome de saída. Os nomes ausentes são substituídos como 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()
    
por 01.02.2018 / 22:16