¿Cómo divido un archivo de audio en múltiples?

36

Encontré algo para videos, que se ve así.

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

Traté de usar eso para un archivo de audio, pero solo el primer archivo de audio contenía audio real, los otros estaban en silencio, aparte de eso era bueno, creaba un nuevo archivo de audio por cada segundo. ¿Alguien sabe qué modificar para que esto funcione con archivos de audio u otro comando que pueda hacer lo mismo?

Nombre para mostrar
fuente
Si desea otras formas de hacerlo, explique con más detalle lo que está tratando de lograr. Los cmdlines de ffmpeg son difíciles de recordar.
1
@siblynx Como expliqué en la pregunta, divida cada segundo de un archivo de audio en nuevos archivos de audio.
DisplayName

Respuestas:

52

Esto funcionó para mí cuando lo probé en un archivo mp3.

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

¿Dónde -segment_timeestá la cantidad de tiempo que desea por cada archivo (en segundos)?

Referencias

slm
fuente
Trabajó en mp3 s. Me falló el mensaje de m4b que decía: " Secuencia de audio no válida . Se requiere exactamente una secuencia de audio MP3".
vossad01
Para su información, reemplace mp3conm4a
Mikhail
¿Qué pasa con un caso en el que tengo un archivo de 40 minutos en el que me gustaría dividir, digamos, 4 minutos, 6 minutos, 12 minutos, 8 minutos, 10 minutos en lugar de dividirlos en subarchivos uniformes?
isosceleswheel
@isosceleswheel - mira esto - unix.stackexchange.com/questions/94168/… .
slm
También funcionó para archivos wav.
Mário Meyrelles
19

Para dividir un gran archivo de audio en un conjunto de pistas con diferentes longitudes, puede usar el siguiente 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 ejemplo, dividí un solo archivo .opus de la banda sonora original de inicio en subarchivos usando este archivo de texto que contiene inicio, fin y nombre:

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

Escribí este breve awkprograma para leer el archivo de texto y crear ffmpegcomandos desde cada línea:

{
    # 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)
}

Aquí hay una pythonversión más detallada del programa llamado split.py, donde ahora tanto el archivo de pista original como el archivo de texto que especifica subpistas se leen desde la línea de comandos:

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()

Puede crear fácilmente ffmpegllamadas cada vez más complicadas modificando la plantilla de comando y / o agregando más campos a cada línea del archivo track_list.

rueda isósceles
fuente
esto es fantástico, ! dígame cómo ejecutar esto desde un programa de Python, es decir, quiero leer el audio y el archivo de anotaciones con inicio, fin y etiqueta. y luego divida el audio en partes con tamaños correspondientes a cada línea del archivo.
kRazzy R
2
@kRazzyR subprocess.call(command)es el pythonanálogo a system(command)in awk, los cuales le permiten enviar ffmpegcomandos al shell. Edité mi publicación para incluir una pythonimplementación flexible que ilustrara una forma en que podría hacerlo .
isosceleswheel
1
En mi experiencia, el tiempo de inicio de la pista # 2 debería ser igual al tiempo de finalización de la pista # 1, y así sucesivamente. Es decir, sus tiempos de ejemplo omitirán un segundo entre cada pista.
Tim Smith
1
Aquí hay una versión compacta de bash / zsh. Edite los tiempos según sea necesario y luego elimine la palabra echo para ejecutar los 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 gracias por atrapar eso, agregué una edición arriba. Dependiendo de su reproductor, puede haber un pequeño inconveniente entre las pistas, pero esto definitivamente suena mejor que cortar 1s.
isosceleswheel
3

La siguiente línea dividirá un archivo de audio en varios archivos, cada uno con una duración de 30 segundos.

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

Cambie 30 (que es el número de segundos) a cualquier número que desee.

Stryker
fuente
1

respuesta de slm :

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

no funcionaría para mí sin el -map 0agregado:

ffmpeg -i somefile.mp3 -map 0 -f segment -segment_time 3 -c copy out%03d.mp3
Desarraigado
fuente
El mapeo funciona muy bien, pero también agrega -vn para eliminar cualquier imagen incrustada, o intentará recrear la imagen para cada segmento (sloooowww).
Chris Reid
1

La solución dada no funcionó para mí. Creo que esto se debe a una versión anterior de ffmpegmi sistema.
En cualquier caso, quería proporcionar una solución que funcionó para mí. También puede personalizar los temporizadores para permitir la superposición de audio si lo desea.

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

divide tus archivos de audio en incrementos de 30 segundos

tisaconundrum
fuente
¡Una nueva pregunta estaría en orden, ya que esto no responde la pregunta de OP!
George Udosen