Como faço para dividir um arquivo de áudio em vários?

36

Encontrei algo para vídeos, que se parece com isso.

ffmpeg -i * -c:v libx264 -crf 22 -map 0 -segment_time 1 -g 1 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*9)" -f segment output%03d.mp4

Tentei usá-lo para um arquivo de áudio, mas apenas o primeiro arquivo continha áudio real, os outros ficaram em silêncio, exceto que era bom, criou um novo arquivo de áudio a cada segundo. Alguém sabe o que modificar para fazer isso funcionar com arquivos de áudio ou outro comando que pode fazer o mesmo?

Mostrar nome
fonte
Se você quiser outras formas de fazer isso, explique com mais detalhes o que você está tentando alcançar. É difícil lembrar os cmdlines do ffmpeg.
1
@siblynx Como expliquei na pergunta, divida cada segundo de um arquivo de áudio em novos.
DisplayName

Respostas:

52

Isso funcionou para mim quando eu tentei em um arquivo mp3.

$ ffmpeg -i somefile.mp3 -f segment -segment_time 3 -c copy out%03d.mp3

Onde -segment_timeé a quantidade de tempo que você deseja por cada arquivo (em segundos).

Referências

slm
fonte
Trabalhou em mp3 s. Falha para mim no m4b s dizendo: "Fluxo de áudio inválido. Exatamente um fluxo de áudio MP3 é necessário".
precisa saber é o seguinte
FYI, substitua mp3porm4a
Mikhail
Que tal um caso em que eu tenho um arquivo de 40 minutos que eu gostaria de acessar, por exemplo, 4min, 6min, 12min, 8min, 10min, em vez de dividir em subarquivos uniformes?
isosceleswheel
@isosceleswheel - veja isso - unix.stackexchange.com/questions/94168/… .
slm
Também funcionou para arquivos wav.
Mário Meyrelles
19

Para dividir um grande arquivo de áudio em um conjunto de faixas com diferentes comprimentos, você pode usar o seguinte comando:

# -to is the end time of the sub-file
ffmpeg -i BIG_FILE -acodec copy -ss START_TIME -to END_TIME LITTLE_FILE

Por exemplo, eu quebrei um único arquivo .opus da trilha sonora original do Inception em subarquivos usando este arquivo de texto que contém nome de início, fim e nome:

00:00:00 00:01:11 01_half_remembered_dream
00:01:11 00:03:07 02_we_built_our_own_world
00:03:07 00:05:31 03_dream_is_collapsing
00:05:31 00:09:14 04_radical_notion
00:09:14 00:16:58 05_old_souls
00:16:58 00:19:22 06
00:19:22 00:24:16 07_mombasa
00:24:16 00:26:44 08_one_simple_idea
00:26:44 00:31:49 09_dream_within_a_dream
00:31:49 00:41:19 10_waiting_for_a_train
00:41:19 00:44:44 11_paradox
00:44:44 00:49:20 12_time

Eu escrevi este pequeno awkprograma para ler o arquivo de texto e criar ffmpegcomandos a partir de cada linha:

{
    # make ffmpeg command string using sprintf
    cmd = sprintf("ffmpeg -i inception_ost.opus -acodec copy -ss %s -to %s %s.opus", $1, $2, $3)

    # execute ffmpeg command with awk's system function
    system(cmd)
}

Aqui está uma pythonversão mais detalhada do programa chamada split.py, onde agora o arquivo de trilha original e o arquivo de texto que especificam as sub-trilhas são lidos na linha de comando:

import subprocess
import sys


def main():
    """split a music track into specified sub-tracks by calling ffmpeg from the shell"""

    # check command line for original file and track list file
    if len(sys.argv) != 3:
        print 'usage: split <original_track> <track_list>'
        exit(1)

    # record command line args
    original_track = sys.argv[1]
    track_list = sys.argv[2]

    # create a template of the ffmpeg call in advance
    cmd_string = 'ffmpeg -i {tr} -acodec copy -ss {st} -to {en} {nm}.opus'

    # read each line of the track list and split into start, end, name
    with open(track_list, 'r') as f:
        for line in f:
            # skip comment and empty lines
            if line.startswith('#') or len(line) <= 1:
                continue

            # create command string for a given track
            start, end, name = line.strip().split()
            command = cmd_string.format(tr=original_track, st=start, en=end, nm=name)

            # use subprocess to execute the command in the shell
            subprocess.call(command, shell=True)

    return None


if __name__ == '__main__':
    main()

Você pode facilmente criar ffmpegchamadas cada vez mais complicadas modificando o modelo de comando e / ou adicionando mais campos a cada linha do arquivo track_list.

isosceleswheel
fonte
isto é fantástico, ! por favor me diga Como executar isso a partir de um programa python, ou seja, eu quero ler o áudio e o arquivo de anotação com início, fim, rótulo. e depois divida o áudio em pedaços com tamanhos correspondentes a cada linha do arquivo.
precisa saber é o seguinte
2
O @kRazzyR subprocess.call(command)é o pythonanalógico para o system(command)in awk, o que permite enviar ffmpegcomandos ao shell. Editei meu post para incluir uma pythonimplementação flexível que ilustra uma maneira de você fazer isso.
Isosceleswheel
1
Na minha experiência, o horário de início da faixa 2 deve ser igual ao horário de término da faixa 1 e assim por diante. Ou seja, seu exemplo de exemplo pulará um segundo entre cada faixa.
Tim Smith
1
Aqui está uma versão compacta do bash / zsh. Edite os horários conforme necessário e remova a palavra echo para realmente executar os comandos. source="source audio file.m4a"; i=0; t1=0:00; for end_time in 1:24 5:40 14:48 19:33 35:11 40:00 46:08 51:58 ''; do i=$((i+1)); t0=$t1 t1=$end_time; echo ffmpeg -i "$source" -acodec copy -ss $t0 ${t1:+-to} $t1 $(printf "track%02d.%s" $i ${source##*.}); done
Tim Smith
@ TimSmith obrigado por entender isso, adicionei uma edição acima. Dependendo do seu player, ainda pode haver um pequeno soluço entre as faixas, mas isso definitivamente soa melhor do que cortar 1s.
precisa
3

A linha a seguir dividirá um arquivo de áudio em vários arquivos, cada um com 30 segundos de duração.

ffmpeg -i file.wav -f segment -segment_time 30 -c copy parts/output%09d.wav

Altere 30 (que é o número de segundos) para o número que desejar.

Stryker
fonte
1

resposta do slm :

ffmpeg -i somefile.mp3  -f segment -segment_time 3 -c copy out%03d.mp3

não funcionaria para mim sem o -map 0adicional:

ffmpeg -i somefile.mp3 -map 0 -f segment -segment_time 3 -c copy out%03d.mp3
Sem raízes
fonte
O mapeamento funciona muito bem, mas também adiciona -vn para remover as imagens incorporadas, ou tenta recriar a imagem para cada segmento (sloooowww).
Chris Reid
1

A solução fornecida não funcionou para mim. Acredito que isso se deva a uma versão mais antiga do ffmpegmeu sistema.
De qualquer forma, eu queria fornecer uma solução que funcionasse para mim. Você também pode personalizar os cronômetros para permitir a sobreposição de áudio, se desejar.

Output file #0 does not contain any stream

ffmpeg -i your_audio_file.mp3 -acodec copy -t 00:00:30 -ss 00:00:00 split_audio_file.mp3

divida seus arquivos de áudio em incrementos de 30 segundos

tisaconundrum
fonte
Uma nova pergunta estaria em ordem, pois isso não responde à pergunta da OP!
George Udosen