Подтвердить что ты не робот

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

Мой вопрос в том, поддерживает ли более поздний подход время вычисления и память?

4b9b3361

Ответ 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

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