Видео: как эффективно разделить видео?
Я хочу разделить большое видео 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
но согласно manpage 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
мой вопрос в том, экономит ли более поздний подход время и память вычислений?
10 ответов:
ffmpeg wiki ссылается на эту страницу в разделе "Как эффективно разделить видео". Я не уверен, что эта страница отвечает на этот вопрос, поэтому я сделал так, как предложил @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 winsSD file = 1.35 GB DVB транспортный поток
в HD = 3,14 ГБ DVB транспорт потоквывод
одна команда лучше, если вы обрабатываете HD, она согласуется с комментариями руководства по использованию-ss после входного файла для выполнения "медленного поиска". SD-файлы имеют незначительную разницу.
две версии команд должны быть быстрее, добавив еще один-ss перед входным файлом для "быстрого поиска", за которым следует более точный медленный поиск.
вот полезный скрипт, он поможет вам разделить автоматически:скрипт для разбиения видео с помощью 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="" OUT_FILE_FORMAT="" typeset -i CHUNK_LEN CHUNK_LEN="" 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]\+\)$//') FILE_NAME=$(echo "$IN_FILE" | sed 's/^\(.*\)\.[a-zA-Z0-9]\+$//') 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
http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg также может быть полезным для вас. Также ffmpeg имеет сегментный muxer, который может работать.
в любом случае я предполагаю, что объединение их в одну команду сэкономит время.
по моему опыту, не используйте ffmpeg для разделения / объединения. MP4Box, быстрее и легче, чем ffmpeg. Пожалуйста, попробуйте. Например, если вы хотите разделить файл 1400MB MP4 на две части 700mb, вы можете использовать следующий cmdl:
MP4Box -splits 716800 input.mp4например, для объединения двух файлов вы можете использовать:MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4
вот простой файл Windows bat для разделения входящего файла на 50 частей. Каждая часть имеет длину 1 минуту. Извините за такой тупой сценарий. Я надеюсь, что лучше иметь тупой скрипт windows, а не не иметь его вообще. Возможно, это кому-то поможет. (На основе "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
позволяет ли более поздний подход экономить время вычислений и память?
нет большой разницы между этими двумя примерами, которые вы предоставили. Первый пример режет видео последовательно, в 2 шага, в то время как второй пример делает это одновременно (с использованием потоков). Никакого особого ускорения не будет заметно. Вы можете прочитать больше о создание нескольких выходов с помощью FFmpeg
более того, то, что вы можете использовать (в недавнем FFmpeg) является stream segmenter muxer что можно:
выходные потоки в несколько отдельных файлов почти фиксированной продолжительности. Шаблон выходного имени файла может быть установлен аналогично image2.
вот идеальный способ разделить видео. Я сделал это раньше, и это хорошо работает для меня.
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).пожалуйста, следуйте этому, и я уверен, что он будет работать отлично.
не тестировал ist, но это выглядит многообещающе:
очевидно, что разделение AVI на сегменты одинакового размера, что означает, что эти куски не теряют качество или увеличивают память или должны быть пересчитаны.
Он также использует копию кодека - означает ли это, что он может обрабатывать очень большие потоки ? Поскольку это моя проблема, я хочу сломать свой avi, чтобы я мог использовать фильтр, чтобы избавиться от искажения. Но в целом Ави работает в течение нескольких часов.
один простой способ-использовать опцию обрезки с publitio url-API на основе.
Как только вы загрузите свое видео, просто установите начальное смещение и конечное смещение в url (so_2, eo_2) следующим образом:
https://media.publit.io/file/so_2,eo_2/tummy.mp4Это позволит мгновенно создавать новые видео, начиная со 2-й секунды и 2 секунд в длину. вы можете разделить видео таким образом, как вам нравится.
оказывается, что размер(ы) файла в более позднем случае будет пропорционально эквивалентен временному срезу.
Comments