J'ai un gros fichier vidéo (large.mp4
) et un fichier de sous-titres correspondant (large.srt
).
Quel est le meilleur moyen de scinder les deux fichiers en n parties égales?
Cela produira large-1.mp4
, ..., large-n.mp4
et large-1.srt
, ..., large-n.srt
. Et tous ces fichiers auront la même taille (sauf les derniers).
Quel est le meilleur moyen de scinder les deux fichiers en parties d’une durée spécifique, par exemple 15 minutes?
La sortie sera similaire à celle indiquée ci-dessus.
Je voudrais utiliser un outil de ligne de commande, de préférence ffmpeg
et de préférence la commande directe, sans script.
Une tâche aussi complexe que celle-ci (à ma connaissance) ne peut pas être effectuée avec ffmpeg
seul et en un seul appel, mais j'ajouterai une version en ligne ci-dessous. Voici la version du script:
#!/bin/bash
in=$1
dur=$2
totaldur=$(ffprobe -v -8 -show_entries format=duration -of flat large.mp4 | sed -r 's/.*"([0-9]+).*/\1/')
i=0
while (( i * dur < totaldur) )
do
ffmpeg -i $in -i ${in%%.*}.srt \
-ss $((i*dur)) -t $dur -c copy -sn ${in%%.*}-$((i+1)).${in#*.} \
-ss $((i*dur)) -t $dur -an -vn ${in%%.*}-$((i+1)).srt
((i++))
done
Ce script prend deux arguments, le premier étant le nom de fichier de la vidéo et le second la durée en secondes, voir l'exemple ci-dessous. Il dirige d'abord la sortie de ffprobe
vers sed
pour obtenir la durée totale de la vidéo en secondes. Cette valeur est utilisée pour créer une boucle while
pour les parties. À l'intérieur de la boucle, ffmpeg
est appelé pour créer les parties, à la fois le .mp4
et le .srt
en un seul appel.
$ tree # the directory contains large.mp4 and large.srt
.
├── large.mp4
└── large.srt
$ ffmpeg -i large.mp4 |& awk '/Duration/' # large.mp4 has a duration of 00:02:30.07
Duration: 00:02:30.07, start: 0.000000, bitrate: 1283 kb/s
$ /path/to/above/script large.mp4 60 # let's split it after every 60 seconds
$ tree
.
├── large-1.mp4
├── large-1.srt
├── large-2.mp4
├── large-2.srt
├── large-3.mp4
├── large-3.srt
├── large.mp4
└── large.srt
Les deux premières variables contiennent le nom du fichier et la durée en secondes, ajustez-les à vos besoins.
in=large.mp4;dur=60;i=0;while ((i*dur<$(ffprobe -v -8 -show_entries format=duration -of flat large.mp4|sed -r 's/.*"([0-9]+).*/\1/')));do ffmpeg -y -i $in -i ${in%%.*}.srt -ss $((i*dur)) -t $dur -c copy -sn ${in%%.*}-$((i+1)).${in#*.} -ss $((i*dur)) -t $dur -an -vn ${in%%.*}-$((i+1)).srt;((i++));done
Voici quelques liens que j'ai trouvés sur le chemin: