Обрезка видео по времени начала и окончания с помощью 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;