it-swarm.com.de

FFmpeg: Wie kann ich Videos effizient teilen?

Ich möchte ein großes AVI-Video in zwei kleinere aufeinanderfolgende Videos aufteilen. Ich benutze ffmpeg.

Eine Möglichkeit ist, ffmpeg zweimal auszuführen:

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

Laut Manpage von ffmpeg kann ich jedoch aus einer Eingabedatei mit nur one line mehrere Ausgabedateien erstellen:

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

Meine Frage ist, spart der spätere Ansatz Rechenzeit und Speicherplatz?

90
Antony

Das ffmpeg-Wiki verweist auf diese Seite in Bezug auf "So teilen Sie Video effizient auf". Ich bin nicht überzeugt, dass diese Seite diese Frage beantwortet, also habe ich @AlcubierreDrive vorgeschlagen…

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

Welche Ausgänge ...

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

Ich habe eine SD- & HD-Datei getestet, nach ein paar Läufen und ein paar Berechnungen.

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-Datei = 1.35 GB DVB-Transportstream
HD-Datei = 3.14GB DVB-Transportstrom

Fazit

Der Einzelbefehl ist besser, wenn Sie mit HD arbeiten. Er stimmt mit den Kommentaren der Handbücher überein, dass -ss nach der Eingabedatei für eine 'langsame Suche' verwendet wird. SD-Dateien haben einen geringfügigen Unterschied.

Die Version mit zwei Befehlen sollte schneller sein, indem Sie vor der Eingabedatei ein weiteres -ss für den 'schnellen Suchlauf' gefolgt vom genaueren langsamen Suchlauf hinzufügen.

74
user2867531

Hier ist ein nützliches Skript, das Ihnen beim automatischen Aufteilen hilft: Ein Skript zum Aufteilen von Videos mit 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
19
Marco C.

http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg kann auch für Sie nützlich sein. Auch ffmpeg hat einen Segmentmuxer, der funktionieren könnte.

Ich vermute jedenfalls, dass die Kombination dieser Befehle Zeit spart.

5
rogerdpack

Verwenden Sie nach meiner Erfahrung ffmpeg nicht zum Teilen/Verbinden. MP4Box ist schneller und leichter als ffmpeg. Bitte tryit . Wenn Sie beispielsweise eine MP4-Datei mit 1400 MB in zwei Teile mit 700 MB aufteilen möchten, können Sie die folgende Cmdl verwenden: MP4Box -splits 716800 input.mp4eg zum Verketten zweier Dateien, die Sie verwenden können:

MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4

Oder wenn Sie nach Zeit teilen müssen, verwenden Sie -splitx StartTime:EndTime:

MP4Box -add input.mp4 -splitx 0:15 -new split.mp4

5
Classsic

spart der spätere Ansatz Rechenzeit und Speicher?

Es gibt keinen großen Unterschied zwischen diesen beiden Beispielen, die Sie zur Verfügung gestellt haben. Im ersten Beispiel wird das Video sequenziell in zwei Schritten geschnitten, im zweiten Beispiel zur gleichen Zeit (unter Verwendung von Threads). Es wird keine besondere Beschleunigung spürbar. Lesen Sie mehr über Erstellen mehrerer Ausgaben mit FFmpeg

Darüber hinaus können Sie (in letzter Zeit FFmpeg) den stream segmenter muxer verwenden, der

ausgabe-Streams in eine Reihe von separaten Dateien von nahezu fester Dauer. Das Dateinamensmuster der Ausgabe kann auf ähnliche Weise wie image2 eingestellt werden.

1
Mladen B.

Hier ist eine einfache Windows-Bat-Datei, um die eingehende Datei in 50 Teile aufzuteilen. Jeder Teil hat eine Länge von 1 Minute. Entschuldigung für so ein dummes Skript. Ich hoffe, es ist besser, ein dummes Windows-Skript zu haben, als es überhaupt nicht zu haben. Vielleicht hilft es jemandem. (Basierend auf "bat file for loop" von dieser Site.)

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
1
Alex Bor

Hier ist eine perfekte Möglichkeit, das Video zu teilen. Ich habe es schon einmal gemacht und es funktioniert gut für mich.

ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4 (für 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') (für PHP).

Bitte folgen Sie diesem und ich bin sicher, dass es perfekt funktioniert.

0
Atul Upadhyay

Hab nicht getestet, aber das sieht vielversprechend aus:

Grundstrom-Segmentierer

Es ist offensichtlich, dass AVI in Segmente gleicher Größe aufgeteilt wird, was bedeutet, dass diese Chunks keine Qualität verlieren oder den Speicher nicht erhöhen oder neu berechnet werden müssen.

Es verwendet auch die Codec-Kopie - bedeutet das, dass sehr große Streams verarbeitet werden können? Da dies mein Problem ist, möchte ich mein avi aufteilen, so dass ich einen Filter verwenden könnte, um die Verzerrung zu beseitigen. Aber eine ganze Avi läuft stundenlang.

0
Mathias Weitz