Обрезка видео по времени начала и окончания с помощью ffmpeg

Я попытался вырезать видео, используя время начала и окончания видео, используя следующую команду

ffmpeg -ss 00:00:03 -t 00:00:08 -i movie.mp4 -acodec copy -vcodec copy -async 1 cut.mp4

Используя вышеупомянутую команду, я хочу вырезать видео из 00:00:03 в 00:00:08, Но он не обрезает видео между этими временами вместо того, чтобы обрезать видео с первыми 11 секундами. Может кто-нибудь помочь мне, как решить эту проблему?

Изменить 1:

Я попытался вырезать с помощью следующей команды, которая предлагается mark4o

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

Но была показана следующая ошибка.

кодировщик 'aac' является экспериментальным, но экспериментальные кодеки не включены

поэтому я добавил -strict -2 в команду т.е.

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -strict -2 cut.mp4

Сейчас работает нормально.

14 ответов

Решение

У вас, вероятно, нет ключевого кадра на отметке 3 секунды. Поскольку не ключевые кадры кодируют отличия от других кадров, им требуются все данные, начиная с предыдущего ключевого кадра.

С контейнером mp4 можно вырезать не ключевой кадр без перекодирования с использованием списка редактирования. Другими словами, если ближайший ключевой кадр до 3 с равен 0, то он скопирует видео, начинающееся с 0, и использует список редактирования, чтобы сообщить игроку начать воспроизведение через 3 секунды.

Если вы используете последнюю версию ffmpeg из git master, она сделает это с помощью списка редактирования при вызове с помощью предоставленной вами команды. Если это не работает для вас, то вы, вероятно, используете старую версию ffmpeg, или ваш плеер не поддерживает редактирование списков. Некоторые проигрыватели игнорируют список редактирования и всегда воспроизводят все медиафайлы в файле от начала до конца.

Если вы хотите точно вырезать, начиная с не ключевого кадра, и хотите, чтобы оно воспроизводилось, начиная с нужной точки на проигрывателе, который не поддерживает списки редактирования, или хотите убедиться, что вырезанная часть фактически не находится в выходном файле (например, если он содержит конфиденциальную информацию), то вы можете сделать это путем перекодирования, чтобы ключевой кадр был точно в желаемое время начала. Перекодировка используется по умолчанию, если вы не укажете copy, Например:

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

При перекодировании вы также можете включить дополнительные параметры, связанные с качеством, или конкретный кодер AAC. Для получения дополнительной информации см. Руководство по кодированию x264 для видео ffmpeg и Руководство по кодированию AAC для аудио.

Так же -t Опция указывает продолжительность, а не время окончания. Приведенная выше команда будет кодировать 8 секунд видео, начиная с 3 секунд. Для начала в 3 с и окончания в 8 с используйте -t 5, Если вы используете текущую версию ffmpeg, вы также можете заменить -t с -to в приведенной выше команде, чтобы закончить в указанное время.

Попробуйте использовать это. Это самый быстрый и лучший способ ffmpeg, который я понял:

 ffmpeg -ss 00:01:00 -i input.mp4 -to 00:02:00 -c copy output.mp4

Эта команда обрезает ваше видео в считанные секунды!

Я объяснил это в моем блоге здесь:

-i: указывает входной файл. В этом случае это (input.mp4).
-ss: используется с -i, ищет во входном файле (input.mp4) позицию.
00:01:00: это время, когда начинается ваше обрезанное видео.
-to: Указывает продолжительность от начала (00:01:40) до конца (00:02:12).
00:02:00: время, когда закончится ваше обрезанное видео.
-c копия: это опция для обрезки через потоковое копирование. (NB: очень быстро)

Формат синхронизации: чч: мм: сс

Обратите внимание, что текущий ответ с высоким рейтингом устарел, и обрезка будет крайне медленной. Для получения дополнительной информации посмотрите эту официальную статью ffmpeg.

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -c copy cut.mp4 

Используйте -c copy для быстрого создания. В этом случае ffmpeg не перекодирует видео, а просто обрезает его в соответствии с размером.

Вот что я использую, и для запуска потребуется всего несколько секунд:

ffmpeg -i input.mp4 -ss 01:19:27 -to 02:18:51 -c:v copy -c:a copy output.mp4

Создано mp4 файлы также могут использоваться в iMovie.

Ссылка: https://www.arj.no/2018/05/18/trimvideo

Дополнительная информация, связанная с получением полной продолжительности с использованием модели get_duration(input_video).


Если вы хотите объединить несколько кат-сцен, вы можете использовать следующий скрипт Python (cut.py):

#!/usr/bin/env python3

import subprocess


def get_duration(input_video):
    cmd = ["ffprobe", "-i", input_video, "-show_entries", "format=duration",
           "-v", "quiet", "-sexagesimal", "-of", "csv=p=0"]
    return subprocess.check_output(cmd).decode("utf-8").strip()


if __name__ == "__main__":
    name = "input.mkv"

    times = []
    times.append(["00:00:00", "00:00:10"])
    times.append(["00:06:00", "00:07:00"])

    # times = [["00:00:00", get_duration(name)]]

    if len(times) == 1:
        time = times[0]
        cmd = ["ffmpeg", "-i", name, "-ss", time[0], "-to", time[1], "-c:v", "copy", "-c:a", "copy", "output.mp4"]
        subprocess.check_output(cmd)
    else:
        open('concatenate.txt', 'w').close()
        for idx, time in enumerate(times):
            output_filename = f"output{idx}.mp4"
            cmd = ["ffmpeg", "-i", name, "-ss", time[0], "-to", time[1], "-c:v", "copy", "-c:a", "copy", output_filename]
            subprocess.check_output(cmd)

            with open("concatenate.txt", "a") as myfile:
                myfile.write(f"file {output_filename}\n")

        cmd = ["ffmpeg", "-f", "concat", "-i", "concatenate.txt", "-c", "copy", "output.mp4"]
        output = subprocess.check_output(cmd).decode("utf-8").strip()


Если вы хотите вырезать видео целиком (если вы хотите конвертировать mkv форматировать в mp4) просто раскомментируйте следующую строку:

# times = [["00:00:00", get_duration(name)]]
    ffmpeg -i movie.mp4 -vf trim=3:8 cut.mp4

Бросьте все, кроме второго 3 до второго 8.

Чтобы вырезать на основе начального и конечного времени исходного видео и избежать необходимости выполнять математические операции, укажите конечное время в качестве параметра ввода и начальное время в качестве параметра вывода.

ffmpeg -t 1:00 -i input.mpg -ss 45 output.mpg

Это произведет 15-секундное сокращение с 0:45 до 1:00.

Это потому что когда -ss задается как опция вывода, выброшенное время все еще включается в общее время, считываемое с входа, которое -t использует, чтобы знать, когда остановиться. Тогда как если -ss задается как опция ввода, время начала ищется, а не подсчитывается, откуда и возникает путаница.

Это медленнее, чем поиск, так как пропущенный сегмент все еще обрабатывается перед тем, как быть сброшенным, но это единственный способ сделать это, насколько я знаю. Если вы вырезаете изнутри большого файла, более разумно просто посчитать и использовать -ss для ввода.

Используйте -to вместо -t: -to указывает время окончания, -t указывает продолжительность

Моя установка:

      $ ffmpeg
ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 12.0.5 (clang-1205.0.22.9)

Я обнаружил, что порядок переключателей имеет значение. Если -i не между -ss а также -t затем в результате я получил пробел на 3 секунды впереди.

Итак, какие бы дополнительные переключатели вы ни использовали, убедитесь, что вы установили эти три переключателя в правильном порядке, как это

      ffmpeg -ss 00:00:03 -i movie.mp4 -t 00:00:08 cut.mp4

Меня интересовало время обрезки в миллисекундах, и я заметил, что секунды (и доли от них) можно указать для обрезки следующим образом:

      ffmpeg -i input.mp4 -ss 17.5 -to 20.5 output.mp4

Для продолжительности, а не конечного времени, используйте -tвместо -to:

      ffmpeg -i input.mp4 -ss 17.5 -t 3 output.mp4

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

  • transcode.sh Управляет транскодированием, включая извлечение клипов.
  • ff-segmenter.sh Внешний интерфейс, в котором вы можете указать, где начинается и заканчивается реклама (или сегменты).

Поместите оба скрипта на свой путь... и...

      # Cut out everything from (3min 12.345s to 4min 1s) and (1hour 48min 0.2s to 1hour 52min 43.0s)
ff-segmenter.sh -i "input.mp4" -o "output.mp4" -x -s 3:12.345-4:01 -s 1:48:00.2-1:52:43

Без-xпереключатель, выбор инвертируется. Таким образом, все, что не входит в список вырезок, отбрасывается. -hпереключатель объясняет.

Не стесняйтесь использовать этот инструмент https://github.com/rooty0/ffmpeg_video_cutter Я писал некоторое время назад В значительной степени это интерфейс cli для ffmpeg... вам просто нужно создать yaml, что вы хотите вырезать... что-то нравится

cut_method: delete  # we're going to delete following video fragments from a video
timeframe:
  - from: start   # waiting for people to join the conference
    to: 4m
  - from: 10m11s  # awkward silence
    to: 15m50s
  - from: 30m5s   # Off-Topic Discussion
    to: end

а затем просто запустите инструмент, чтобы получить результат

Во-первых, видео должно быть закодировано с помощью кодировщика ffvhuff, чтобы видео можно было обрезать точно в момент начала и окончания. Обычно с другими приведенными выше командами возможно, что видео не обрезается до определенной продолжительности, поскольку не каждый кадр является кадром с внутренним кодированием.

      ffmpeg -ss 00:03:00 -i input_file.mkv -t 00:01:19 -c:v ffvhuff -pix_fmt yuv420p -y output_file.mkv

Используя библиотеку ffmpeg-python, я сделал это так.. но вы должны удалить ffmpeg перед установкой ffmpeg-library.. см. мой github для получения более подробной информации. https://github.com/johntsunami/ffmpeg-python-video-trimmer/blob/main/trimmer.py

      sys.path.append(r"C:\Users\johnc\Desktop\ffmpeg\bin")
stream = ffmpeg.input(r"C:/Users/johnc/Desktop/krystal.mp4",ss=57, t=55)  # ss is start time,  t IS DURATION

## SEPARATES AUDIO AND VIDEO INDEPENDENTLY BECAUSE SOMETIMES IT DOESNT HAVE AUDIO UNLESS YOU DO THIS>

audio = stream.audio 
video = stream.video   #.trim(start=60,end=115).filter('setpts','PTS-STARTPTS') ## CURRENTLY IS GOOD BUT DOESNT CUT DURATION AFTER 55 seconds

#overwrite_output overwrites it automatically if i dont want it just use output
stream = ffmpeg.output(audio, video, r'C:\Users\johnc\Desktop\output.mp4')


ffmpeg.run(stream)

Несмотря на то, что я опоздал на 6 лет, я думаю, что все приведенные выше ответы не соответствуют вопросу, который Kalai. Приведенный ниже сценарий bash обработает текстовый файл в следующем формате:

URL | start_time | end_time | filename

например

https://www.youtube.com/watch?v=iUDURCrvrMI|00:02:02|00:03:41|1

и прокрутите файл, загружает файл, который youtube-dl поддерживает, рассчитывая продолжительность между start_time а также end_time и передать его ffmpeg, поскольку -tна самом деле продолжительность, а не реальнаяend_time

Напишите мне, если у вас есть вопросы.

    for i in $(<video.txt);
    do
        URL=`echo $i | cut -d "|" -f 1`;
        START=`echo $i | cut -d "|" -f 2`;
        END=`echo $i | cut -d "|" -f 3`;
        FILE=`echo $i | cut -d "|" -f 4`;

        SEC1=`echo $START | sed 's/^/((/; s/:/)*60+/g' | bc`
        SEC2=`echo $END | sed 's/^/((/; s/:/)*60+/g' | bc`

        DIFFSEC=`expr ${SEC2} - ${SEC1}`

        ffmpeg $(youtube-dl -g $URL | sed "s/.*/-ss $START -i &/") -t $DIFFSEC -c copy $FILE".mkv";
        ffmpeg -i $FILE".mkv" -f mp3 -ab 192000 -vn $FILE".mp3";
        rm $FILE".mkv";
    done;
Другие вопросы по тегам