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 27/04/2021, à 11:42

Jarodd

Récupérer les sous-titres d'un m2ts

Bonjour,
J'ai un fichier .m2ts provenant d'un enregistrement TV depuis la Freebox. Le fichier a plusieurs pistes audio.
Or il a été enregistré avec des pubs au début et à la fin. Je voudrais donc couper ces parties. J'utilise ffmpeg :

ffmpeg -i video.m2ts -vcodec copy -acodec copy -ss 00:04:18 -to 00:54:56.500 video_sans_pub.m2ts

Je coupe bien les pubs, par contre je me retrouve avec un fichier qui n'a plus qu'une seule piste audio.
J'ai fouillé dans la doc de mmpeg, mais je n'ai pas trouvé ce qu'il fallait mettre (la gestion des pistes ça a l'air bien compliqué !)
Je voudrais donc un conseil pour réussir à couper les pubs, tout en conservant toutes les pistes audio (et les sous-titres si possible, même s'ils n'ont pas l'air de bien fonctionner).
Merci pour votre aide.

Edit 01/05 : renommage du sujet
Sujet original : Couper une vidéo avec ffmpeg, en conservant les pistes audio
(résolu en #2)

Dernière modification par Jarodd (Le 01/05/2021, à 15:57)


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#2 Le 27/04/2021, à 13:11

grigouille

Re : Récupérer les sous-titres d'un m2ts

ffmpeg -i video.m2ts -map 0 -codec copy  -ss 00:04:18 -to 00:54:56.500 video_sans_pub.m2ts

Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#3 Le 27/04/2021, à 16:46

Lulux3

Re : Récupérer les sous-titres d'un m2ts

Bonjour
Pour les sous-titres, s'ils sont au format Teletext (utilisé par la Freebox pour les enregistrement via ADSL, mais pas via TNT), je me suis fait un outil qui va bien:

#!/bin/bash
#
#Auteur: Jean-Claude SCHILLING
#Mise à jour 28/04/2021
#Paramètres
	Page="${2:-888}"
	msmin="60"
	msmax="100"	
	MinTime="1200"
	MinSil="100"
	VidFile="${1}"
	FontName="Sans"
	
#Constantes
	HI="F"
	HIColor="red|magenta"
	HIFilter="^[.,;:]+$|^\(.*\)$"
	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" 
	t_Template="Dialogue: 0,<START>,<END>,<STYLE>,,0,0,0,<EFFECT>,<TEXTE>"
# 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"
		
#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
}
#Temps en secondes
hms2ms ()
{
	f_result="${1}"	
	local millis=${f_result/*.*/0}
	if [ -n "${f_result}" ]
	then
		if [ "${millis}" = "0" ]
		then millis="${f_result##*.}000"
			 millis="${millis::3}"
		else millis=""
		fi
		f_result="${f_result%.*}"
		local secondes=$(echo "${f_result##*:}" | sed -E 's/^[0]*//')
		if [ ${f_result/*:*/0} = "0" ]
		then 	f_result="${f_result%:*}"
			local minutes=$(echo "${f_result##*:}" | sed -E 's/^[0]*//')
		fi
		if [ ${f_result/*:*/0} = "0" ]
		then 	f_result="${f_result%:*}"
		local heures=$(echo "${f_result}" | sed -E 's/^[0]*//')
		fi		
		minutes=$((( ${heures:-0} * 60 ) + ${minutes:-0} ))
		secondes=$((( ${minutes:-0} * 60 ) + ${secondes:-0} ))
		f_result=$(echo "${secondes}${millis:-000}" | sed -E 's/^[0]*//')
	fi
	echo "${f_result}"
}
#Temps en HH:MM:SS
ms2hms ()
{
	if [ -n "${1}" ]
	then
		f_result=$(echo "${1}" | sed -E 's;[^0-9]];;g')
		if [ "${2:-3}" -lt 3 ]
		then 
			Saisie=500 ; Saisie=${Saisie::-${2}}
			f_result=$(( ${f_result} + ${Saisie:-500} ))
			Saisie=1000 ; Saisie=${Saisie::-${2}}
			f_result=$(( ${f_result} / ${Saisie:-1000} ))
		fi
		f_result="0000${f_result}"
		local secondes=$(echo "${f_result::-${2:-3}}" | sed -E 's/^0+//')
		local minutes=$(( ${secondes:=0} / 60 ))
		secondes=$(( ${secondes} % 60 )) ; secondes="00${secondes}"
		f_result="${secondes: -2}.${f_result: -${2:-3}}"
		local heures=$(( ${minutes} / 60 ))
		minutes=$(( ${minutes} % 60 )) ; minutes="00${minutes}"
		f_result="${minutes: -2}:${f_result}"
		f_result="${heures}:${f_result}"
		if [ -z "${2}" ]
		then 		
			f_result=$(echo "${f_result}" | sed -E 's/[0]*$//' | sed -E 's/^([0]+:)*[0]?//')
		fi
	else f_result=""
	f_result="${f_result%.}"
	fi
	echo "${f_result}"
}
#Résolution d'après la vidéo
resol_vid ()
{
	if [ -f "${1}" ]
	then
		local InFile="${1}"
		local Resol=$(ffmpeg -i "${InFile}" 2>&1 | grep -E "^[[:blank:]]*Stream.*: Video:")
		local fps
		Resol=$(echo "${Resol}" | grep -E -o ", [0-9]+x[0-9]+")
		f_result=$(echo "${Resol}" | grep -E -o ", [0-9]+ fps" |grep -E -o "[0-9]+")
		fps="${f_result:-${fps:-25}}"
		f_result="${Resol##*, }"
	else
		f_result="" ; return 1
	fi
	
}
#Taille de police
size_font ()
{
	local fs="${FontSize%% *}"
	local ry="${1}"
	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} (originale)"
		;;
		+*)
			if [ -n "${t_h}" ]
			then
				fs=$(( ${t_h} * 115 / 100 ))
				fs="${fs} (orig.agrandie)"
			fi
		;;
		-*)
			if [ -n "${t_h}" ]
			then
				fs=$(( ${t_h} * 85 / 100 ))
				fs="${fs} (orig.diminuée)"
			fi
		;;
		[1-9]*)
			fs=$(echo "${fs// /}" | grep -E -o "[1-9][0-9]*(\.[0-9])?")
			fs="${fs} (forcée)"
		;;
		[Nn]*)
			fs=$(( ( ${ry:-360} + 12 ) / 24 ))
			fs="${fs} (normale)"
		;;

		*)
			fs=$(( ( ${ry:-360} + 125 ) / 27 ))
			fs="${fs} (optimale)"
		;;
	esac	
	f_result="${fs:-16 (par défaut)}"
}
#Initialisation du fichier ASS
init_ass ()
{
			echo "[Script Info]" > "${OutFile}"
			echo "ScriptType: v4.00+" >> "${OutFile}"
			if [ -n "${VidResol}" ]
			then
				echo "PlayResX: ${VidResol%x*}" >> "${OutFile}"
				echo "PlayResY: ${VidRy}" >> "${OutFile}"
			fi	
			echo "WrapStyle: 0" >> "${OutFile}"
			echo "ScaledBorderAndShadow: yes" >> "${OutFile}"
			echo -e "\n[V4+ Styles]" >> "${OutFile}"
			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" >> "${OutFile}"
			Saisie="${Size#0}"
			local StyleLine="${s_Template//<SCALE?>/${Saisie:-100}}"
			size_font "${VidRy:-360}"
			f_result="${f_result%% *}"
			StyleLine="${StyleLine//<FONTSIZE>/${f_result:=18}}"
			f_result=$(( ${f_result} / 2 ))
			StyleLine="${StyleLine//<MARGINV>/${f_result}}"
			f_result=$(( ${f_result} * 4 ))
			StyleLine="${StyleLine//<?MARGIN>/${f_result}}"
			f_result=$(( ${f_result} * 4 + 80 ))
			StyleLine="${StyleLine//<OUTLINE>/${f_result%??}}"
			StyleLine="${StyleLine//<SHADOW>/0}"
			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}"  >> "${OutFile}"
				f_result="${f_result#*,}"
			done
			Line="${StyleLine/<STYLE>/Default}"
			Line="${Line/<COLOR>/HC0FFC0}"
			echo -e "${Line}\n"  >> "${OutFile}"
			echo -e "[Events]" >> "${OutFile}"
			echo "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" >> "${OutFile}"
}
# Nettoyage du fichier ASS avec conservation des couleurs
clean_ass ()
# Fichier Filtre[Taille]
{
	local Erreur=( 0 0 0 0 0 )
	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 AssScale=$(echo ${VidResol} | grep -E -o '[0-9]*$')
	AssScale=$((( ${AssScale:-720} + 5 ) / 10 ))
	local isValid=$(echo "${InFile,,}" | grep -E -o "\.ass$")
	local sTime=""
	local eTime="" 
	local nTime=""
	local MaxTime=""
	local Texte=""
	local Line=""
	local p_Line=""
	local Style=""
	local Couleur=""
	local t_scale=""
	local t_l="➖"
	local c1=""
	local d_max=""
	local d_min=""
	local style_tab="red H0000FF,white HFFFFFF,yellow H00FFFF,magenta HFF00FF,cyan HFFFF00,green H00FF00"
	if [ -n ${isValid} ]
	then OutFile="[mod]${InFile#\[temp\]}"
		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 "${InfoCoul}Conversion en cours${DataCoul}"
			init_ass
			while read Line
			do	
				Line=$(echo "${Line}" | sed -E 's/(^.*)\\N[[:blank:]]*/\1/')
				f_result=$(echo "${Line}" | grep -E -o "^Dialog|^Comment")
				if [ -n "${f_result}" ]
				then
					sTime=$(echo "${Line}" | sed -E 's/^[^,]*,([^,]*).*/\1/')
					f_result=$(hms2ms "${sTime}")
					Texte=$(echo "${Line}" | sed -E 's/^([^,]*,){9}(.*)$/\2/')
					f_result=$(( ${f_result:-0} + ${SubOffset:-0} ))
					if [ -n "${TimeScale}" ]
					then
						t_scale="${TimeScale%\/*}"
						f_num="${TimeScale#${t_scale}}"
						f_num="${f_num#*\/}"
						f_result=$((( ${f_result:-0} * ${t_scale:=1} ) /  ${f_num:-1} ))
					fi
					MaxTime=$(( ${f_result:-0} - ${MinSil:-0} ))
					if [ -n "${p_Line}" ]
					then					
						if [ "${n_Time:-0}" -gt "${f_result}" ]
						then
							eTime="$(( ${n_Time:-0} + ${d_min:-0} ))"
							echo -e -n "${t_l/➖/❗}" ; (( Erreur[3] += 1 ))
							p_Line="${p_Line//<EFFECT>/!Mauvaise chronologie!}"
						else						
							if [ "${d_max}" -gt 0 ]
							then 
								eTime="$(( ${n_Time:-0} + ${d_max:-0} ))"
								if [ "${eTime:-0}" -gt "${MaxTime}" ]
								then 
									eTime="$(( ${n_Time:-0} + ${d_min:-0} ))"
									if [ "${eTime:-0}" -gt "${MaxTime}" ]
									then
										t_l="${t_l/➖/➰}" ; (( Erreur[2] += 1 ))
										p_Line="${p_Line//<EFFECT>/!Chevauchement!}"
									else
										eTime="${MaxTime}"								
									fi
								fi
							else
								eTime="${MaxTime}"
							fi
							echo -n "${t_l}" ; t_l="➖"
							p_Line="${p_Line//<EFFECT>/}"
						fi
						n_Time="${f_result}"					
						f_result=$(ms2hms "${eTime}" 2)
						echo -e "${p_Line//<END>/${f_result}}" >> "${OutFile}"
					else n_Time="${f_result}"
					fi
					Couleur=$(echo "${Texte// /}" | grep -E -o "c&H[^&]*&\}")
					eTime="${n_Time}"
					Saisie=$(echo "${Texte// /}" | sed -E 's;\{[^}]*\}|\\N;;g' | sed -E 's/[^[:alnum:]]//g')
					d_max=$(( ${#Saisie} * ${msmax:=0}))
					d_min=$(( ${#Saisie} * ${msmin:=60}))
					if [ "${d_min:-0}" -lt "${MinTime:=1200}" ]
					then
						d_min="${MinTime}"
					fi
					if [ "${d_max}" -gt 0 ]
					then
						if [ "${d_max:-0}" -lt "${d_min}" ]
						then
							d_max="${d_min}"
						fi
					fi
					sTime=$(ms2hms "${n_Time:-0}" 2)
					p_Line=""
					if [ -n "${Couleur}" ]
					then
						t0="${Texte%%\{\\c&*}"
						Texte="${Texte#"$t0"}"
					else t0=""
					fi
					Texte="${Texte//\*/\{\\i1\}}"
					while [ -n "${Texte}" ]
					do	
						Couleur="${Couleur%&\}*}"
						c1="${Couleur##*c&}"
						t1="${Texte##*&\}}"
						Style="Defaut"
						if [ -n "${c1}" ]
						then
							Texte="${Texte%\{\\c&*}" ; Texte="${Texte%\\N}"					
							Style=$(echo ${style_tab} | grep -E -o "[^,]*${c1}")
							if [ -n "${Style}" ]
							then Style="s_${Style%% *}"
							else t1="{\\c&${c1}&}${t1}" ; Style="s_Defaut"
							fi
						else Texte=""						
						fi			
						l1="${t_Template/<TEXTE>/"${t0}${t1}"}"
						l1="${l1/<STYLE>/${Style}}"
						if [ "${HI,,}" = "f" ]
						then
							if [ -n "${#Saisie}" ]
							then Saisie=$(echo ${l1} | grep -E -o "s_${HIColor:-red}")
								if [ -z "${Saisie}" ]
								then
									Saisie=$(echo "${t1// /}" | sed -E 's;\{[^}]*\}|\\N;;g' | grep -E -o "${HIFilter}")
								fi
							fi
							if [ -n "${Saisie}" ]
							then 
								l1="${l1/#Dialogue/Comment}"
								t_l="❔" ; (( Erreur[0] += 1 ))
							fi
						fi
						if [ -n "${p_Line}" ]
						then p_Line="${p_Line//<EFFECT>/!Ligne dédoublée!}\n"
							 l1="${l1//<EFFECT>/!Ligne dédoublée!}"
							 t_l="➗" ; (( Erreur[1] += 1 ))
						fi							
						p_Line="${p_Line}${l1//\\/\\\\}"
					done
					if [ "${n_time:-0}" -lt 0 ]
					then 
						t_l="⛔"
						(( Erreur[4] += 1 ))
						p_Line="${p_Line//<EFFECT>/!Temps négatif!}"
						
					fi
					p_Line="${p_Line//<START>/${sTime}}"
	 				
				fi
			done < $InFile
			f_result=$(ms2hms "${eTime}" 2)
			p_Line="${p_Line//<EFFECT>/}"
			echo -e "${p_Line//<END>/${f_result}}" >> "${OutFile}"
			echo -e "terminé."
		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
	echo -e "⛔ ${Erreur[4]} Erreurs - ❗ ${Erreur[3]} Mauvaises chronologies - ➰ ${Erreur[2]} Chevauchements - ➗ ${Erreur[1]} lignes dédoublées - ❔ ${Erreur[0]} lignes filtrées"
	if [ "${Erreur[4]}" -gt 0 ]
	then return 1
	else return 0
	fi
}

#Soustraction de temps
dTime ()
{
	f_result=$(hms2ms "${1}")
	local stime="${f_result}"
	f_result=$(hms2ms "${2}")
	if [ -n "${f_result}" ]
	then
		f_result=$(( ${f_result} - ${stime:-0} ))
		f_result=$(ms2hms "${f_result}")
	fi
}

#Menu principal
menu_param ()
{
				echo -e "\r${InfoCoul}============================================================================${NoCoul}"
				echo -e "${NoCoul}RESUME DES PARAMETRES:${NoCoul}"
				echo -e "${NoCoul}----------------------------------------------------------------------------"
				if [ ! "${VidFile##*.}" = "ass" ]
				then		
					echo -e "${SurCoul}S${NoCoul}ource Vidéo: 	\t${DataCoul}${VidFile}${NoCoul}"		
					echo -e "\t${SurCoul}D${NoCoul}epuis: 		\t${DataCoul}${Debut}${NoCoul}"
					echo -e "\t${SurCoul}J${NoCoul}usque: 		\t${DataCoul}${Fin}${NoCoul}"
					dTime ${Debut} ${Fin}
					echo -e "\t[info] Durée: \t${DataCoul}${f_result:-inconnue}${NoCoul}"
					echo -e "\t${SurCoul}P${NoCoul}age télétexte: \t${DataCoul}${Page:=888}${NoCoul}"
					echo -e "\t${SurCoul}M${NoCoul}ode:         \t${DataCoul}${Mode:=ass}${NoCoul}"
					echo -e "\td${SurCoul}U${NoCoul}rée mini ST: \t${DataCoul}${MinTime:=1200}${NoCoul} ms"								
					echo -e "${SurCoul}E${NoCoul}xtraire la page teletexte de la source"
					echo -e "${NoCoul}----------------------------------------------------------------------------"				
				fi
				echo -e "\t${SurCoul}V${NoCoul}ers le fichier: \t${DataCoul}${TxtFile:=${VidFile/%.*/.ass}}${NoCoul}"
				if [ -f "${TxtFile}" ]
				then
					if [ "${TxtFile##*.}" = "ass" ]
					then
						SubRx=$(grep -E "^PlayResX" "${TxtFile}"| grep -E -o "[0-9]*")
						SubRy=$(grep -E "^PlayResY" "${TxtFile}"| grep -E -o "[0-9]*")
						TxtResol="${SubRx}x${SubRy}"
						Saisie=$(grep -E -o "Style:[[:blank:]]*Subtitle(,[^,]*){2}" "${TxtFile}")
						Saisie="${Saisie// /}" ; t_h="${Saisie##*,}" ; Saisie="${Saisie%,*}"
						t_f="${Saisie##*,}"
						VidRy="${VidResol##*x}"
						VidRy="${VidRy:=${SubRy}}"
						t_h=$(( ${t_h:-8} * ${VidRy:-360} / ${SubRy:-360} ))			
						echo -e "[info]\t${DataCoul}Résolution du télétexte:	\t${DataCoul}${TxtResol:-inconnue}${NoCoul} (lxh)"				
						echo -e "\t${SurCoul}R${NoCoul}ésolution de référence:	\t${DataCoul}${VidResol:-${TxtResol:-inconnue} (par défaut)}${NoCoul} (lxh)"				
						echo -e "\tdécala${SurCoul}G${NoCoul}e: 				\t${DataCoul}${SubOffset}${NoCoul} millisecondes"
						echo -e "\teche${SurCoul}L${NoCoul}le des temps:		\t${DataCoul}${TimeScale}${NoCoul}"
						if [ "${HI}" = F ]
						then Saisie="Actif"
						else Saisie="Inactif"
						fi
						echo -e "\t${SurCoul}F${NoCoul}iltrer Malentendants:	\t${DataCoul}${Saisie}${NoCoul}"
						echo -e "\tp${SurCoul}O${NoCoul}lice:					\t${DataCoul}${FontName:=${t_f}}${NoCoul}"
						size_font "${VidRy}"		
						echo -e "\t${SurCoul}T${NoCoul}aille de police:			\t${DataCoul}${f_result/ / ${NoCoul}}"
						Saisie="${TxtScale#0}"
						echo -e "\tEchelle de ${SurCoul}Z${NoCoul}oom:			\t${DataCoul}${Saisie:-Automatique}${NoCoul}"								
						echo -e "${SurCoul}N${NoCoul}ettoyer maintenant"
					fi
				fi				
				echo -e "----------------------------------------------------------------------------"
				echo -e "${SurCoul}? H${NoCoul}→ obtenir de l'aide"
				echo -e "----------------------------------------------------------------------------"
				echo -e "${SurCoul}Q${NoCoul}uitter"
				echo -e "${InfoCoul}============================================================================${NoCoul}"
				echo -e -n "Saisir une [${SurCoul}clé${NoCoul}]....\b${NoCoul}"
}

resol_vid "${VidFile}"
VidResol="${f_result}"
#Boucle principale
while [ ! "${Key}" = "q" ]
do
	menu_param
	read  Key Param
	Saisie=""
	Param="${Key:1}${Param}"
	Key="${Key::1}"
	case "${Key,,}" in
		d)
			Param=$(echo "${Param}" | grep -E -o "[0-5]?[0-9](:[0-5][0-9]){,2}([.][0-9]{,3})?|[0-9]+([.][0-9]{,3})?")
			if [ -z "${Param}" ]
			then
				read -p "Temps de début: [${Debut}]" Param
				Param=$(echo "${Param}" | grep -E -o "[0-5]?[0-9](:[0-5][0-9]){,2}([.][0-9]{,3})?|[0-9]+([.][0-9]{,3})?")
			fi
			Debut="${Param:-${Debut}}"
			Debut="${Debut#0}"
		;;
		j)
			Param=$(echo "${Param}" | grep -E -o "[0-5]?[0-9](:[0-5][0-9]){,2}([.][0-9]{,3})?|[0-9]+([.][0-9]{,3})?")
			if [ -z "${Param}" ]
			then
				read -p "Temps de fin: [${Fin}]" Param
				Param=$(echo "${Param}" | grep -E -o "[0-5]?[0-9](:[0-5][0-9]){,2}([.][0-9]{,3})?|[0-9]+([.][0-9]{,3})?")
			fi
			Fin="${Param:-${Fin}}"
			Fin=${Fin#0} 
		;;
		p)
			Param=$(echo "${Param}" | grep -E -o "[0-9]{3}")
			if [ -z "${Param}" ]
			then
				read -p "Page télétexte: [${Page}]" Param
				Param=$(echo "${Param}" | grep -E -o "[0-9]{3}")
			fi
			Page="${Param:-${Page}}"
		;;
		t)
			Param=$(echo "${Param}" | grep -E -o "[+><=-]|[0-9]+(.[0-9])?%?")
			if [ -z "${Param}" ]
			then
				echo -e "Pour utiliser la taille d'origine, taper ${SurCoul}=${NoCoul}"
				echo -e "Pour utiliser une plus grande/petite taille, taper ${SurCoul}+/-${NoCoul}"
				echo -e "Pour utiliser une taille optimale, taper ${SurCoul}0${NoCoul}"
				echo -e "Pour utiliser un pourcentage de l'écran, taper ${SurCoul}<1-9>%${NoCoul}"								
				read -p "Taille de police: [${FontSize}]" Param
				Param=$(echo "${Param}" | grep -E -o "[+><=-]|[0-9]+(.[0-9])?%")
			fi
			FontSize="${Param:-${FontSize}}"
			FontSize="${FontSize#0}"
		;;
		o)
			if [ -z "${Param}" ]
			then
				echo -e "Pour utiliser la police d'origine, taper ${SurCoul}=${NoCoul}"
				read -p "Police: [${FontName}]" Param
			fi
			Param="${Param/*=*/${t_f}}"
			FontName="${Param:-${FontName}}"
		;;
		z)
			Param=$(echo "${Param}" | grep -E -o "[0-9]+")
			if [ -z "${Param}" ]
			then
				read -p "Facteur de zoom: [${TxtScale}]%" Param
				Param=$(echo "${Param}" | grep -E -o "[0-9]+")
			fi
			TxtScale="${Param:-${TxtScale}}"
		;;
		m)
			Param=$(echo "${Param}" | grep -E -o "text|ass")
			if [ -z "${Param}" ]
			then
				read -p "Mode d'extraction (text|ass): [${Mode}]" Param
				Param=$(echo "${Param}" | grep -E -o "text|ass")
			fi
			Mode="${Param:-${Mode}}"
		;;
		u)
			Param=$(echo "${Param}" | grep -E -o "[0-9]*")
			if [ -z "${Param}" ]
			then
				read -p "Durée minimale par ligne (ms): [${MinTime}]" Param
				Param=$(echo "${Param}" | grep -E -o "[0-9]*")
			fi
			MinTime="${Param:-${MinTime}}"
		;;
		s)
			if [ ! -f "${Param}" ]
			then
				read -p "Source Vidéo: [${VidFile}]" Param
			fi
			resol_vid "${Param}"
			if [ "${0}" = 0 ]
			then VidFile="${Param}"
				VidResol="${f_result}"
				if [ $(confirme "modifier aussi la destination? [O/N]") ]
				then TxtFile="${VidFile/%.*}${Mode/text/srt}"
				fi
			fi
		;;
		v)
			if [ -z "${Param}" ]
			then
				read -p "Nom du fichier sans l'extension: [${TxtFile%.*}]" Param
			fi
			if [ -n "${Param}" ]
			then	TxtFile="${Param# }.${Mode/text/srt}"
			fi
		;;
		e)
			echo -e -n "\r${InfoCoul}Extraction du télétexte..............⏳\b${NoCoul}"
			if [ "${Page:=888}" = "000" ]
			then txt_page=""
			else txt_page="-txt_page $Page"
			fi			
			if [ -n "${Fin}" ]
			then
				ffmpeg -y -loglevel error \
					-txt_format "${Mode:=ass}" -txt_duration "${MinTime:=1200}" $txt_page \
					-i "${VidFile}" \
					-ss "${Debut:-0}" -to "${Fin}" \
					"${TxtFile:=${VidFile/%.*}.${Mode/text/srt}}" 2>> "${LogFile:=tltx2ass.log}"
					f_result="$?"
			else
				ffmpeg -y -loglevel error \
					-txt_format "${Mode:=ass}" -txt_duration "${MinTime:=1200}" $txt_page \
					-i "${VidFile}" \
					-ss "${Debut:-0}" \
					"${TxtFile:=${VidFile/%.*}.${Mode/text/srt}}" 2>> "${LogFile:=$HOME/Developpement/tew/tltx2ass.log}"
					f_result="$?"
			fi
			if [ ${f_result} = "0" ]
			then echo -e "terminée"
			else echo -e "${ErrCoul}ERREUR ${f_result}${NoCoul}"
			fi
		;;
		r)
			Param=$(echo "${Param}" | grep -E -o "[0-9]+x[0-9]+|0")
			if [ -z "${Param}" ]
			then
				read -p "Résolution de référence: [${VidResol}]" Param
				Param=$(echo "${Param}" | grep -E -o "[0-9]+x[0-9]+|0")
			fi
			VidResol="${Param:-${VidResol}}"
			VidResol="${VidResol#0}"
		;;
		f)
			Param=$(echo "${Param::1}" | grep -E -o -i "[01ONYAI]")
			if [ -z "${Param}" ]
			then
				read -p "Filtrer les ST pour malentendants: [${HI/1/Actif}${HI/0/Inactif}]" Param
				Param=$(echo "${Param::1}" | grep -E -o -i "[01ONYAIF]")
			fi
			Param=$(echo "${Param,,}"  | sed -E 's/[1aoyf]/F/' | sed -E 's/[0in]/0/')
			HI="${Param:-${HI}}"
		;;
		g)
			Param=$(echo "${Param}" | grep -E -o -e "-?[0-9]+")
			if [ -z "${Param}" ]
			then
				read -p "Décalage en millisecondes: [${SubOffset}]" Param
				Param=$(echo "${Param}" | grep -E -o -e "-?[0-9]+")
			fi
			SubOffset="${Param:-${SubOffset}}"
			SubOffset="${SubOffset#0}"
		;;
		l)
			Param=$(echo "${Param// /}" | sed -E 's;[^[0-9]./];;g')
			if [ -z $(echo ${Param//0/} | grep -E -o "[1-9]+[/][1-9]+|[1-9]*\.?[1-9]*)?") ]
			then
				read -p "Echelle de temps: [${TimeScale}]" Param
			fi
			Param=$(echo "${Param// /}" | sed -E 's;[^[0-9]./];;g')
			if [ "${Param/*.*/0}" = "0" ]
			then  Saisie="${Param#*.}"
				Param="${Param/./}/1${Saisie//?/0}"
			fi
			if [ -n $(echo ${Param//0/} | grep -E -o "[1-9]+[/][1-9]+|[1-9]+") ]
			then 
			TimeScale="${Param}"
			fi
		;;
		n)
			if [ -f "${TxtFile}" ]
			then 
#NETTOYAGE preliminaire	
				
				OutStr=$( 	sed -E 's/([\]h)+/ /g' "${TxtFile}" |\
							sed -E 's/[[:blank:]]+/ /g' |\
							sed -E 's/([.,:;!?]+)([[:alpha:]])/\1 \2/g' |\
							sed -E 's/([^[:alnum:]][-])([^ ])/\1 \2/g' |\
							sed -E 's/([[:blank:]]*\\N)+/\\N/g' |\
							sed -E 's/\\/\\\\/g' |\
							sed -E 's/[[:blank:]]+([.,:!?;-]+)/\1/g')

				echo "${OutStr}" > "[temp]${TxtFile}"		
				clean_ass "[temp]${TxtFile}" "${HI}${TxtScale}"
				if [ "${?}" = "0" ]
				then
					mv "${TxtFile}" "[old]${TxtFile}" 
					rm "[temp]${TxtFile}"
					mv "[mod]${TxtFile}" "${TxtFile}"
				else
					echo -e "${ErrCoul} Oups, quelque chose s'est mal passé!${NoCoul}"
				fi					
			fi					
		;;		
		q)
			exit
		;;		
	esac
done
exit

- Crée un fichier "tltx2ass.sh" et donne lui les droits d'exécution.
- lance la commande:
     

tltx2ass.sh video.m2ts

- regle le temps de début:

d4:18

- regle le temps de fin: 

j54:56.5

- change la page teletext si tu te contentes de sous-titres monochromes centrés (ou si la page 888 ne contient rien): 

p889

- change les autres paramètres de la même manière si nécessaire
- tape 

e

pour extraire les sous-titres vers le fichier video.ass
- ajuste les paramètres suivants selon tes préférences, ou laisse les valeurs par défaut.
- tape 

n

pour "nettoyer le fichier" (ajuste les durées d'affichage, supprime les lignes vides, commente les ST spécifiques aux malentendants si c'est souhaité, etc..)

Essaie et dis-moi ce que tu en penses.

Dernière modification par Lulux3 (Le 28/04/2021, à 11:00)

Hors ligne

#4 Le 27/04/2021, à 16:51

Jarodd

Re : Récupérer les sous-titres d'un m2ts

Merci grigoulle pour la commande ! Elle a bien fonctionné.
Par contre, je n'arrive plus à ouvrir le fichier video.m2ts, ni video_sans_pub.m2ts. VLC charge indéfiniment, mais rien ne se lance.
Vidéos (l'appli fournie avec Ubuntu) ne peux pas lire du m2ts visiblement (demande de télécharger un greffon, qui échoue).

Dès que j'ai réussi à lancer la vidéo, j'essaye ton script Lulux !


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#5 Le 27/04/2021, à 17:43

Jarodd

Re : Récupérer les sous-titres d'un m2ts

@Lulux3 Voici le résultat obtenant en lançant le programme :

$ ./tltx2ass.sh video.m2ts 
./tltx2ass.sh: ligne 303: resol_vid : commande introuvable
============================================================================
RESUME DES PARAMETRES:
----------------------------------------------------------------------------
Source Vidéo: 		
	Depuis: 			
	Jusque: 			
./tltx2ass.sh: ligne 235: hms2ms : commande introuvable
./tltx2ass.sh: ligne 237: hms2ms : commande introuvable
	[info] Durée: 	inconnue
	Page télétexte: 	888
	Mode:         	ass
	dUrée mini ST: 	1200 ms
Extraire la page teletexte de la source
----------------------------------------------------------------------------
	Vers le fichier: 	
----------------------------------------------------------------------------
? H→ obtenir de l'aide
----------------------------------------------------------------------------
Quitter
============================================================================
Saisir une [clé]....

Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#6 Le 27/04/2021, à 18:10

Lulux3

Re : Récupérer les sous-titres d'un m2ts

Bonsoir
Il semble que tu n'aies pas copié la totalité du fichier.
Vérifie avec un éditeur de texte: il doit y avoir 688 lignes.
Par ailleurs, il faut te mettre dans le répertoire qui contient le fichier "video.m2ts".

Hors ligne

#7 Le 27/04/2021, à 20:08

Jarodd

Re : Récupérer les sous-titres d'un m2ts

Exact je n'avais pas copié la totalité du fichier...
J'ai modifié les lignes 597 et 604 car ce chemin n'existait pas chez moi.
J'ai tout paramétré (je n'ai pas bien compris le p889), et après avoir tapé "e", j'ai bien un fichier video.ass, mais qui fait 0 octet.
Comment etre sûr qu'il y a bien des sous-titres dans la vidéo ? Je les active dans le menu de VLC, mais rien n'apparaît, peut-être qu'il n'y a rien.


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#8 Le 28/04/2021, à 10:38

Lulux3

Re : Récupérer les sous-titres d'un m2ts

Bonjour

Jarrod a écrit :

je n'ai pas bien compris le p889

Il s'agit de choisir la page télétext. Habituellement (sur France TV et Arte entre autres), les pages disponibles sont 888 (malentendants) et 889 (standard)

Jarrod a écrit :

j'ai bien un fichier video.ass, mais qui fait 0 octet

Etrange: en cas de page vide, on devrait avoir un fichier ass de 736 octets (l'en-tête de fichier seule)

Jarrod a écrit :

Comment etre sûr qu'il y a bien des sous-titres dans la vidéo ?

Utilise Mediainfo (passe en mode html pour plus de détails, et notamment l'identification des pages)

Hors ligne

#9 Le 28/04/2021, à 10:55

Lulux3

Re : Récupérer les sous-titres d'un m2ts

Juste un petit plus
Ci dessous un patch qui permet de charger toutes les pages, en entrant "000" comme numéro de page.
Le fichier obtenu est inutilisable s'il y a plusieurs pages (tous les sous-titres se retrouvent mélangés dans un seul fichier ASS), mais cela permet de vérifier la présence ou non de sous-titres.
Et ça résoud également

J'ai modifié les lignes 597 et 604 car ce chemin n'existait pas chez moi

Les lignes ci-dessous doivent venir remplacer les lignes 591 à 606 du script d'origine.

			if [ "${Page:=888}" = "000" ]
				then txt_page=""
				else txt_page="-txt_page $Page"
			fi			
			if [ -n "${Fin}" ]
			then
				ffmpeg -y -loglevel error \
					-txt_format "${Mode:=ass}" -txt_duration "${MinTime:=1200}" $txt_page \
					-i "${VidFile}" \
					-ss "${Debut:-0}" -to "${Fin}" \
					"${TxtFile:=${VidFile/%.*}.${Mode/text/srt}}" 2>> "${LogFile:=tltx2ass.log}"
					f_result="$?"
			else
				ffmpeg -y -loglevel error \
					-txt_format "${Mode:=ass}" -txt_duration "${MinTime:=1200}" $txt_page \
					-i "${VidFile}" \
					-ss "${Debut:-0}" \
					"${TxtFile:=${VidFile/%.*}.${Mode/text/srt}}" 2>> "${LogFile:=tltx2ass.log}"
					f_result="$?"
			fi

J'édite mon post d'hier avec cette mise à jour.

Hors ligne

#10 Le 01/05/2021, à 15:56

Jarodd

Re : Récupérer les sous-titres d'un m2ts

Bonjur,
J'ai fait le changement de la ligne 591 à 606.
J'ai toujours un fichier .ass de 0 octet, et j'obtiens ces logs :

[libzvbi_teletextdec @ 0x5632ca77bac0] [Eval @ 0x7ffd7d1360b0] Undefined constant or missing '(' in 'ass'
[libzvbi_teletextdec @ 0x5632ca77bac0] Unable to parse option value "ass"
[libzvbi_teletextdec @ 0x5632ca77bac0] Error setting option txt_format to value ass.
[libzvbi_teletextdec @ 0x5632ca7c3620] [Eval @ 0x7ffd7d136520] Undefined constant or missing '(' in 'ass'
[libzvbi_teletextdec @ 0x5632ca7c3620] Unable to parse option value "ass"
[libzvbi_teletextdec @ 0x5632ca7c3620] Error setting option txt_format to value ass.
Error while opening decoder for input stream #0:0 : Invalid argument

Edit : j'ai renommé le sujet pour coller à la discussion actuelle, le problème initial ayant été résolu en #2.

Dernière modification par Jarodd (Le 01/05/2021, à 15:58)


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne