1
0
Fork 0
ffmpeg_concat/ffmpeg.sh

130 lines
3.6 KiB
Bash
Executable File

#!/bin/zsh -f
# vi:spl=fr
# NB :
# Lorsque l'on passe une variable en tant que paramètre à un programme externe,
# ZSH protège les espaces de cette variable (comme si tout son contenu était
# encadré par des guillemets).
# Il faut alors utiliser la syntaxe ${=MA_VAR} pour que les espaces servent de
# séparateurs (comme si on avait directement tapé le contenu). Malheureusement,
# si un des champs est un nom de fichier avec des espaces, on se retrouve avec
# 2 champs séparés.
# Dans ce cas, le plus simple est de stocker chaque champ comme élément séparé
# d'un tableau. ZSH sait alors exactement comment passer les champs au programme.
# Pour initialiser une variable avec un tableau, il suffit d'encadrer le
# contenu entre parenthèses.
# +-----------------------+
# ! !
# ! V1F !
# ! !
# +-------+-------+-------+
# ! V2F ! V3F ! V4F !
# +-------+-------+-------+
FOLDER="$HOME/Video"
V1F="$FOLDER/HPIM0037.mov"
V1_pre=''
V1_time='5.5'
V2F="$FOLDER/HPIM0038.mov"
V2_pre=''
V2_time='3.25'
V3F="$FOLDER/HPIM0039.mov"
V3_pre=''
V3_time='0.0'
V4F="$FOLDER/HPIM0040.mov"
V4_pre='crop=iw*3/4:ih:0:0,rotate=PI,'
V4_time='7.7'
# Durée de la vidéo en sortie
# Format = [HH:]MM:SS[.m...] ou S+[.m...]
VOUT_duration='9.5'
# 0 => Affiche avec ffplay ce que ça *devrait* rendre (pas tout à fait équivalent)
# 1 => Encode la vidéo avec ffmpeg
encode=1
# Largeur de la vidéo résultante
W_out=1174
# Hauteur de la ligne des 3 vidéos
H_outL=240
# 1 => génère des vidéos, à partir des originales, avec un TimeStamp incrusté
# -> Utile pour la mise au point des valeurs de debut (-ss)
create_tsvid=0
# Pour utiliser les vidéos incrustées à la place des vidéos originales
use_tsvid=1
if (( $create_tsvid )); then
# Commande pour incruster le texte
DRAW_TEXT="drawtext=text='%{pts\:hms\:0}':fontcolor=red:fontsize=50:shadowx=3:shadowy=2:x=(w-tw)/2:y=h/3"
# Commande pour générer une "keyframe" toutes les secondes
# -> indispensable pour avoir un minimum de précision sur l'option "-ss" avec ffplay.
FORCE_KF=( '-force_key_frames' 'expr:gte(t,n_forced*1)' )
ffmpeg -hide_banner -i $V1F -vf "${V1_pre}${DRAW_TEXT}" $FORCE_KF ${V1F}.mkv
ffmpeg -hide_banner -i $V2F -vf "${V2_pre}${DRAW_TEXT}" $FORCE_KF ${V2F}.mkv
ffmpeg -hide_banner -i $V3F -vf "${V3_pre}${DRAW_TEXT}" $FORCE_KF ${V3F}.mkv
ffmpeg -hide_banner -i $V4F -vf "${V4_pre}${DRAW_TEXT}" $FORCE_KF ${V4F}.mkv
fi
if (( $use_tsvid )); then
V1F=${V1F}.mkv
V2F=${V2F}.mkv
V3F=${V3F}.mkv
V4F=${V4F}.mkv
V1_pre=''
V2_pre=''
V3_pre=''
V4_pre=''
fi
if (( $encode )); then
CMD='ffmpeg'
# Les noms des fichiers peuvent contenir des espaces, donc on utilise un tableau pour séparer les entrées
INPUTS=( '-ss' $V1_time '-i' $V1F '-ss' $V2_time '-i' $V2F '-ss' $V3_time '-i' $V3F '-ss' $V4_time '-i' $V4F )
FILTER_OPT='-filter_complex'
OUTPUT=( '-to' $VOUT_duration "$(date +%Y-%m-%d_%H-%M-%S).mkv" )
else
CMD='ffplay'
INPUTS=( '-ss' $V1_time $V1F '-noframedrop' )
FILTER_OPT='-vf'
V2_time=$(( $V1_time - $V2_time ))
V3_time=$(( $V1_time - $V3_time ))
V4_time=$(( $V1_time - $V4_time ))
V2_pre="movie=${V2F}, setpts=PTS+${V2_time}/TB, ${V2_pre}"
V3_pre="movie=${V3F}, setpts=PTS+${V3_time}/TB, ${V3_pre}"
V4_pre="movie=${V4F}, setpts=PTS+${V4_time}/TB, ${V4_pre}"
fi
$CMD -hide_banner $INPUTS $FILTER_OPT "\
\
${V1_pre}scale=${W_out}:-1 [V1]; \
${V2_pre}scale=-1:${H_outL} [V2]; \
${V3_pre}scale=-1:${H_outL} [V3]; \
${V4_pre}scale=-1:${H_outL} [V4]; \
\
[V2][V3][V4] hstack=3 [VL]; \
\
[V1][VL] vstack=shortest=1 \
" \
$OUTPUT