FFmpeg: Как эффективно разделить видео?
Я хочу разбить большое avi-видео на два меньших последовательных видео. Я использую ffmpeg.
Один из способов - запустить ffmpeg два раза:
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi
Но, согласно man-странице ffmpeg, я могу сделать несколько файлов с одним входным файлом, используя только строку одна:
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi \
-vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi
Мой вопрос в том, поддерживает ли более поздний подход время вычисления и память?
Ответы
Ответ 1
Ссылка ffmpeg ссылается на эту страницу в разделе "Как эффективно разделить видео". Я не убежден, что эта страница отвечает на этот вопрос, поэтому я сделал это как @AlcubierreDrive...
echo "Two commands"
time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 -sn test1.mkv
time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test2.mkv
echo "One command"
time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 \
-sn test3.mkv -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test4.mkv
Какие выходы...
Two commands
real 0m16.201s
user 0m1.830s
sys 0m1.301s
real 0m43.621s
user 0m4.943s
sys 0m2.908s
One command
real 0m59.410s
user 0m5.577s
sys 0m3.939s
Я тестировал SD и HD файл, после нескольких прогонов и небольшой математики.
Two commands SD 0m53.94 #2 wins
One command SD 0m49.63
Two commands SD 0m55.00
One command SD 0m52.26 #1 wins
Two commands SD 0m58.60 #2 wins
One command SD 0m58.61
Two commands SD 0m54.60
One command SD 0m50.51 #1 wins
Two commands SD 0m53.94
One command SD 0m49.63 #1 wins
Two commands SD 0m55.00
One command SD 0m52.26 #1 wins
Two commands SD 0m58.71
One command SD 0m58.61 #1 wins
Two commands SD 0m54.63
One command SD 0m50.51 #1 wins
Two commands SD 1m6.67s #2 wins
One command SD 1m20.18
Two commands SD 1m7.67
One command SD 1m6.72 #1 wins
Two commands SD 1m4.92
One command SD 1m2.24 #1 wins
Two commands SD 1m1.73
One command SD 0m59.72 #1 wins
Two commands HD 4m23.20
One command HD 3m40.02 #1 wins
Two commands SD 1m1.30
One command SD 0m59.59 #1 wins
Two commands HD 3m47.89
One command HD 3m29.59 #1 wins
Two commands SD 0m59.82
One command SD 0m59.41 #1 wins
Two commands HD 3m51.18
One command HD 3m30.79 #1 wins
Файл SD= транспортный поток DVB 1.35GB
HD файл= 3.14GB Транспортный поток DVB
Заключение
Единственная команда лучше, если вы обрабатываете HD, она согласуется с комментариями руководства по использованию -ss после входного файла для "медленного поиска". Файлы SD имеют незначительную разницу.
Две версии команд должны быть быстрее, добавив еще один -ss перед входным файлом для быстрого поиска, за которым следует более точный медленный поиск.
Ответ 2
Здесь полезный script, он помогает вам автоматически разбивать: A script для разделения видео с помощью ffmpeg
#!/bin/bash
# Written by Alexis Bezverkhyy <[email protected]> in 2011
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>
function usage {
echo "Usage : ffsplit.sh input.file chunk-duration [output-filename-format]"
echo -e "\t - input file may be any kind of file reconginzed by ffmpeg"
echo -e "\t - chunk duration must be in seconds"
echo -e "\t - output filename format must be printf-like, for example myvideo-part-%04d.avi"
echo -e "\t - if no output filename format is given, it will be computed\
automatically from input filename"
}
IN_FILE="$1"
OUT_FILE_FORMAT="$3"
typeset -i CHUNK_LEN
CHUNK_LEN="$2"
DURATION_HMS=$(ffmpeg -i "$IN_FILE" 2>&1 | grep Duration | cut -f 4 -d ' ')
DURATION_H=$(echo "$DURATION_HMS" | cut -d ':' -f 1)
DURATION_M=$(echo "$DURATION_HMS" | cut -d ':' -f 2)
DURATION_S=$(echo "$DURATION_HMS" | cut -d ':' -f 3 | cut -d '.' -f 1)
let "DURATION = ( DURATION_H * 60 + DURATION_M ) * 60 + DURATION_S"
if [ "$DURATION" = '0' ] ; then
echo "Invalid input video"
usage
exit 1
fi
if [ "$CHUNK_LEN" = "0" ] ; then
echo "Invalid chunk size"
usage
exit 2
fi
if [ -z "$OUT_FILE_FORMAT" ] ; then
FILE_EXT=$(echo "$IN_FILE" | sed 's/^.*\.\([a-zA-Z0-9]\+\)$/\1/')
FILE_NAME=$(echo "$IN_FILE" | sed 's/^\(.*\)\.[a-zA-Z0-9]\+$/\1/')
OUT_FILE_FORMAT="${FILE_NAME}-%03d.${FILE_EXT}"
echo "Using default output file format : $OUT_FILE_FORMAT"
fi
N='1'
OFFSET='0'
let 'N_FILES = DURATION / CHUNK_LEN + 1'
while [ "$OFFSET" -lt "$DURATION" ] ; do
OUT_FILE=$(printf "$OUT_FILE_FORMAT" "$N")
echo "writing $OUT_FILE ($N/$N_FILES)..."
ffmpeg -i "$IN_FILE" -vcodec copy -acodec copy -ss "$OFFSET" -t "$CHUNK_LEN" "$OUT_FILE"
let "N = N + 1"
let "OFFSET = OFFSET + CHUNK_LEN"
done
Ответ 3
http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg также может быть вам полезен. Кроме того, ffmpeg имеет сегментный мультиплексор, который может работать.
В любом случае я предполагаю, что объединение их в одну команду позволит сэкономить время.
Ответ 4
По моему опыту, не используйте ffmpeg для разделения/соединения. MP4Box, быстрее и светлее ffmpeg. Пожалуйста, попробуйте. Например, если вы хотите разделить файл 1400mb MP4 на две части на 700 мб, вы можете использовать следующий cmdl: MP4Box -splits 716800 input.mp4
например, для конкатенации двух файлов, которые вы можете использовать:
MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4
Или, если вам нужно разделить по времени, используйте -splitx StartTime:EndTime
: -splitx StartTime:EndTime
:
MP4Box -add input.mp4 -splitx 0:15 -new split.mp4
Ответ 5
Вот простой файл bat для Windows, чтобы разбить входящий файл на 50 частей. Каждая часть имеет длину 1 минуту. Извините за такой немой script. Надеюсь, что лучше иметь немые окна script, а не иметь его вообще. Возможно, это помогает кому-то.
(Основано на "файле bat для цикла" с этого сайта.)
set var=0
@echo off
:start
set lz=
if %var% EQU 50 goto end
if %var% LEQ 9 set lz=0
echo part %lz%%var%
ffmpeg -ss 00:%lz%%var%:00 -t 00:01:00 -i %1 -acodec copy -vcodec copy %2_%lz%%var%.mp4
set /a var+=1
goto start
:end
echo var has reached %var%.
exit
Ответ 6
поддерживает ли более поздний подход время вычисления и память?
Нет большой разницы между этими двумя примерами, которые вы предоставили. Первый пример разрезает видео последовательно, в 2 этапа, в то время как второй пример делает это одновременно (используя потоки). Никакого особого ускорения не будет заметно. Вы можете больше узнать о создании нескольких выходов с помощью FFmpeg
Кроме того, вы можете использовать (в недавнем FFmpeg) потоковый мультиплексор потока, который может:
выводит потоки в несколько отдельных файлов почти фиксированной продолжительности. Вывод шаблона имени файла может быть установлен так же, как image2.
Ответ 7
Вот отличный способ разделить видео. Я делал это раньше, и он хорошо работает для меня.
ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4
(для CMD). shell_exec('ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4')
(для php).
Пожалуйста, следуйте этому, и я уверен, что он будет работать отлично.
Ответ 8
Не тестировал ist, но это выглядит многообещающим:
Основной сегмент потока
Это, очевидно, расщепление AVI на сегменты одинакового размера, что означает, что эти куски не теряют качество или увеличивают память или должны быть пересчитаны.
Он также использует копию кодека - означает ли это, что он может обрабатывать очень большие потоки? Поскольку это моя проблема, я хочу разбить мой avi, поэтому я могу использовать фильтр, чтобы избавиться от искажения. Но целый avi работает в течение нескольких часов.
Ответ 9
одним простым способом является использование опции обрезки с использованием api на основе url.
как только вы загрузите свое видео, просто установите смещение начала и конец смещения в url (so_2, eo_2) следующим образом:
https://media.publit.io/file/so_2,eo_2/tummy.mp4
это создаст мгновенно новые видео, начиная со второй секунды и 2 секунды в длину. вы можете разделить видео так, как вам нравится.
Ответ 10
Оказывается, что размер файла (ов) в более позднем случае будет пропорциональным эквиваленту временного фрагмента.