Script créé en 2019...
This commit is contained in:
commit
14eecc515c
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.avi
|
||||
*.mkv
|
||||
*.MOV
|
||||
*.mp4
|
||||
*.MP4
|
14
LICENSE_WTFPLv2.txt
Normal file
14
LICENSE_WTFPLv2.txt
Normal file
@ -0,0 +1,14 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
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.
|
||||
|
31
ReadMe.md
Normal file
31
ReadMe.md
Normal file
@ -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.
|
||||
|
||||
|
||||
<!-- vi:spl=fr -->
|
7
Video. Jame Fenton, CC BY-SA.svg
Normal file
7
Video. Jame Fenton, CC BY-SA.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="92.766px" viewBox="0 0 100 92.766" enable-background="new 0 0 100 92.766" xml:space="preserve">
|
||||
<polygon fill="#010101" points="43.633,54.597 43.633,79.294 65.023,66.961 "/>
|
||||
<path fill="#010101" d="M8.936,41.618l-2.401-9.013l12.82,7.413l14.827-3.963L13.439,24.101l15.654-4.204l20.803,12.006 l14.825-3.959L43.853,15.912l15.2-4.089L79.965,23.91l10.438-2.796l0.014,0.092l5.866-1.563l-3.01-11.252 C92.102,4.19,87.393-2.086,77.068,0.683L62.726,4.553L51.585,7.521l0.009,0.005l-15.168,4.09l-0.022-0.013L21.6,15.548l0.066,0.053 l-11.021,2.956C4.071,20.42-1.599,25.688,0.411,33.276l2.563,9.566v1.806v3.067v31.38c0.063,5.094,3.029,13.671,13.657,13.671h69.7 C91.421,92.684,100,89.74,100,79.095V41.618H8.936z M78.641,6.541c6.551-1.762,8.309,1.828,8.772,3.433l1.821,6.793l-15.423-8.93 L78.641,6.541z M93.934,79.095c0,6.755-5.35,7.584-7.627,7.603H16.632c-6.755,0-7.554-5.351-7.588-7.629V47.715h84.891V79.095z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
118
ffmpeg.ps1
Executable file
118
ffmpeg.ps1
Executable file
@ -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
|
129
ffmpeg.sh
Executable file
129
ffmpeg.sh
Executable file
@ -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
|
Loading…
Reference in New Issue
Block a user