Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 06/05/2018, à 15:52

Lulux3

Télécharger et "en même temps" Encoder une Webvidéo: TEW.sh

Bonjour
J'utilise youtube-dl pour télécharger des vidéos, que je réencode en x265 pour économiser de l'espace disque.
Il est possible, grâce à ffmpeg, de réaliser l'encodage à la volée, ce qui économise pas mal de temps lorsqu'on a une connection un peu lente.
Cette manip est assez fastidieuses en ligne de commande, alors je me suis fait un petit script interactif pour simplifier tout ça.
Il se contente d'une url en paramètre (et en option un fichier de destination). Il récupère les données (dont les sous-titres si disponibles) avec youtube-dl, puis affiche un résumé.
On peut alors modifier chaque paramètre: choix de la qualité de la vidéo principale, choix des soustitres, ajouter un flux ou un fichier à muxer, mappage, et bien entendu codecs, destination et format.
Il y a aussi une fonction  de traitement des sous-titres: filtrage des sous-titres pour malentendants et/ou transcrption de vtt vers ass en conservant les styles et les couleurs.
Lorsque tout est OK, on lance le processus d'encodage, ou on le met en attente pour le lancer plus tard via un script.
On peut passer ensuite à une autre vidéo (par exemple l'épisode suivant d'une série), en gardant les mêmes réglages s'ils sont pertinents.
On peut donc en une seule opération, obtenir par exemple une vidéo multilingue avec sous-titres, encodée en x265.
Testé avec succès sur Arte et  France-tv, mais cela devrait marcher sur bien d'autres sites (en fait tous les sites sur lesquels youtube-dl est fonctionnel, dont bien sûr youtube)
Installation:
- Prérequis: youtube-dl et ffmpeg doivent être installés (dispos dans les dépots officiels).
- Copier le texte ci-dessous dans un éditeur de texte
- Adapter les paramètres par défaut selon vos préférences.
- Sauver, de préférence dans un répertoire dédié, sous le nom: TEW.sh, et donner le droit d'exécution.
Utilisation:
- Se rendre sur la page de la vidéo souhaitée, et copier l'url dans le presse papier,
- Ouvrir un terminal dans le répertoire où se trouve le script,
- Taper la commande:

./TEW.sh <url> 

- Vérifier les options résumées, et corriger si nécessaire en suivant les instructions.
- Lorsque tout est OK, on peut soit lancer directement le traitement, soit le mettre en attente, soit vérifier le résultat en affichant la ligne de commande, ou en lançant un test.
- Ensuite, un autre menu permet d'entrer une nouvelle URL, de gérer la liste d'attente, de l'exécuter directement ou de quitter.

N'hésitez pas à me faire part de vos remarques.

Le script :
édit mis à  jour le 12/05/2018
édit mis à  jour le 30/05/2018
édit mis à  jour le 10/09/2019
édit mis à  jour le 25/04/2020

#!/bin/bash
#!/bin/bash
# Téléchargement et Encodage simultané de Webvidéo.
# utilise youtube-dl (téléchargement) et ffmpeg (encodage).
# Mise à jour le 25 avril 2020
# Version en développement
# Usage: d_tew.sh [<url>]

#Variables par défaut
# Variables de couleur
	export DataCoul="\e[0;34m"
	export SurCoul="\e[1;34;43m"
	export NoCoul="\e[0m"
	export InfoCoul="\e[0;36m"
	export ErrCoul="\e[1;31m"
	export SaisCoul="\e[1;34;47m"
	export WarnCoul="\e[1;35m"
# Options vidéos par défaut (changer à vos risques):
	VideoCodec="hevc -preset veryfast -crf 26 -x265-params log-level=0"
	AudioCodec="copy"
	SubCodec="subrip"
#	fps=25
	SubFiltre="fr"
	VidFormat="mkv"
#	VidFiltre="best"
#	VidQual="-"
	QualFiltre="VO[^F]|Originale|qaa"
	SecFiltre=""
	AltMap="a s P"
	StreamTags="a:1 -l=fre a:1 -t=VF a:0 -t=VO s:0 -l=fre"
	ForceRen="True"
# Options pour les sous-titres:
	HIColor="red"
	HIFilter="[[:alnum:]]*"
	HIDelay=400
	ColDef="H00FFFFFF"
	ForceCoul="True"
	ForceHide="False"
	ForceAllFiles="False"
#	FontSize="n.n%"
#	FontSize="nn (forcée)"
	FontSize="= (normale)"
#	FontSize="+ (grande)"
#	FontSise="- (petite)"
#	FontSize=" (optimale)" 
#	s_Template="Style: s_color, Sans, 20, &c_color, &H00FFFF00, &H00000000, &H006C6C6C, 0, 0, 0, 0, Scale, Scale, 0, 0, 1, 0.5, 0.5, 2, 16, 16, 16, 0" 
	s_Template="Style: <STYLE>, <FONT>, <FONTSIZE>, &<COLOR>, &H00FFFF00, &H00000000, &H006C6C6C, 0, 0, 0, 0, <SCALEX>, <SCALEY>, 0, 0, 1, <OUTLINE>, <SHADOW>, 2, <LMARGIN>, <RMARGIN>, <MARGINV>, 0" 
	SubScale=70
# Options Youtube-dl à conserver:
	YdlOpt="--restrict-filenames --prefer-ffmpeg --ignore-config"
# Options générales ffmpeg:
	QueueSize=4096
	FfOpts="-y -loglevel warning"
	Dispo=" a_0 a:0_default s:0_default"
# Noms de fichiers:
	ScriptName="Perm.tew"
	TempName="Temp.tew"
	ConfFile="~/.config/Tew/Tew.conf"

#Fonctions utilitaires
confirme ()
#demande confirmation et retourne 1 si la chaîne saisie ne correspond pas au motif (par défaut: [OoYy]).
#option [ <message>][ <motif>]
{
	local message=${1:-"[O/N]? "}
	local motif=${2:-"[OoYy]"}
	local key=""
	read -p "$message"
	local key=${REPLY:-"N"}
	key=${key:0:1}
	key=${key/${motif}/}
	f_Result=${#key}
	if [ -n "${key}" ]
	then
		return 1
	else
		return 0
	fi
}
transforme ()
# interprète un motif
# 1: chaîne / 2: modificateur
{
	case ${2:0:1} in
		"/")
			local motif=$(echo "${2:1}" | grep -o -E "^[/]?[^/]*")
			local rempl=${2##/*/}
			case ${motif:0:1} in
				"/")
					f_Result="${1//${motif:1}/${rempl}}"
				;;
				"#")
					f_Result="${1/#${motif:1}/${rempl}}"
				;;	
				"%")
					f_Result="${1/%${motif:1}/${rempl}}"
				;;						
				*)
					f_Result="${1/${motif}/${rempl}}"
				;;	
			esac
		;;
		*)
			f_Result="${2:-${1}}"
		;;
	esac
	echo "${f_Result}"
}

#Exécution via un script temporaire
#scriptexec <commandes[s]> [ nom de fichier]
scriptexec ()
{
	local FName=${2:-${TempName}}
	echo -e "#!/bin/bash" > $FName
	echo -e "#Script TEW temporaire" >> $FName
	echo -e "${1}" >> $FName
	chmod "a+x" ${FName}
	echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Le script ${DataCoul}${FName}${InfoCoul} a été créé${NoCoul}"
	bash "$FName"
	rm ${TempName}
	echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Le script ${DataCoul}${FName}${InfoCoul} a été effacé${NoCoul}"
}

#Variables personalisées
read_config ()
{
	InFile="$1"
	if [ -f "$InFile" ]
	then
		while read Saisie
		do
			case "$Saisie" in
				[Nn]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Nn]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						ForceRen="$Saisie"
					fi
				;;
				[Pp]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Pp]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						VidFiltre="$Saisie"
					fi
				;;
				[Qq]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Qq]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						QualFiltre="$Saisie"
					fi
				;;
				[Ff]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Ff]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						SecFiltre="$Saisie"
					fi
				;;
				[Mm]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Mm]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						AltMap="$Saisie"
					fi
				;;
				[Uu]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Uu]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						SubFiltre="$Saisie"
					fi
				;;
				[Cc]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Cc]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						ForceCoul="$Saisie"
					fi
				;;
				[Hh]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Hh]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						ForceHide="$Saisie"
					fi
				;;
				[Ee]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Ee]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						ForceAllFiles="$Saisie"
					fi
				;;
				[Vv]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Vv]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						VideoCodec="$Saisie"
					fi
				;;
				[Aa]*)
					if [ -n "$Saisie" ]
					then
						AudioCodec="$Saisie"
					fi
				;;
				[Ss]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Ss]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						SubCodec="$Saisie"
					fi
				;;
				[Dd]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Dd]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						VidFormat="$Saisie"
					fi
				;;
				[Tt]*)
					Saisie=$( echo "$Saisie" | sed -e 's/^[Tt]:[[:blank:]]*//')
					if [ -n "$Saisie" ]
					then
						StreamTags="$Saisie"
					fi
				;;
			esac
		done < $InFile
	fi
}

write_config ()
{
	if [ ! -f "$1" ]
	then
		echo -e "# [$(date '+%D - %H:%M:%S')] Fichier de configuration créé automatiquement" > $1
		echo -e "N: $ForceRen" >> $1
		echo -e "P: $VidFiltre" >> $1
		echo -e "Q: $QualFiltre" >> $1
		echo -e "F: $SecFiltre" >> $1
		echo -e "M: $AltMap" >> $1
		echo -e "U: $SubFiltre" >> $1
		echo -e "C: $ForceCoul" >> $1
		echo -e "H: $ForceHide" >> $1
		echo -e "E: $ForceAllFiles" >> $1
		echo -e "V: $VideoCodec" >> $1
		echo -e "A: $AudioCodec" >> $1
		echo -e "S: $SubCodec" >> $1
		echo -e "D: $VidFormat" >> $1
		echo -e "T: $StreamTags" >> $1
	else
		sed -E -i "s/^[Nn]:.*/N: $ForceRen/" $1
		sed -E -i "s/^[Pp]:.*/P: $VidFiltre/" $1
		sed -E -i "s/^[Qq]:.*/Q: $QualFiltre/" $1
		sed -E -i "s/^[Ff]:.*/F: $SecFiltre/" $1
		sed -E -i "s/^[Mm]:.*/M: $AltMap/" $1
		sed -E -i "s/^[Uu]:.*/U: $SubFiltre/" $1
		sed -E -i "s/^[Cc]:.*/C: $ForceCoul/" $1
		sed -E -i "s/^[Hh]:.*/H: $ForceHide/" $1
		sed -E -i "s/^[Ee]:.*/E: $ForceAllFiles/" $1
		sed -E -i "s/^[Vv]:.*/V: $VideoCodec/" $1
		sed -E -i "s/^[Aa]:.*/A: $AudioCodec/" $1
		sed -E -i "s/^[Ss]:.*/S: $SubCodec/" $1
		sed -E -i "s/^[Dd]:.*/D: $VidFormat/" $1
		sed -E -i "s/^[Tt]:.*/T: $StreamTags/" $1
	fi
}

#Affichage de l'aide

Aide1 ()
{
	echo -e "${InfoCoul}============================================================================${NoCoul}"
	echo -e "${InfoCoul}    - AIDE PARAMETRES -${NoCoul}"
	echo -e "  Le programme peut utiliser au maximum trois sources et en 'muxer' les flux dans un seul fichier vidéo"
	echo -e "  La source principale est téléchargée à partir d'un site web, à l'adresse (URL) indiquée au menu général"
	echo -e "  Le nom de la vidéo, ainsi que son code d'identification (Vidéo ID) sont fournis par le site"
	echo -e "  Les sites fournissant souvent plusieurs qualités ou formats, la meilleure qualité (best) est choisie par défaut"
	echo -e "  La source secondaire peut être soit un autre format proposé par le site (par exemple la version orignale audio)"
	echo -e "  soit un fichier présent dans le répertoire courant. Ils doivent comporter la chaine d'identification (Vidéo ID)"
	echo -e "  La dernière source est obligatoirement un fichier, et ne contient qu'un ou plusieurs flux de sous-titres."
	echo -e "  Lors de l'initialisation, YOUTUBE_DL télécharge tous les fichiers de sous-titres disponibles sur le site pour cette vidéo."
	echo -e "  Les fichiers disponibles pour ces deux sources sont listés et numérotés. "
	echo -e "  Le mappage de la source secondaire permet de sélectionner les flux désirés."
	echo -e "  voir la documentation de l'option '-map' de ffmpeg pour une explication plus complète"
	echo -e "  Le mappage de la source principales, non modifiable, est 'tous les flux',  la source sous-titre est mappée à 'tous les sous-titres'."
	echo -e "  Pour chaque catégorie (Vidéo, Audio, et Sous-titres), il est possible de choisir le codec à utiliser ('copy' pour ne pas réencoder)."
	echo -e "  note: le codec vidéo n'est appliqué qu'au premier flux vidéo (copy pour les autres flux éventuels)"
	echo -e "  Des tags -langage, titre) peuvent être associés aux flux du fichier final."
	echo -e "  Le titre de la vidéo est éditable, de même que le nom de fichier."
}

Aide2 ()
{
	echo -e "${InfoCoul}============================================================================${NoCoul}"
	echo -e "${InfoCoul}    - AIDE MENU PRINCIPAL -${NoCoul}"
	echo -e "  Le menu principal s'affiche dans l'un de ces cas:"
	echo -e "  - L'URL requise est absente ou non résolue par YOUTUBE_DL"
	echo -e "  - Sortie du menu PARAMETRES par la commande [R]"
	echo -e "  - Commande d'exécution terminée ou interrompue"
	echo -e "  Les commandes disponibles à ce niveau sont:"
	echo -e "  si la liste des tâches n'est pas vide:"
	echo -e "   ${SurCoul}A${NoCoul}:  afficher la liste des tâches."
	echo -e "   ${SurCoul}V${NoCoul}:  vider la liste des tâches."
	echo -e "   ${SurCoul}C${NoCoul}:  sauver la liste des tâches dans un fichier exécutable."
	echo -e "   ${SurCoul}S${NoCoul}:  ajouter la liste des tâches à un fichier existant."
	echo -e "   ${SurCoul}X${NoCoul}:  lancer l'exécution de la liste des tâches."
	echo -e "  dans tous les cas:"
	echo -e "   ${SurCoul}? H${NoCoul}:  affiche cette aide."
	echo -e "   ${SurCoul}Q${NoCoul}:  Quitter le programme."
	echo -e "  il est aussi possible de saisir une nouvelle URL, ce qui relance le programme"
	echo -e "  dans ce cas, les choix et paramètres de la dernière exécution sont conservés si possible"
	echo -e "  Toute autre saisie relance le programme avec la même URL"
}

#Fonction de selection et de nettoyage du répertoire
#Renomme les fichiers selectionnés en supprimmant les espaces
liste_fichiers ()
{
	if [[ "$ForceAllFiles" == "True" ]]
	then Crit=".*"
	else Crit=${1:-".*"}
	fi
	local ModList=$(ls -1 | grep -E -h -n -T "$Crit")
	echo "${ModList}"
}

#Fonctions de filtres pour les sous-titres
Filtre_HI ()
{	
	local File="$1"
	local ColorFilter=${2/ /|c.}
	local TextFilter=${3:-">[.]*<|,[.]+$"}
	local Delay="${4:-400}"
	f_Result="0"
	if [ -f ${File} ]
	then OutFile="[mod]${File}"
		if [ -f $OutFile ]
		then echo -e "${WarnCoul}Le fichier ${DataCoul}${OutFile}${WarnCoul} sera écrasé${NoCoul}"
			confirme "Voulez-vous continuer? O/N "
		fi			
		if [ "${f_Result}" = "0" ]
		then 
			SubOffset=$((${SubOffset:-0} + ${Delay}))
				grep -E -v -h "<c\.(${ColorFilter:-red})>)" "${File}" | grep -E -v -h ${TextFilter} > "${OutFile}"
		else echo -e "${ErrCoul}Opération Annulée${NoCoul}"
			OutFile=""
			return 1
		fi
	else echo -e "${ErrCoul}Pas de fichier à traiter${NoCoul}"
		OutFile=""
		return 1	
	fi
	return 0
}
#Taille de police
size_font ()
{
	local fs="${FontSize%% *}"
	local ry="${1}"
	local t_h=$(( ry / 25 ))
	case "${fs}" in
		[0-9]*%*)
			if [ -n "${ry}" ]
			then
				fs=$(echo "${fs%%%*}.0" | sed -E 's/\.([0-9])(\.0)?/\1/')
				fs=$(( ${ry} *  ${fs} ))
				fs=$(( ${fs} + 5 ))
				fs=$(( ${fs} / 1000 ))
				fs="${fs} (= ${FontSize%%%*}%)"
			fi
		;;
		=*)
			fs="${t_h} (normale)"
		;;
		+*)
			if [ -n "${t_h}" ]
			then
				fs=$(( ${t_h} * 12 / 10 ))
				fs="${fs} (grande)"
			fi
		;;
		-*)
			if [ -n "${t_h}" ]
			then
				fs=$(( ${t_h} * 8 / 10 ))
				fs="${fs} (petite)"
			fi
		;;
		[1-9]*)
			fs=$(echo "${fs// /}" | grep -E -o "[1-9][0-9]*(\.[0-9])?")
			fs="${fs} (forcée)"
		;;
		*)
			fs=$(( ( ${ry:-360} + 135 ) / 30 ))
			fs="${fs} (optimale)"
		;;
	esac	
	f_Result="${fs:-16 (par défaut)}"
}

#Initialisation du fichier ZASS
init_ass ()
{
			local i_File="${1}"
			echo "[Script Info]" > "${i_File}"
			echo "ScriptType: v4.00+" >> "${i_File}"
			if [ -n "${VidResol}" ]
			then
				echo "PlayResX: ${VidResol%x*}" >> "${i_File}"
				echo "PlayResY: ${VidResol#*x}" >> "${i_File}"
			fi	
			echo "WrapStyle: 0" >> "${i_File}"
			echo "ScaledBorderAndShadow: yes" >> "${i_File}"
			local style_tab="red H0000FF,white HFFFFFF,yellow H00FFFF,magenta HFF00FF,cyan HFFFF00,green H008000"
			echo -e "\n[V4+ Styles]" >> "${i_File}"
			echo "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" >> "${i_File}"
			Saisie="${Size#0}"
			local StyleLine="${s_Template//<SCALE?>/${Saisie:-100}}"
			size_font "${VidResol#*x}"
			f_Result="${f_Result%% *}"
			StyleLine="${StyleLine//<FONTSIZE>/${f_Result:=16}}"
			f_Result=$(( ${f_Result} / 2 ))
			StyleLine="${StyleLine//<MARGINV>/${f_Result}}"
			f_Result=$(( ${f_Result} * 4 ))
			StyleLine="${StyleLine//<?MARGIN>/${f_Result}}"
			f_Result=$(( ${f_Result} * 3 + 48 ))
			StyleLine="${StyleLine//<OUTLINE>/${f_Result%??}}"
			StyleLine="${StyleLine//<SHADOW>/${f_Result%??}}"
			StyleLine="${StyleLine//<FONT>/${FontName:-${t_f:-Sans}}}"
			f_Result="${style_tab},"
			while [ -n "${f_Result}" ]
			do
				Style="${f_Result%%,*}"
				Couleur="${Style##* }"
				Style="${Style%% *}"
				Line="${StyleLine/<STYLE>/s_${Style}}"
				Line="${Line/<COLOR>/${Couleur}}"
				echo "${Line}"  >> "${i_File}"
				f_Result="${f_Result#*,}"
			done
			Line="${StyleLine/<STYLE>/Default}"
			Line="${Line/<COLOR>/HFFFFFF}"
			echo -e "${Line}\n"  >> "${i_File}"
			echo -e "[Events]" >> "${i_File}"
			echo "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" >> "${i_File}"
}

# Conversion de VTT vers ASS avec conservation des couleurs
vtt2ass ()
# Fichier Filtre[Taille]
{
	local InFile="$1"
	local HeadLine="Dialogue: 0,"
	local ColorFilter=${HIColor/ /|s_}
	local Size=$(echo ${2} | grep -E -o "[0-9]*")
	local HI=$(echo ${2::1} | grep -o -i "f")
	local isValid=$(echo "${InFile,,}" | grep -E -o "\.vtt$")
	local NewTime=""
	local LineTime="" 
	local NewText=""
	local NewLine=""
	local NewStyle=""
	local t_l="➖"
	local l_texte=""
	if [ -n ${isValid} ]
	then OutFile="${InFile/%.???/.ass}"
		Saisie=0
		if [ -f "$OutFile" ]
		then
			echo -e "${WarnCoul}Le fichier ${DataCoul}${OutFile}${WarnCoul} sera écrasé${NoCoul}"
			confirme "Voulez-vous continuer? [O/N]" 
			Saisie=$?
		fi
		if [ "${Saisie}" = "0" ]
		then
			echo -e -n "${InfoCoul}Conversion en cours ⏳\b${NoCoul}"
#Initialisation du fichier ass
			init_ass "${OutFile}"
			while read line
			do
				if [ "${#line}" -gt 1 ]
				then
					fLine=$(echo "${line}" | tr -d "\n")
#					echo -e -n "${#line}."
					Saisie=$(echo "${fLine}" | grep -E -o "[0-9]*:.*->.*[.][0-9]{2}") 
					if [[ ! "${Saisie:-${NewTime}}" == "${NewTime}" ]]
					then
						if [ -n "${NewText}" ]
						then 
							if [ -n "${NewLine}" ]
							then NewLine="\n${NewLine}"
							fi
							NewLine="${HeadLine}${LineTime},${NewText}${NewLine}"							
						fi						
						if [ -n "${NewLine}" ]
						then
							echo -e "${NewLine}" >> $OutFile
							HeadLine="Dialogue: 0,"
							echo -e -n "${t_l}"	 ; t_l="➖"				
						fi
						NewTime="${Saisie}"
						LineTime=$(echo "${NewTime/#0/}" | sed -r 's/[0-9][[:blank:]]*-*>[[:blank:]]*0?/,/g')
						NewLine=""
						NewStyle=""
						NewText=""
					else
						if [ -n "${NewTime}" ]
						then 												
#							Saisie=$(echo ${fLine%<*} | sed -E 's;[*]([^<\]*)?;\{\\i1\}\1\{\\i0\};')
							Saisie="${fLine%<*}"
							l_texte="${Saisie#*>}"
#							echo "[512] ${Saisie}"
							l_texte="${l_texte/\*/\{\\i1\}}"
							if [ "${Saisie:0:1}" = "<" ]
							then
								Saisie="${Saisie%%>*}"
							else
								Saisie="Default"
							fi							
							if [[ ! "${Saisie}" == "${NewStyle}" ]]
							then
								if [ -n "${NewText}" ]
								then 
									if [ -n "${NewLine}" ]
									then NewLine="\n${NewLine}"
									fi
									NewLine="${HeadLine}${LineTime},${NewText}${NewLine}"						
								fi						
								NewStyle="${Saisie}"				
								NewText="${NewStyle/<c./s_},,0,0,0,,${l_texte}"
								Saisie=$(echo "${l_texte// /}" | sed -E 's;\{[^}]*\}|\\N;;g' | grep -E -o "${HIFilter}")
								if [ -n "${HI}" ]
								then
									if [ -n "${Saisie}" ]
									then 
										Saisie=$(echo ${NewText} | grep -E -o "s_${ColorFilter:-red}")
									else Saisie="T"
									fi
									if [ -n "${Saisie}" ]
									then HeadLine="Comment: 0," ; t_l="?"
									fi
								fi 
							else
								if [ -n "${l_texte}" ]
								then
									NewText="${NewText}\N${l_texte}"								
								fi
							fi
						fi

					fi
				fi
			done < $InFile
			if [ -n "${NewText}" ]
			then 
				if [ -n "${NewLine}" ]
				then NewLine="\n${NewLine}"
				fi
				NewLine="${HeadLine}${LineTime},${NewText}${NewLine}"							
			fi						
			if [ -n "${NewLine}" ]
			then
				echo -e "${NewLine}" >> $OutFile
				echo "${t_l}"			
			fi
		else echo -e "${ErrCoul}Opération Annulée${NoCoul}"
			OutFile=""
			return 1
		fi
	else echo -e "${ErrCoul}Type de fichier non pris en charge${NoCoul}"
		OutFile=""
		return 1	
	fi
	return 0
}

#Fonction de sélection d'un fichier
#[ contexte filtre n°]
SelFile ()
{
	local LocFiles=${ExtFiles}
	if [ -z "${LocFiles}" ]
	then 
		echo -e "\r${WarnCoul}Aucun fichier présélectionné (filtre${DataCoul} ${VidId}${InfoCoul})"
		echo -e -n "Voulez-vous élargir à tous les fichiers du répertoire? "
		if confirme
		then
			LocFiles=$(liste_fichiers	".*")
		else return 1
		fi		
	fi
	local filtre=${2:-.*}
	if [ -n "${3}" ]
	then filtre="^[[:blank:]]*${3}:"
	fi
	local NbLines=""
	local ligne=""
	VerSaisie=""
	until [ "${NbLines}" = "1" ]
	do
		ListItems=$(echo "${LocFiles}" | grep -E "${filtre}")
		NbLines=$(echo "${ListItems}" | grep -c -E "^[[:blank:]]*[0-9]*:")
		case "$NbLines" in
			"0")
				if [ "${filtre}" = ".*" ]
				then
					echo -e "\r${WarnCoul}Aucun fichier trouvé "
					Saisie=""
					VerSaisie=""
					return 1
				else
					filtre=".*"
				fi					
			;;
			"1")
				echo -e -n "\r${InfoCoul}Fichier ${1} sélectionné : "
			;;
			*)
				echo -e "\r${InfoCoul}Choix du fichier ${1} (filtre:${DataCoul} $filtre${InfoCoul})                   "
				echo -e "${NoCoul}\t\tN°  \tfichier"
				echo -e "${DataCoul}$ListItems${NoCoul}"
				read -p "Choisir un fichier par son numéro, ou saisir un nouveau filtre: " Saisie
				case "$Saisie" in
					"0")
						ListItems=""
						NbLines="1"
					;;
					[0-9]*)
						filtre="^[[:blank:]]*${Saisie}:"
					;;
					*)
						if [ -n "${Saisie}" ]
						then filtre=${Saisie}
						else 
							VerSaisie=""
							return 1
						fi
					;;
				esac
			;;
		esac
	done
	
	if [ -z "${ListItems}" ]
	then
		Saisie=""
		VerSaisie=""
		Resol=""
	else
		Saisie=$(echo "${ListItems}" | sed -e 's/^[[:blank:]]*[0-9]*:[[:blank:]]*//g')
		echo -e -n "${DataCoul}${Saisie}${InfoCoul} ⏳\b"
		if [ -f "$Saisie" ]
		then  echo -e "vérifié${NoCoul}"				
			VerSaisie=$(echo "${Saisie}" | sed -e 's/[[:blank:]/&,]/_/g')
			if [[ ! "${Saisie}" == "${VerSaisie}" ]]
			then 				
				VerSaisie="'${Saisie}'"
			fi
		else
			echo -e "\r${WarnCoul}innaccessible${NoCoul}                                "
			Saisie=""
			VerSaisie=""
			return 1
		fi			
	fi
}
#Correspondance de caractères
utf2iso ()
{
	f_Result="${1}" 
	f_Result="${f_Result//é/é}"
	f_Result="${f_Result//è/è}"
	f_Result="${f_Result//à/Ã}"
	f_Result="${f_Result//ï/ï}"
	f_Result="${f_Result//ô/ô}"
	f_Result="${f_Result//ç/ç}"
	f_Result="${f_Result//ê/ê}"
	f_Result="${f_Result//ù/ù}"
#	echo -e "[671] ${f_Result}"
}
#Fonction de sélection du format
# contexte [-sélecteur/filtre [option]]
SelFormat ()
{
	local contexte="${1}"
	Saisie="${2:--}"
	local f_filtre=""
	local format1=""
	local Opt="${3}"
	local ligne=""
	local NbLines=""
	local Selection=""
	local ListItems=""
#	Resol=""
	yformat=""
	f_Result=""
	if [ ! "${Saisie:0:1}" = "-" ]
	then 
		ListItems=$(echo "${ListFormats}" | grep -E "${Saisie:1}")	
	fi
	while [ -n "${Saisie}" ]
	do	
		if [ "${contexte}" = "complémentaire" ]
		then Saisie="${Saisie#+}"
		fi
		if [ "${Saisie:0:1}" = "+" ]
		then
			Saisie="${Saisie:1}"
		else		
			yformat=""
			f_Result=""
			Resol=""
		fi
		case ${Saisie} in
			-*)
				format1="${Saisie}"
				f_filtre="${format1}"
			;;
			0*)
				Saisie=""
				Opt=""
				format1=""
				f_filtre=""
				Resol=""
				return		
			;;
			[1-9]*)
				Saisie=$(echo "${Saisie}" | grep -E -o "[0-9]*")
				ligne=$(echo "${ListItems}" | grep -E "^[[:blank:]]*${Saisie}")
				format1=$(echo "${ligne#*:}" | grep -E -o "^[[:blank:]]*[^[:blank:]]*")
				f_filtre="${format1}"
			;;
			*)
				ListItems=$(echo "${ListFormats}" | grep -E "${Saisie}")	
				NbLines=$(echo "${ListItems}" | grep -c -E "^[[:blank:]]*[0-9]*:")
				case "$NbLines" in
					"0")						
						echo -e "\r${WarnCoul}Aucun format correspondant au filtre  ${Saisie}${NoCoul}"
						format1=""
						f_filtre=""
						Opt="*"			
					;;
					"1")
						ligne="${ListItems#*:}"
						format1=$(echo "${ligne#*:}" | grep -E -o "^[[:blank:]]*[^[:blank:]]*")
						f_filtre="${Saisie}"
					;;
					*)
						format1=""
						f_filtre=""
					;;
				esac
			;;		
		esac
		if [ -n "${format1}" ]
		then
			if [ "${contexte}" = "principale" ]
			then
				Resol=$(echo "${ligne}" | grep -E -o '[0-9]+x[0-9]+')
			else
				Resol=""
			fi
			format1="${format1// /}"
			format1="${format1#-}"			
			echo -e -n "\r${InfoCoul}Vérification de la sélection ${DataCoul}[${format1:-Auto}] ${Resol}${InfoCoul}\t⏳\b"
			if [ -n "${format1}" ]
			then
#				utf2iso "${format1}"			
				Saisie="-f ${format1}"
			else Saisie=""
			fi
			result1=$(youtube-dl ${YdlOpt} ${Saisie} -g "${url}")
			if [ "$?" = 0 ]
			then echo -e -n "${NoCoul}"
				if [ "${Opt:0:1}" = "?" ]
				then
					echo -e "\r${InfoCoul}url: ${DataCoul}${result1}${NoCoul}"
					Opt="${Opt#?}"
					read -p "[E]dition, [A]nnulation ou [RETURN]:   " Saisie
					case "${Saisie,,}" in
						a)
							result1=""
							format1=""
							echo -e "\r${InfoCoul}Sélection annulée${NoCoul}]"
							Opt="*"
						;;
						e)
							read -p "Modification URL:  " Saisie
							if [ -n "${Saisie}" ]
							then
								transforme "${result1}" "${Saisie}"
								result1="${f_Result}"
								echo -e "\r${InfoCoul}url modifiée: ${DataCoul}${result1}${NoCoul}"
							else Opt=""
							fi
						;;
						*)
							Opt="*"
						;;
					esac				
				fi
				if [ -n "${result1}" ]
				then
					echo -e "\r${InfoCoul}Url(s) de la source ajoutée(s) à la sélection ${contexte}${NoCoul}\t\t"
					yformat="${yformat},${f_filtre}"
					f_Result="${f_Result} ${result1}"
					if [ "${Opt:0:1}" = "+" ]
					then
						Opt="*"
					fi
				else
					Opt="*"
				fi		
			else echo -e " ${WarnCoul}introuvable${NoCoul}"	
				echo -e "\r${InfoCoul}Sélecteur supprimé${NoCoul}"
				Opt="*"
			fi
		else Opt="*"
		fi
		format1=""
		f_filtre=""
		if [ -z "${Opt}" ]
		then
			Saisie=""
		else
			ListItems=$(echo "${ListFormats}" | grep -E "${Opt}")
			echo -e "\r${InfoCoul}Sélecteur actuel: ${DataCoul}${yformat#,}${NoCoul}"
			echo -e "\r${InfoCoul}Choix d'une source ${1} (filtre:${DataCoul} ${Opt}${InfoCoul})"
			echo -e "${NoCoul}\t\tN°  \tcode \textension \tresolution \tnote"
			echo -e "${DataCoul}$ListItems${NoCoul}"
			echo -e "\t${SaisCoul}[+]-<sélecteur> [Options]${InfoCoul}:\tutiliser un sélecteur de format youtube-dl${NoCoul}"
			echo -e "\t${SaisCoul}[+]<n°ligne> [Options]${InfoCoul}\t:selection de ligne par son numéro${NoCoul}"
			echo -e "\t${SaisCoul}<regex> [Options]${InfoCoul}\t\t:Présélection par expression régulière${NoCoul}"
			echo -e "\t${SaisCoul}0${InfoCoul}\t\t:Annulation et sortie${NoCoul}"
			echo -e "\t${SaisCoul}RETURN${InfoCoul}\t\t:Enregistrement et sortie${NoCoul}"
			echo -e "\t\t${InfoCoul}Options: ${SaisCoul}?${InfoCoul} = édition URL / ${SaisCoul}+${InfoCoul} = revenir au menu ${NoCoul}"			
			echo -e "\t\t${InfoCoul}Saisie précédée de ${SaisCoul}+${InfoCoul} = ajout à la sélection (source principale uniquement)${NoCoul}"
			read -p "Votre choix:     " Saisie Opt
#			Saisie="${Saisie// /}"
		fi	
	done
	echo ""
	yformat="${yformat#,}"
	return
}

#Menu paramètres
Menu_Param ()
{
				echo -e "\r${InfoCoul}============================================================================${NoCoul}"
				echo -e "${NoCoul}RESUME DES PARAMETRES:${NoCoul}"
				echo -e "${NoCoul}----------------------------------------------------------------------------"
				echo -e "${SurCoul}N${NoCoul}om de la vidéo: ${DataCoul} ${VidName}${NoCoul} \t${SaisCoul}E${NoCoul}diter"
				echo -e "${NoCoul}Vidéo ID       : ${InfoCoul} $VidId"
				echo -e "${NoCoul}----------------------------------------------------------------------------"
				echo -e "Fichiers locaux correspondants:"
				echo -e "${InfoCoul}${ExtFiles}${NoCoul}"
				echo -e "${NoCoul}----------------------------------------------------------------------------"
				echo -e "Source ${SurCoul}P${NoCoul}rincipale: ${DataCoul}${VidQual/#-/Auto}${NoCoul}"
				echo -e "Résolution vidéo     : ${DataCoul}${VidResol:-inconnue}${NoCoul}"
				echo -e "Fréquence d'image    : ${DataCoul}${fps:-inconnue}${NoCoul}"
				echo -e "${NoCoul}----------------------------------------------------------------------------"
				echo -e "Source ${SurCoul}B${NoCoul}onus: \t${DataCoul}${AltSource:-aucune}${NoCoul} \t[${SaisCoul}0, n°, q${NoCoul}alité] [${SaisCoul}<filtre>${NoCoul}]"
				echo -e "	${SaisCoul}M${NoCoul}appage: \t${DataCoul}$AltMap${NoCoul}	\t[${SaisCoul}V${NoCoul}idéo ${SaisCoul}A${NoCoul}udio ${SaisCoul}S${NoCoul}ub (${SaisCoul}P${NoCoul})rioritaire]"
				echo -e "	Décala${SaisCoul}G${NoCoul}e: \t${DataCoul}${AltOffset:-0}${NoCoul}	\t${SaisCoul}<millisecondes>${NoCoul}"
				echo -e "${NoCoul}----------------------------------------------------------------------------"
				echo -e -n "So${SurCoul}U${NoCoul}s-titres: \t${DataCoul}${SubFile:-aucun}${NoCoul}	\t[${SaisCoul}n°"
				if [ -f "${SubFile}" ]
				then 
					echo -e ", 0, C${NoCoul}ouleur ${SaisCoul}F${NoCoul}iltrage HI ${SaisCoul}<echelle>${NoCoul}]"
					echo -e "	${WarnCoul}Attention: Les options C et/ou F écraseront le fichier de sous-titres actuel!${NoCoul}"
					echo -e "	Décala${SaisCoul}G${NoCoul}e: \t${DataCoul}${SubOffset:-0}${NoCoul}	\t${SaisCoul}<millisecondes>${NoCoul}"
				else echo -e "${NoCoul}]"
				fi
				echo -e "----------------------------------------------------------------------------"
				echo -e "${SurCoul}O${NoCoul}ptions de traitement pour ffmpeg:"
				echo -e "	Codec ${SaisCoul}v${NoCoul}idéo              : ${DataCoul}$VideoCodec${NoCoul}"
				echo -e "	Codec ${SaisCoul}a${NoCoul}udio              : ${DataCoul}$AudioCodec${NoCoul}"
				echo -e "	Codec ${SaisCoul}s${NoCoul}oustitres         : ${DataCoul}$SubCodec${NoCoul}"
				echo -e "	${SaisCoul}D${NoCoul}estination de la vidéo  : ${DataCoul}$VidDest${NoCoul}"
				echo -e "	${SaisCoul}T${NoCoul}ags des flux de sortie  : ${DataCoul}$StreamTags${NoCoul}"
				echo -e "----------------------------------------------------------------------------"
				echo -e "E${SurCoul}X${NoCoul}écution et mise en file:"
				echo -e "	Télécharger avec ${SaisCoul}Y${NoCoul}outube-dl, puis encoder avec ffmpeg"
				echo -e "	Traitement complet avec ${SaisCoul}f${NoCoul}fmpeg (plus rapide, mais moins sûr)"
				echo -e "Options: [${SaisCoul}A${NoCoul}fficher, Mettre en ${SaisCoul}F${NoCoul}ile,  ${SaisCoul}T${NoCoul}ester, ${SaisCoul}L${NoCoul}ancer]"
				echo -e "----------------------------------------------------------------------------"
				echo -e "${SurCoul}? H${NoCoul}→ obtenir de l'aide"
				echo -e "----------------------------------------------------------------------------"
				echo -e "${SurCoul}R${NoCoul}etour au menu principal"
				echo -e "${InfoCoul}============================================================================${NoCoul}"
				echo -e "Saisir: [${SurCoul}clé${NoCoul} [${SaisCoul}action${NoCoul} [${SaisCoul}option(s)${NoCoul}]"
}

#Sous-Menu avancé
Sous_Menu ()
{
#	echo -e "Sous-menu ${Key}"
	if [[ ! ${1:0:1} == [HRX?] ]]
	then
		echo -e "${NoCoul}----------------------------------------------------------------------------"
		case ${1:0:1} in
			[N])
				echo -e "${InfoCoul}Nom de la Vidéo: ${DataCoul}${VidName}${NoCoul}\n"
				echo -e "	${SaisCoul}E${NoCoul}diter le nom de la vidéo [ ${SaisCoul}<Nom>${NoCoul}]"
				echo -e "	Renommer également le fichier: ${SaisCoul}O${NoCoul}ui, ${SaisCoul}N${NoCoul}on, ${SaisCoul}T${NoCoul}oujours, ${SaisCoul}J${NoCoul}amais, ${SaisCoul}D${NoCoul}emander"
			;;
			#[P])
				#echo -e "${InfoCoul}Source Principale actuelle: ${DataCoul}${VidQual:-Auto}${NoCoul}\n"
				#echo -e "	Modifier la  qualité dans une ${SaisCoul}L${NoCoul}iste, [ avec un ${SaisCoul}<filtre>${NoCoul}]${NoCoul})"
				#echo -e "	${SaisCoul}I${NoCoul}nfo: affiche l'URL de téléchargement"
			#;;
			[B])
				echo -e "${InfoCoul}Source Secondaire actuelle: \t${DataCoul}${AltSource:-aucune}${InfoCoul}, mappage: ${DataCoul}$AltMap${NoCoul}"
				echo -e "${InfoCoul}Décalage                  : \t${DataCoul}${SubOffset:-0}${NoCoul} millisecondes\n"
				if [ -z "$ExtFiles" ]
				then
					echo -e "	Choisir un fichier en utilisant son ${SaisCoul}n°${NoCoul}"
					echo -e "	Choisir un fichier dans une ${SaisCoul}L${NoCoul}iste, avec un [${SaisCoul} <filtre>${NoCoul}])"
				fi
				if [ -n "$AltSource" ]
				then
					echo -e "	Supprimer la source: taper ${SaisCoul}0${NoCoul}"
				fi
				echo -e "	Choisir une ${SaisCoul}Q${NoCoul}alité dans une liste, avec un [${SaisCoul} <filtre>${NoCoul}] (actuel: ${DataCoul}$QualFiltre${NoCoul})"
				echo -e "	Modifier le ${SaisCoul}M${NoCoul}appage \t[${SaisCoul} <a v s>${NoCoul}]"
				echo -e "	Modifier le décala${SaisCoul}G${NoCoul} \t${SaisCoul}<millisecondes>${NoCoul}"
				echo -e "	${SaisCoul}I${NoCoul}nfo: affiche l'URL de téléchargement"
			;;
			[U])
				echo -e "${InfoCoul}Fichier de Sous-titres     : \t${DataCoul}${SubFile:-aucun}${NoCoul}"
				echo -e "${InfoCoul}Filtre de Sous-titres      : \t${DataCoul}${SubFiltre:-aucun}${NoCoul}"
				AssScale=$(echo ${VidResol} | grep -E -o '[0-9]*$')
				AssScale=$((( ${AssScale:-720} + 5 ) / 10 ))
				echo -e "${InfoCoul}Echelle par défaut (ASS)   : \t${DataCoul}${AssScale}${NoCoul} %"
				echo -e "${InfoCoul}Décalage                   : \t${DataCoul}${SubOffset:-0}${NoCoul} millisecondes\n"
				echo -e "	Modifier le décala${SaisCoul}G${NoCoul}e \t${SaisCoul}<millisecondes>${NoCoul}"
				echo -e "	Choisir un fichier dans une ${SaisCoul}L${NoCoul}iste, avec un [${SaisCoul} <filtre>${NoCoul}]"
				if [ -n "$ExtFiles" ]
				then
					echo -e "	Choisir un fichier en utilisant son ${SaisCoul}n°${NoCoul} - Supprimer la source: taper ${SaisCoul}0${NoCoul}"
				fi
				if [[ ! $(echo "${SubFile}" | grep -E -o -i '.vtt$|.ass$') == "" ]]
				then
					echo -e -n "	${SaisCoul}F${NoCoul}iltrer les ST pour malentendants" 
					if [[ ! $(echo "${SubFile}" | grep -E -o -i '.vtt$') == "" ]]
					then
						echo -e " (cumulable avec ${SaisCoul}C${NoCoul} ci-dessous)"
						echo -e "	Transfomer un fichier VTT en ASS en ${SaisCoul}C${NoCoul}ouleurs avec [${SaisCoul}<echelle>${NoCoul}]"
					else echo -e ""
					fi
				fi
			;;
			[O])
					echo -e "${WarnCoul}Options d'encodage: utilisateurs avancés seulement!!${NoCoul}\n"
					echo -e "	Choisir les codecs utilisés par ffmpeg pour les différents flux: "
					echo -e "	${SaisCoul}V${NoCoul}idéo, ${SaisCoul}A${NoCoul}udio, ${SaisCoul}S${NoCoul}ous-titres: [ ${SaisCoul}<codec>${NoCoul}]"
					echo -e "	Changer la ${SaisCoul}D${NoCoul}estination du [ ${SaisCoul}<fichier de sortie>${NoCoul}]"
					echo -e "	Modifier les ${SaisCoul}T${NoCoul}ags associés aux flux: [ ${SaisCoul}(a,v,s)[:n] {(-l,-t)=<label>...}${NoCoul}]"
			;;
			[X])
					echo -e "	Choisir l'exécutable ${SaisCoul}F${NoCoul}fmpeg (défaut) ou ${SaisCoul}Y${NoCoul}outube-dl"
					echo -e "	Options de lancement:"
					echo -e "		${SaisCoul}A${NoCoul}ffichage de la commande"
					echo -e "		Mise en ${SaisCoul}F${NoCoul}ile de la commande"
					echo -e "		${SaisCoul}T${NoCoul}est de la commande"
					echo -e "		${SaisCoul}L${NoCoul}ancement immédiat de la commande"
			;;
		esac
		echo -e "${NoCoul}----------------------------------------------------------------------------"
		read -p " saisir choix et option séparés par un espace: " Act Opt
	fi
}

fps_vid ()
{
	if [ -n "${1}" ]
	then
		local InFile="${1// / -i }"
		Resol=$(ffmpeg -i ${InFile} 2>&1 | grep -E "^[[:blank:]]*Stream.*: Video:")
		f_Result=$(echo "${Resol}" | grep -E -o ", [0-9]+ fps")
		f_Result="${f_Result#, }"; f_Result="${f_Result%% fps*}"
		Resol=$(echo "${Resol}" | grep -E -o ", [0-9]+x[0-9]+ ")
		Resol="${Resol#, }" ; Resol="${Resol%% *}"
	else
		Resol=""
		f_Result=""
		return 1
	fi
}

# Récupération des données et soustitres

read_config "$ConfFile"
rm -f $TempScriptName

if [ -f "${1}" ]
then 
	vtt2ass "${1}"
fi

Saisie="${1}"
VidId=""
until [ "${Key^^}" = "Q" ]
	do
		if [ "${Key}" = "D" ]
		then 
			VidId="${Saisie}"
			Key=""
		else
			Key=${Saisie}
		fi
		Saisie=""		
		if [ -n "${Key}" ]
		then
			echo -e -n " \r${InfoCoul}Recherche Vidéo...................................⏳\b${NoCoul}"
			# | grep -E -n -T "$filtre")
			Saisie=$(youtube-dl $YdlOpt $Key --get-id)	
			if [ -z "$Saisie" ]
			then echo -e " \r${ErrCoul}impossible de résoudre cette URL${NoCoul}"
			else url="${Key}"
			fi
		else Saisie=${VidId}
		fi
		if [ -n "$Saisie" ]
		then
			if [[ ! "${Saisie}" == "${VidId}" ]]
			then
				echo -e -n " \r${InfoCoul}Recherche des formats disponibles.................⏳\b${NoCoul}"
				ListFormats=$(youtube-dl "-F" $url | grep -E -v '^[[]|format' | grep -E -n -T ".*")
				VidId=$Saisie
				SubOffset=""
				AltOffset=""
				SelFormat "principale" "${VidQual}"
				VidQual="${yformat:-${VidQual}}"
				download_url="${f_Result# }"
				VidResol="${Resol:-${VidResol}}"
				SelFormat "complémentaire" "${AltSource:-${QualFiltre}}"
				AltSource="${yformat:-${AltSource}}"
				AltUrl="${f_Result:-${AltUrl}}"
				echo -e -n "\r${InfoCoul}Recherche et téléchargement des sous-titres.......⏳\b${NoCoul}"
				youtube-dl $url $YdlOpt "-q" "--write-sub" "-w" "-o" "%(id)s.%(ext)s" "--all-subs" "--skip-download"
				ExtFiles=$(liste_fichiers "${VidId}")
				if [ -n "${ExtFiles}" ]
				then SelFile " de sous-titres" "${SubFiltre}"
					if [ "$?" = "0" ]
					then SubFile=$VerSaisie
					fi
				else	SubFile=""
				fi				
				if [[ $(echo ${SubFile##*.}	| grep -E -o -i "srt|ass|ssa") ]]
				then SubCodec="copy"
				fi		
				echo -e -n "\r${InfoCoul}Récupération des données de la vidéo..............⏳\b${NoCoul}"
				VidName=$(youtube-dl $YdlOpt $url -e | sed -E -e "s,[{}'/],.,g")
				Tag0=$(echo ${VidName} | sed -e 's/[/&,|;]/_/g')
				VidDest="${Tag0}-${VidId}.${VidFormat}"
				fps_vid "${download_url# }"
				fps="${f_Result:-${fps}}"
				VidResol="${Resol:-${VidResol}}"				
			else
				ExtFiles=$(liste_fichiers "${VidId}")
			fi

# Résumé et choix
			Saisie=""
			Key=""
			Opt=""
			Act=""
			until [[ ${Key^^} =~ ^[XR].* ]]
			do
				Menu_Param
				read -p "votre choix : " Key Act Opt
				echo -e "\n"
				if [ -n "$Key" ]
				then
					Saisie=""
					case "${Key,,}" in
						[0-9]*|[ldgi]*)
							echo -e -n "Action ambigüe, saisir une clé: "
							read  Saisie
							Saisie=$(echo $Saisie | grep -E -i -o "^[NSUOX]")
						;;
						[qm]*)
							Saisie="B"
						;;
						[c]*)
							Saisie="U"
						;;
						[tvas]*)
							Saisie="O"
						;;
						[yf]*)
							Saisie="X"
						;;
						[e]*)
							Saisie="N"							
						;;
						[p]*)
							Saisie="P"							
						;;
					esac
					if [ -n "$Saisie" ]
					then
						Opt="$Act $Opt"
						Act="$Key"
						Key="$Saisie"
					fi
					if [[ ! ${#Key} == 1 ]]
					then
						Opt="$Act $Opt"
						Act="${Key:1}"
					fi
					if [ -z "$Act" ]
					then
						Sous_Menu ${Key^^}
					fi
					Opt=$(echo ${Opt} | sed -E 's+^[[:blank:]] *++')
					case $Key in
						[Nn]*)
							Opt="${Act:1} $Opt"
							Opt=$(echo ${Opt} | sed -E 's+^[[:blank:]]*++')
							if [ -z "$Opt" ]
							then
								read -p "Saisir le nom de la vidéo: " Opt
							fi
							case "${Opt}" in 
								"/"*"/"*)							
									transforme "$VidName" "$Opt"
								;;
								"-"[sS]*)							
									f_Result=$(echo "$VidName" | sed -E -e "${Opt:1}")
								;;
								*)
									f_Result=$(echo "$Opt" | sed -E -e "s,[{}'/],.,g")								
								;;								
							esac
							VidName=${f_Result:-${VidName}}
							case ${Act^^} in
								[T]*)
									ForceRen="0"
									Opt="0"
								;;								
								[J]*)
									ForceRen="1"
									Opt="1"
								;;	
								[D]*)
									ForceRen=""
									Opt=""
								;;
								[OY]*)
									Opt="0"
								;;
								[N]*)
									Opt="1"
								;;
								*)
									Opt="${ForceRen}"
								;;								
							esac
							if [ -n "${f_Result}" ]
							then f_Result="${Opt}"
								if [ -z "$Opt" ]
								then
									echo -e -n "Mettre à jour nom de fichier? "
									confirme "O/N "
								fi
								if [ "${f_Result}" = "0" ]
								then	Saisie=$(echo ${VidName} | sed -e 's/[/&,|;]/_/g')
										VidDest="${Saisie}.${VidFormat}"
										echo -e "${InfoCoul}Destination modifiée en: ${DataCoul}$VidDest${NoCoul}"
								fi							
							fi
						;;
						[Bb]*)
							case "$Act" in
								0*)
									AltSource=""
									AltUrl=""
								;;
								[1-9]*|[Ll]*)
									NFile=$(echo "$Act" | grep -E -o -e "^[0-9]*")
									SelFile "complémentaire" "$Opt" "$NFile"
									if [ "$?" = "0" ]
									then AltSource=$Saisie
										 AltUrl="${VerSaisie}"
										if [ -n "$Opt" ]
										then SecFiltre="$Opt"
										fi
									fi
								;;
								[Qq]*)
									Opt="${Act:1}$Opt"
									SelFormat "complémentaire" "${Opt:-*} +"
									AltUrl="${f_Result:-${AltUrl}}"
									AltSource="${yformat:-${AltSource}}"
								;;
								[Mm]*)
									Opt="${Act:1}$Opt"
									if [ "$Opt" == " " ]
									then
										echo -e "sélectionner le(s) flux à mapper: ${SurCoul}A${NoCoul}udio, ${SurCoul}V${NoCoul}idéo, ${SurCoul}S${NoCoul}oustitres."
										read -p "plusieurs choix possibles, [:n°] de flux en option: " Opt
									fi
									Opt=$(echo "${Opt// /}" | grep -E -i -o "[avspn]*" | sed -E 's/[AaVvSsPpNn]/ &/g')
									AltMap=${Opt:-${AltMap}}
								;;
								[Gg]*)
									Opt="${Act:1}$Opt"
									if [[ $(echo ${Opt} | grep -E -o -e "[-]?[0-5]?[0-9]{,4}$") == ${Opt} ]]
									then 
									AltOffset="${Opt}"
									else echo -e "${WarnCoul}Le décalage doit être inférieur à 1 minute (60000 millisecondes)!${NoCoul}"
									fi								
								;;
								[Ii]*)
									echo -e "Url de téléchargement (source bonus):\n${DataCoul}${AltUrl}${NoCoul}"							
								;;
							esac
						;;
						[Pp]*)
							Opt="${Act:1}$Opt"
							SelFormat "principale" "-${VidQual}" "?+"
							VidQual="${yformat:-${VidQual}}"
							download_url="${f_Result:-${download_url}}"
							fps_vid "${download_url# }"
							fps="${f_Result:-${fps}}"
							VidResol="${Resol:-${VidResol}}"				
						;;
						[Uu]*)
							case "$Act" in
								0*)
									SubFile=""
								;;
								[1-9]*|[Ll]*)
									Opt=${Opt:-${SubFiltre}}
									NFile=$(echo "$Act" | grep -E -o -e "^[0-9]*")
									SelFile "de sous-titres" "$Opt" "$NFile"
									if [ "$?" = "0" ]
									then SubFile=$VerSaisie
										if [ -n "$Opt" ]
										then SubFiltre="$Opt"
										fi
									fi
								;;
								[CcFf]*)
									Opt="${Act:1}$Opt"
									Act="${Act::1}"
									OutFile=""
									if [ "${Act,,}" = "f" ]
									then
										Filtre_HI "${SubFile}" "${HIColor}" "${HIFilter}" "${HIDelay}"
										if [ $? == 0 ]
										then 
											rm -f "${SubFile}"
											SubFile="${OutFile}"
											echo -e "\r${InfoCoul}Fichier ${DataCoul}${SubFile}${InfoCoul} créé${NoCoul}"
										fi
										Act="${Opt::1}"
										Opt="${Opt:1}"									
									fi
									if [ "${Act,,}" = "c" ]
									then
										vtt2ass "${SubFile}" "$Opt"
										if [ $? == 0 ]
										then 
											rm -f "${SubFile}"
											SubFile="${OutFile}"
											SubCodec="copy"
											echo -e "\r${InfoCoul}Fichier ${DataCoul}${SubFile}${InfoCoul} créé${NoCoul}"
										fi									
									fi
									ExtFiles=$(liste_fichiers "${VidId}")
									OutFile=""								
								;;
								[Gg]*)
									Opt="${Act:1}$Opt"
									if [[ $(echo ${Opt} | grep -E -o -e "[-]?[0-5]?[0-9]{,4}$") == "${Opt}" ]]
									then SubOffset=${Opt}
									else echo -e  "${WarnCoul}Le décalage doit être inférieur à 1 minute (60000 millisecondes)!${NoCoul}"
									fi								
								;;
							esac
						;;
						[Oo]*)
							Opt="${Act:1}$Opt"
							case "$Act" in
								[Vv]*)
									if [ -z "$Opt" ]
									then
										read -p "saisir le codec vidéo et ses paramètres: " -i "${VideoCodec}" Opt
									fi
									case "${Opt}" in 
										"/"*"/"*)							
											Opt=$(transforme "$VideoCodec" "$Opt")
										;;
										"-"[sS]*)							
											Opt=$(echo "$VideoCodec" | sed -E -e "${Opt:1}")
										;;					
									esac
									VideoCodec=${Opt:-$VideoCodec}
								;;
								[Aa]*)
									if [ -z "$Opt" ]
									then
										read -p "saisir le codec audio et ses paramètres: " Opt
									fi
									case "${Opt}" in 
										"/"*"/"*)							
											Opt=$(transforme "$AudioCodec" "$Opt")
										;;
										"-"[sS]*)							
											Opt=$(echo "$AudioCodec" | sed -E -e "${Opt:1}")
										;;	
									esac				
									AudioCodec=${Opt:-$AudioCodec}
								;;
								[Ss]*)
									if [ -z "$Opt" ]
									then
										read -p "saisir le codec des sous-titres: " Opt
									fi
									case "${Opt}" in 
										"/"*"/"*)							
											Opt=$(transforme "$SubCodec" "$Opt")
										;;
										"-"[sS]*)							
											Opt=$(echo "$SubCodec" | sed -E -e "${Opt:1}")
										;;
									esac					
									SubCodec=${Opt:-$SubCodec}
								;;
								[Dd]*)
									if [ -z "$Opt" ]
									then
										read -p "saisir le nom du fichier de sortie: " Opt
									fi
									case "${Opt}" in 
										"/"*"/"*)							
											Opt=$(transforme "$VidDest" "$Opt")
										;;
										"-"[sS]*)							
											Opt=$(echo "$VidDest" | sed -E -e "${Opt:1}")
										;;
										"-n"*)							
											Opt="${VidName}.${VidFormat}"
										;;
										*)
											Opt=$(echo "$Opt" | sed -E -e "s,[{}'/],.,g")								
										;;								
									esac
									Opt=${Opt:-${VidDest}}									
									if [ -n "$Opt" ]
									then VidDest=$(echo "$Opt" | sed -e 's/[/&,|;]/_/g')
										 VidFormat=$(echo "$Opt" | grep -E -o '[^.]*$')
										 if [[ ${VidFormat,,} == "mp4" ]]
										 then SubCodec="mov_text"
										 fi
									fi
								;;
								[Tt]*)
									if [ -z "$Opt" ]
									then
										echo -e "ajouter un flux à tagger: ${SurCoul}A${NoCoul}udio, ${SurCoul}V${NoCoul}idéo, ${SurCoul}S${NoCoul}oustitres"
										echo -e "un numéro de flux optionnel ${SurCoul}[:n°]${NoCoul} et un tag à associer: ${DataCoul}-l=<langue>, -t=<Titre>${NoCoul} ou ${SurCoul}[E]${NoCoul}ffacer"
										read  Opt
									fi
									Tags=$(echo "${Opt}" | sed -E 's/^[vas](:[0-9]*)?[[:blank:]]*//')
									Opt=$(echo "${Opt}" | grep -o -E "^[vas](:[0-9]*)?")
									if [ -n "$Opt" ]
									then
										case $Tags in
											[Ee])
												StreamTags=$(echo ${StreamTags} | sed -E "s/$Opt(:[0-9]*)?(\ -[LlTt]=[^ ]*)?//g")
											;;
											*)
												Tags=$(echo "${Tags}" | grep -o -E -e "-[LlTtl]=[^, -]*")
												while read tag
												do
													if [ -n "$tag" ]
													then
														StreamTags="${StreamTags} ${Opt} ${tag}"
													fi
												done <<< "${Tags}"
											;;
										esac
									fi
								;;
							esac
						;;
						[Xx]*)
							Opt="${Act:1} $Opt"
							Act="${Act:0:1}"
							if [[ "${Act^^}" == "Y" ]]
							then
								Saisie="$VidQual"
								Line3="-o '[TEMP]%(format_id)s.%(ext)s'" 
								TempFile1=$(youtube-dl --ignore-config ${Line3} -f "${VidQual}" --get-filename "${url}")
								if [[ ! "$AltSource" == "$AltUrl" ]]
								then 									
									TempFile2=$(youtube-dl --ignore-config "${Line3}" -f "${AltSource}" --get-filename "${url}")
									Saisie="${Saisie},${AltSource}"
								else
									TempFile2=""
								fi								
								Line3="youtube-dl -q ${Line3} -f ${Saisie} ${url}\n" 
								case "${Opt^^}" in
									"A"*)
										echo -e "\n${SurCoul}${Line3}${NoCoul}"
									;;
									[IT]*)
										if [ -n "${Line3}" ]
										then
											echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Test de ${DataCoul}${VidName}${NoCoul}"
											${Line3} "--skip-download"
											echo -e "[$(date '+%H:%M:%S')] ${InfoCoul}terminé [ code: ${?}]${NoCoul}"
										fi
									;;
									*)
										Act="F"
										Line2="echo -e -n [\$(date '+%H:%M:%S')]: ${InfoCoul}Téléchargement de [${DataCoul}${TempFile1}, ${TempFile2}${InfoCoul}] ⏳\\b\n"
										Line4="echo -e terminé [ code: \$?]${NoCoul}\n"
										Line5="Encodage"
									;;
								esac
							else 
								Line2=""
								Line3=""
								Line4=""
								Line5="Traitement"
								TempFile1="${download_url}"
								TempFile2="${AltUrl}"
							fi
						
							if [[ "${Act^^}" == "F" ]]
							then
								Commande="ffmpeg ${FfOpts}"
								if [ -n "${fps}" ]
								then
									Params="-r:v ${fps:-25}"
								else Params=""
								fi
								n1=0
								Map=""
								for t1 in ${TempFile1}
								do
									Params="${Params} -thread_queue_size ${QueueSize:-4096} -i ${t1}"
									Map="$Map -map $n1"
									(( n1 += 1 ))
								done
								Tags=$(echo "${StreamTags}" | sed -E 's/[vas](:[0-9]*)? *-[lLtT]/-metadata:s:&/g' | sed -E 's/-[Ll]=/language=/g' | sed -E 's/-[Tt]=/title=/g')
#								Disp=$(echo "${Dispo}" | sed -E 's/[[:blank:]]/ -disposition:/g')
								if [ -n "${TempFile2}" ]
								then
									Saisie=$(echo ${AltMap,,} | grep -E -o '[vas]')
									Saisie=${Saisie//v/$n1:v}
									Saisie=${Saisie//a/$n1:a}
									Saisie=${Saisie//s/$n1:s}
									Saisie=$(echo ${Saisie} | sed -E 's/(-?[0-9]:[vas](:[0-9]*)?)/-map &?/g')
									if [ -n "$(echo ${AltMap} | grep -E -o '[pP]')" ]  
									then
										Map="${Saisie} ${Map}"
									else
										Map="${Map} ${Saisie}"
									fi
									Offset=$(echo ${AltOffset:-0} / 1000  | bc -l | sed -E 's/^(-?)[.]/\10./' | sed -E -e 's/[.]?0*$//')
									Params="${Params}"'\\'"\n -thread_queue_size ${QueueSize:-512} -itsoffset ${Offset:-0} -i ${TempFile2}"
									(( n1 += 1 ))
								fi
								if [ -n "$SubFile" ]
								then
									Offset=$(echo ${SubOffset:-0} / 1000  | bc -l | sed -E 's/^(-?)[.]/\10./' | sed -E -e 's/[.]?0*$//')
									Params="$Params"'\\'"\n -thread_queue_size ${QueueSize:-512} -itsoffset ${Offset:-0} -i ${SubFile}"
									Map="${Map} -map ${n1}:s?"
								fi
								Params="${Params//-itsoffset 0 /}"'\\'"\n ${Map}"'\\'"\n $Tags"'\\'"\n -c copy -c:a ${AudioCodec:-copy} -c:s ${SubCodec:-copy} -c:v:0 ${VideoCodec:-copy}"
								Params="${Params//-c:? copy /}"
								Line6="${Commande}"'\\'"\n ${Params}"'\\'"\n -metadata 'title=${VidName}'"'\\'"\n '${VidDest}'"
								case ${Opt^^} in
									A*)
										echo -e "\n${SurCoul}${Line6}${NoCoul}"
									;;
									[IT]*)
										if [ -n "$Commande" ]
										then
											echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Test de ${DataCoul}${VidName}${NoCoul}"												
											${Commande} ${Params} "-metadata" "'title=$VidName'" "-loglevel" "info" "-to" "1.00" "[test]${VidDest}"
											echo -e "[$(date '+%H:%M:%S')] ${InfoCoul}terminé [ code: ${?}]${NoCoul}"
										fi
									;;
								esac
							fi
							Line5="echo -e -n [$(date +%H:%M:%S)]: \${InfoCoul}${Line5} de [\${DataCoul}$VidName\${InfoCoul}] ⏳\\b"
							Line7='\\'"\n && code"'="erreur: $?"'
							Line8='echo -e "${code/erreur: 0/terminé}${NoCoul}"'
							if [ -f "${SubFile}" ]
							then Line7="${Line7}"'\\'"\n && rm -f ${SubFile}"
							fi
							case ${Opt^^} in
								"L"*)
									if [ -n "${Line6}" ]
									then
										scriptexec "${Line2}${Line3}${Line4}${Line5}\n${Line6}${Line7}\n${Line8}" "${TempName}"
									fi
								;;
								"F"*)
									Line1="#[$(date '+%D_%H:%M:%S')]"								
									Queue="${Queue}${Line1}\n${Line2}${Line3}${Line4}${Line5}\n${Line6}${Line7}\n${Line8}\n"
								;;
								*)
									Key=""
								;;
							esac
						;;
						[Rr]*)
							Commande=""
							Opts=""
						;;
						[hH?]*)
							Aide1
							read -p "[OK]"
						;;
					esac
					echo -e "\n"
				fi
			done
		fi
		Params=""
		Key="0"
		until [ "${Key^^}" = "" ]
		do
			echo -e "${InfoCoul}============================================================================${NoCoul}"
			if [ -n "$Queue" ]
			then
				echo -e "${SurCoul}A${NoCoul}fficher la liste de tâches"
				echo -e "${SurCoul}V${NoCoul}ider la liste de tâches"
				echo -e "${SurCoul}C${NoCoul}réer un script avec la liste des tâches"
				if [ -f $ScriptName ]
				then
					echo -e "${SurCoul}S${NoCoul}auver la liste à la fin du script existant"
				fi
				echo -e "e${SurCoul}X${NoCoul}écuter immédiatement la liste des tâches"
			fi
			echo -e "Enregistrer les ${SurCoul}P${NoCoul}aramètres actuels"
			echo -e "${SurCoul}? H${NoCoul}→ obtenir de l'aide"
			echo -e "${SurCoul}Q${NoCoul}uitter"
			echo -e "${InfoCoul}============================================================================${NoCoul}"
			read -p "votre choix, <nouvelle url> ou [Retour]: " Key
			case ${Key^^} in
				"A")
					echo -e "\n${SurCoul}${Queue}${NoCoul}\n"
				;;
				"V")
					Queue=""
				;;
				"C")
					echo -e "#!/bin/bash" > $ScriptName
					echo -e "#Liste des tâches TEW" >> $ScriptName
					echo -e "${Queue}" >> $ScriptName
					chmod "a+x" ${ScriptName}
					echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Le script ${DataCoul}${ScriptName}${InfoCoul} a été créé${NoCoul}"
				;;
				"S")
					echo -e "${Queue}" >> $ScriptName
					echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Le script ${DataCoul}${ScriptName}${InfoCoul} a été mis à jour${NoCoul}"
				;;
				"X")
					scriptexec "${Queue}" "${TempName}"
				;;
				[?H])
					Aide2
					read -p "[OK]"
				;;
				"P")
					write_config "$ConfFile"
					if [ $? ]
					then
						echo -e "[$(date '+%H:%M:%S')]: ${InfoCoul}Le fichier de configuration ${DataCoul}${ConfFile}${InfoCoul} a été mis à jour${NoCoul}"
					else
						echo -e "[$(date '+%H:%M:%S')]: ${WarnCoul}Impossible de mettre à jour le fichier de configuration ${DataCoul}${ConfFile}${NoCoul}"
					fi
				;;
				"Q")
					exit
				;;
				"D")
					read -p "Mode debug: saisir Video ID:" Saisie
					
				;;
				*)
					Saisie="${Key}"
					Key=""
				;;
			esac
		done
	done

Dernière modification par Lulux3 (Le 27/04/2020, à 21:10)

Hors ligne

#2 Le 12/05/2018, à 21:28

Lulux3

Re : Télécharger et "en même temps" Encoder une Webvidéo: TEW.sh

Bonjour
Je viens de poster une mise à jour assez sympa:
- L'ensemble du processus prend place dans une boucle: on garde donc tous les paramètres après l'éxécution, même en cas de plantage de ffmpeg ou ydl.
- On peut changer l'url et relancer un traitement avec les mêmes paramètres (ou pas): pratique pour les séries par exemple.
- On peut opter pour une mise en queue au lieu d'une exécution immédiate: pas besoin d'attendre pour préparer la tâche suivante.
- Le mappage reconnait les "stream-specifiers" de ffmpeg de la forme [-]{a,v,s}[:n]
- Les métadonnées peuvent être ajoutées aux flux.

Hors ligne

#3 Le 30/05/2018, à 17:20

Lulux3

Re : Télécharger et "en même temps" Encoder une Webvidéo: TEW.sh

Nouvelle mise à jour ce 30 mai:
- correctons de bugs mineurs
- amélioration de la lisibilité
- fonctions de prétraitement pour les sous-titres en VTT (france TV par exemple): filtrage des ST pour malentendants + conversion en ASS couleur (ffmpeg ne conserve pas les couleurs).

Hors ligne