commit 14eecc515c5c8076ea87f51a18d1d97e47abc2ba Author: Michel Date: Sun Mar 13 11:43:27 2022 +0100 Script créé en 2019... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34e32b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.avi +*.mkv +*.MOV +*.mp4 +*.MP4 diff --git a/LICENSE_WTFPLv2.txt b/LICENSE_WTFPLv2.txt new file mode 100644 index 0000000..ee7d6a5 --- /dev/null +++ b/LICENSE_WTFPLv2.txt @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..8383be7 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,31 @@ +# Script pour assembler plusieurs videos avec ffmpeg + +La configuration actuelle permet de générer une seule vidéo à partir de 4 +vidéos indépendantes. + +``` ++-----------------------+ +! ! +! V1F ! +! ! ++-------+-------+-------+ +! V2F ! V3F ! V4F ! ++-------+-------+-------+ +``` + +Les vidéos n'ont pas besoin d'avoir des durées _compatibles_, ni d'être +synchronisées. +Dans les paramètres du script, on fournit la durée de la vidéo en sortie ainsi +que le décalage initial (_offset_) de chacune des vidéos entrantes. + +Il faut par contre que les tailles des vidéos soit compatibles entre elles. +Mais il est possible de fournir un _pré-filtre_ à chaque flux pour couper, +positionner, tourner, etc. la vidéo. + +Il est également possible de générer de nouvelles vidéos avec des _Time Stamps_ +incrustés ; ce qui est utile pour la mise au point des valeurs de début. + +Enfin, il est aussi possible d'utiliser `ffplay` pour obtenir un rendu rapide. + + + diff --git a/Video. Jame Fenton, CC BY-SA.svg b/Video. Jame Fenton, CC BY-SA.svg new file mode 100644 index 0000000..409526a --- /dev/null +++ b/Video. Jame Fenton, CC BY-SA.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/ffmpeg.ps1 b/ffmpeg.ps1 new file mode 100755 index 0000000..2e1ec7a --- /dev/null +++ b/ffmpeg.ps1 @@ -0,0 +1,118 @@ +#!pwsh -f + + +# +-----------------------+ +# ! ! +# ! V1F ! +# ! ! +# +-------+-------+-------+ +# ! V2F ! V3F ! V4F ! +# +-------+-------+-------+ + +$FOLDER="$HOME/Downloads" + +$V1F="$FOLDER/sc4_ext.MOV" +$V1_pre='' +$V1_time='5.5' + +$V2F="$FOLDER/sc4_int.avi" +$V2_pre='' +$V2_time='3.25' + +$V3F="$FOLDER/sc4_sui.mp4" +$V3_pre='' +$V3_time='0.0' + +$V4F="$FOLDER/sc4_GOPRO.MP4" +$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='19.5' + + +# 0 => Affiche avec ffplay ce que ça *devrait* rendre (pas tout à fait équivalent) +# 1 => Encode la vidéo avec ffmpeg +$encode=0 + +# Largeur de la vidéo résultante +$W_out=1024 + +# 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=1 + +# Pour utiliser les vidéos incrustées à la place des vidéos originales +$use_tsvid=1 + + +if ( $create_tsvid -eq 1 ) +{ + + # 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' +} + +if ( $use_tsvid ) +{ + $V1F=$V1F + '.mkv' + $V2F=$V2F + '.mkv' + $V3F=$V3F + '.mkv' + $V4F=$V4F + '.mkv' + $V1_pre='' + $V2_pre='' + $V3_pre='' + $V4_pre='' +} + + +if ( $encode ) +{ + $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, ((Get-Date -format 'yyyy-MM-dd_HH-mm-ss')+'.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" +} + +& $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 diff --git a/ffmpeg.sh b/ffmpeg.sh new file mode 100755 index 0000000..a29c19f --- /dev/null +++ b/ffmpeg.sh @@ -0,0 +1,129 @@ +#!/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