Wie teile ich eine Audiodatei in mehrere auf?

36

Ich habe etwas für Videos gefunden, das so aussieht.

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

Ich habe versucht, das für eine Audiodatei zu verwenden, aber nur die erste Audiodatei enthielt das eigentliche Audio, die anderen waren still, abgesehen davon, dass es gut war, es wurde jede Sekunde eine neue Audiodatei erstellt. Weiß jemand, was zu ändern ist, damit dies mit Audiodateien oder einem anderen Befehl funktioniert, der dasselbe tun kann?

Anzeigename
quelle
Wenn Sie dies auf andere Weise tun möchten, erläutern Sie bitte ausführlicher, was Sie erreichen möchten. ffmpeg cmdlines sind schwer zu merken.
1
@siblynx Wie ich in der Frage erklärt habe, teile jede Sekunde einer Audiodatei in neue Audiodateien auf.
Anzeigename

Antworten:

52

Das hat bei mir funktioniert, als ich es mit einer MP3-Datei ausprobiert habe.

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

Wo -segment_timeist die gewünschte Zeit pro Datei (in Sekunden)?

Verweise

slm
quelle
Arbeitete an mp3 s. Bei m4b s "Ungültiger Audiostream. Genau ein MP3-Audiostream ist erforderlich" ist für mich fehlgeschlagen .
Vossad01
Zu Ihrer Information, ersetzen mp3durchm4a
Mikhail
Wie wäre es mit einem Fall, in dem ich eine 40-minütige Datei habe, in die ich einbrechen möchte, beispielsweise 4 Minuten, 6 Minuten, 12 Minuten, 8 Minuten, 10 Minuten, anstatt sie in einheitliche Unterdateien aufzulösen?
isosceleswheel
@isosceleswheel - schauen Sie sich das an - unix.stackexchange.com/questions/94168/… .
SLM
Es funktionierte auch für WAV-Dateien.
Mário Meyrelles
19

Mit dem folgenden Befehl können Sie eine große Audiodatei in mehrere Spuren unterschiedlicher Länge aufteilen:

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

Ich habe beispielsweise eine einzelne .opus-Datei des Inception Original-Soundtracks mit der folgenden Textdatei in Unterdateien aufgeteilt, die Start, Ende und Namen enthält:

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

Ich habe dieses kurze awkProgramm geschrieben, um die Textdatei zu lesen und ffmpegBefehle aus jeder Zeile zu erstellen :

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

Hier ist eine detailliertere pythonVersion des aufgerufenen Programms split.py, in der nun sowohl die ursprüngliche Spurdatei als auch die Textdatei, die die Unterspuren angibt, von der Befehlszeile aus gelesen werden:

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

Sie können auf einfache Weise immer kompliziertere ffmpegAufrufe erstellen, indem Sie die Befehlsvorlage ändern und / oder jeder Zeile der Datei track_list weitere Felder hinzufügen.

gleichschenkliges Rad
quelle
das ist fantastisch, ! Bitte sagen Sie mir, wie Sie dies von einem Python-Programm ausführen, dh ich möchte Audio und die Anmerkungsdatei mit Start, Ende, Label lesen. und dann teilen Sie Audio in Stücke mit Größen entsprechend jeder Zeile in der Datei.
kRazzy R
2
@kRazzyR subprocess.call(command)ist das pythonAnalogon zu system(command)in awk. In beiden Fällen können Sie ffmpegBefehle an die Shell senden . Ich habe meinen Beitrag so bearbeitet, dass er eine flexible pythonImplementierung enthält, die zeigt, wie Sie dies tun können.
isosceleswheel
1
Meiner Erfahrung nach sollte die Anfangszeit von Spur 2 gleich der Endzeit von Spur 1 sein und so weiter. Das heißt, Ihre Beispielzeiten überspringen eine Sekunde zwischen den einzelnen Spuren.
Tim Smith
1
Hier ist eine kompakte bash / zsh-Version. Bearbeiten Sie die Zeiten nach Bedarf, und entfernen Sie das Wort echo , um die Befehle tatsächlich auszuführen. 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, danke, dass du das abgefangen hast. Ich habe oben eine Bearbeitung hinzugefügt. Abhängig von Ihrem Player kann es immer noch zu einem kleinen Schluckauf zwischen den Tracks kommen, aber das hört sich definitiv besser an, als 1s herauszuschneiden.
Isosceleswheel
3

In der folgenden Zeile wird eine Audiodatei in mehrere Dateien mit einer Dauer von jeweils 30 Sekunden aufgeteilt.

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

Ändern Sie 30 (das ist die Anzahl der Sekunden) in eine beliebige Zahl.

Stryker
quelle
1

slms antwort :

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

würde nicht für mich arbeiten, ohne die -map 0hinzugefügt:

ffmpeg -i somefile.mp3 -map 0 -f segment -segment_time 3 -c copy out%03d.mp3
Wurzellos
quelle
Die Zuordnung funktioniert hervorragend, aber fügen Sie -vn hinzu, um alle eingebetteten Bilder zu entfernen, oder es wird versucht, das Bild für jedes Segment neu zu erstellen (sloooowww).
Chris Reid
1

Die angegebene Lösung hat bei mir nicht funktioniert. Ich glaube, dass dies auf eine ältere Version von ffmpegauf meinem System zurückzuführen ist.
Auf jeden Fall wollte ich eine Lösung anbieten , die für mich funktioniert. Sie können die Timer auch so anpassen, dass sich die Audiodaten bei Bedarf überlappen.

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

Teilen Sie Ihre Audiodateien in 30-Sekunden-Schritten auf

tisaconundrum
quelle
Eine neue Frage wäre angebracht, da dies die Frage von OP nicht beantwortet!
George Udosen