Je souhaite diviser une grande vidéo AVI en deux vidéos consécutives plus petites. J'utilise ffmpeg.
Une façon est d'exécuter ffmpeg deux fois:
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
Mais selon la page de manuel de ffmpeg, je peux créer plusieurs fichiers de sortie à partir d’un fichier d’entrée en utilisant seulement un ligne:
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
Ma question est la suivante: l'approche ultérieure permet-elle de gagner du temps de calcul et de la mémoire?
Le wiki ffmpeg renvoie à cette page en référence à "Comment fractionner une vidéo efficacement". Je ne suis pas convaincu que cette page réponde à cette question. J'ai donc suivi les suggestions de @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
Quelles sorties ...
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
J'ai testé un fichier SD & HD, après quelques essais et un peu de maths.
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
Fichier SD = 1,35 Go de flux de transport DVB
Fichier HD = 3,14 Go de flux de transport DVB
La commande unique est préférable si vous utilisez HD, elle est conforme aux commentaires des manuels sur l’utilisation de -ss après le fichier d’entrée pour effectuer une recherche lente. Les fichiers SD ont une différence négligeable.
La version à deux commandes devrait être plus rapide en ajoutant un autre -ss avant le fichier d'entrée pour la recherche rapide suivie de la recherche lente plus précise.
Voici un script utile, il vous aide à scinder automatiquement: Un script pour scinder des vidéos avec 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
http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg peut également vous être utile. De plus, ffmpeg a un multiplexeur de segment qui pourrait fonctionner.
Quoi qu'il en soit, je pense que les combiner en une seule commande permettrait de gagner du temps.
D'après mon expérience, n'utilisez pas ffmpeg pour scinder/rejoindre. MP4Box, est plus rapide et léger que ffmpeg. S'il vous plaît tryit . Par exemple, si vous voulez diviser un fichier MP4 1400mb en deux parties un 700mb vous pouvez utiliser le cmdl suivant: MP4Box -splits 716800 input.mp4
eg pour concaténer deux fichiers que vous pouvez utiliser:
MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4
Ou si vous avez besoin d'une division par heure, utilisez -splitx StartTime:EndTime
:
MP4Box -add input.mp4 -splitx 0:15 -new split.mp4
la dernière approche permet-elle d’économiser du temps de calcul et de la mémoire?
Il n'y a pas de grande différence entre ces deux exemples que vous avez fournis. Le premier exemple coupe la vidéo séquentiellement, en 2 étapes, tandis que le deuxième exemple le fait en même temps (en utilisant des threads). Aucune accélération particulière ne sera perceptible. Vous pouvez en savoir plus sur créer plusieurs sorties avec FFmpeg
De plus, vous pouvez utiliser (dans FFmpeg récent) le segmenteur de flux muxer qui peut:
les flux de sortie vers un certain nombre de fichiers distincts d’une durée presque fixe. Le modèle de nom de fichier de sortie peut être défini de la même manière que image2 .
Voici un fichier de batte Windows simple pour scinder le fichier entrant en 50 parties. Chaque partie dure 1 minute. Désolé pour ce script stupide. J'espère qu'il est préférable d'avoir un script Windows stupide plutôt que de ne pas l'avoir du tout. Peut-être que cela aidera quelqu'un . (Basé sur "bat file for loop" de ce 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
Voici un moyen idéal pour diviser la vidéo. Je l'ai déjà fait et ça marche bien pour moi.
ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4
(pour 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')
(pour php).
Veuillez suivre ceci et je suis sûr que cela fonctionnera parfaitement.
Je n'ai pas testé, mais cela semble prometteur:
Il s'agit évidemment de diviser l'AVI en segments de même taille, ce qui implique que ces morceaux ne perdent pas en qualité, n'augmentent pas la mémoire ou doivent être recalculés.
Il utilise également la copie de codec - cela signifie-t-il qu'il peut gérer des flux très volumineux? Parce que c'est mon problème, je veux décomposer mon avi afin que je puisse utiliser un filtre pour se débarrasser de la distorsion. Mais tout un avi dure des heures.