Как разделить аудиофайл на несколько?

36

Я нашел что-то для видео, которое выглядит следующим образом.

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

Я попытался использовать это для аудиофайла, но только первый аудиофайл содержал реальное аудио, остальные молчали, кроме того, что это было хорошо, он создавал новый аудиофайл каждую секунду. Кто-нибудь знает, что нужно изменить, чтобы заставить это работать со звуковыми файлами, или другую команду, которая может сделать то же самое?

Отображаемое имя
источник
Если вам нужны другие способы сделать это, пожалуйста, объясните более подробно, чего вы пытаетесь достичь. ffmpeg cmdlines трудно запомнить.
1
@sblynx Как я объяснил в вопросе, разбивайте каждую секунду аудиофайла на новые аудиофайлы.
DisplayName

Ответы:

52

Это сработало для меня, когда я попробовал это на mp3-файл.

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

Где -segment_timeколичество времени, которое вы хотите для каждого файла (в секундах).

Ссылки

SLM
источник
Работал на mp3 с. Мне не удалось на m4b сказать: «Неверный аудиопоток. Требуется ровно один аудиопоток MP3».
vossad01
К вашему сведению, заменить mp3наm4a
Михаил
Как насчет случая, когда у меня есть 40-минутный файл, который я хотел бы разбить, скажем, на 4 минуты, 6 минут, 12 минут, 8 минут, 10 минут, вместо того, чтобы разбить его на единые вложенные файлы?
isosceleswheel
@isosceleswheel - взгляните на это - unix.stackexchange.com/questions/94168/… .
SLM
Это также работает для файлов WAV.
Марио Мейреллес
19

Чтобы разделить большой аудиофайл на набор дорожек различной длины, вы можете использовать следующую команду:

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

Например, я разбил один файл .opus из Inception Original Soundtrack на вложенные файлы, используя этот текстовый файл, содержащий начало, конец, имя:

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

Я написал эту короткую awkпрограмму для чтения текстового файла и создания ffmpegкоманд из каждой строки:

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

Ниже приведена более подробная pythonверсия программы split.py, в которой теперь из командной строки читаются как исходный файл дорожки, так и текстовый файл с указанием субтреков:

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

Вы можете легко создавать более сложные ffmpegвызовы, изменив шаблон команды и / или добавив дополнительные поля в каждую строку файла track_list.

isosceleswheel
источник
это фантастика, ! Пожалуйста, скажите мне, как запустить это из программы на Python, то есть я хочу читать аудио, и файл аннотации с start, end, label. и затем разбить аудио на части с размерами, соответствующими каждой строке в файле.
kRazzy R
2
@kRazzyR subprocess.call(command)- это pythonаналог system(command)in awk, оба из которых позволяют отправлять ffmpegкоманды оболочке. Я отредактировал свой пост, включив в него гибкую pythonреализацию, иллюстрирующую один из способов, как вы могли бы сделать это.
равнобедренное
1
По моему опыту, время начала дорожки № 2 должно равняться времени окончания дорожки № 1 и так далее. То есть, ваш пример будет пропускать секунду между каждым треком.
Тим Смит
1
Вот компактная версия bash / zsh. Измените время по мере необходимости, а затем удалите слово, echo чтобы фактически запустить команды. 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
Тим Смит
@TimSmith спасибо, что поймали это, я добавил редактирование выше. В зависимости от вашего плеера, между треками все еще может быть небольшой сбой, но это определенно звучит лучше, чем выбивание 1 с.
равнобедренное
3

В следующей строке аудиофайл будет разбит на несколько файлов, каждый продолжительностью 30 секунд.

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

Измените 30 (это количество секунд) на любой номер, который вы хотите.

Stryker
источник
1

ответ СЛМ :

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

не будет работать для меня без -map 0добавления:

ffmpeg -i somefile.mp3 -map 0 -f segment -segment_time 3 -c copy out%03d.mp3
без корней
источник
Сопоставление работает отлично, но также добавьте -vn, чтобы удалить любые встроенные изображения, или оно попытается воссоздать изображение для каждого сегмента (sloooowww).
Крис Рид
1

Данное решение не сработало для меня. Я полагаю, что это связано со старой версией ffmpegмоей системы.
В любом случае, я хотел предложить решение, которое сработало для меня. Вы также можете настроить таймеры, чтобы разрешить перекрытие звука, если хотите.

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

разделите ваши аудиофайлы на 30 секунд

tisaconundrum
источник
Новый вопрос будет в порядке, так как это не отвечает на вопрос OP!
Джордж Удосен