#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
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)
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)
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