Lorsquâon Ă©dite les textes sur kdenlive
il est trĂšs facile de faire dâeffacer des caractĂšres lors de certaines manipulations. De maniĂšre gĂ©nĂ©rale, lâĂ©diteur de texte nâest pas super conviviale, le curseur Ă©tant peu visible. De plus suivant les effets que lâon cherche Ă produire, le texte peut ĂȘtre difficilement lisible, on se retrouve avec du noir sur noir par exemple.
LâidĂ©e est donc la suivante :
Extraire le texte des fichiers projets de kdenlive.
Les fichiers projets de kdenlive
sont stockĂ©s sur le disque sous la forme dâun fichier XML
nommé « exemple.kdenlive ».
Pour gérer, les fichiers XML
, je vais utiliser ici xpath
en essayant de décrire la procédure étape par étape.
Prérequis
Il faut tout dâabord un outil permettant de manipuler le XML
et pour cela jâai choisi la solution basĂ©e sur perl
. Une solution robuste et bien intégrée au systÚme. Sur les systÚmes basés sur Debian (comme Ubuntu et Mint) installe la commande xpath
comme suit :
sudo apt update && sudo apt install -y libxml-xpath-perl
Configuration de votre environnement de test
Pour suivre ce tutoriel sur votre propre machine, dans un terminal affecter Ă la variable FILE
le nom dâun fichier projet kdenlive
contenant du texte.
FILE=~/kdenlive/mes-projets/mon-film.kdenlive
Prenez quelques minutes pour regarder la structure de ce fichier dans lâĂ©diteur de votre choix.
Analyse des besoins
On va chercher Ă rĂ©cupĂ©rer le texte et on sâaperçoit quâil est en fait dans un code XML
« encodé » dans le XML
de base.
Il va donc valoir isoler le code XML
embarqué, le reformater correctement, puis extraire le texte.
Pour extraire le code XML
embarqué, on va isoler les éléments de type property
avec lâattribut name
valant xmldata
.
Cela sâobtient comme suit :
xpath -e '//property[@name="xmldata"]' "${FILE}"
Comme on ne veut que le contenu de lâĂ©lĂ©ment on peut mĂȘme Ă©crire :
xpath -e '//property[@name="xmldata"]/text()' "${FILE}"
Pour convertir ce XML
encodé, en XML
valide, il faut ajouter une entĂȘte, et un Ă©lĂ©ment racine.
La conversion est trĂšs simple Ă faire avec la commande sed
 :
xpath -e '//property[@name="xmldata"]/text()' "${FILE}" | sed -e 's,<,<,g'
Pour ajouter un entĂȘte et un Ă©lĂ©ment racine, on peut utiliser lâastuce suivante, basĂ©e sur cat
 :
cat <<EOF
<?xml version='1.0' encoding='utf-8'?>
<root>
$(
xpath -e '//property[@name="xmldata"]/text()' "${FILE}" | sed -e 's,<,<,g'
)
</root>
EOF
Maintenant on a un nouveau flux XML
valide que lâon va pouvoir utiliser. Dans ce flux on cherche Ă obtenir le contenu de lâĂ©lĂ©ment content
qui lui-mĂȘme se trouve dans lâĂ©lĂ©ment item
de lâĂ©lĂ©ment kdenlivetitle
.
Cela sâĂ©crit comme suit :
xpath -e '//kdenlivetitle/item/content'
Et donc on a une premiĂšre solution (quick and dirty) qui sâĂ©crit comme cela :
cat <<EOF | xpath -e '//kdenlivetitle/item/content/text()'
<?xml version='1.0' encoding='utf-8'?>
<root>
$(
xpath -e '//property[@name="xmldata"]' "${FILE}" | sed -e 's,</property>,,g' | sed -e 's,<property name="xmldata">,,g' | sed -e 's,<,<,g'
)
</root>
EOF
On peut améliorer le résultat avec un peu de ménage :
cat <<EOF | xpath -q -e '//kdenlivetitle/item/content/text()'
<?xml version='1.0' encoding='utf-8'?>
<root>
$(
xpath -q -e '//property[@name="xmldata"]/text()' "${FILE}" | sed -e 's,<,<,g'
)
</root>
EOF
On a plus ou moins ce quâon souhaitait, mais si on veut corriger un texte, cela risque de ne pas ĂȘtre simple de le retrouver dans kdenlive
.
On a perdu lâordre et le nom des zones de texte. Lâordre nâest pas si important, puis que dans kdenlive
il est basé sur le nom du clip
. Au final seul le nom du clip
est nécessaire.
Pour énumérer les noms des éléments contenant du texte on peut commencer par :
xpath -q -e '//property[@name="kdenlive:clipname"]/text()' "${FILE}"
Cependant on ne veut que les éléments répondant à property[@name="xmldata"]
, on doit donc adapter le code comme suit :
xpath -q -e '//property[@name="xmldata"]/../property[@name="kdenlive:clipname"]/text()' "${FILE}"
Ici ..
permet de revenir Ă lâĂ©lĂ©ment parent pour donner une nouvelle condition.
OK, maintenant on va revenir un peu en mode bash
pour pouvoir associer ces deux solutions, puisque lâon souhaite associer le nom du clip
au texte correspondant :
Dans un premier temps, il faut réécrire la ligne précédente comme suit :
while read -r clipname ; do
echo "> ${clipname}Â :"
done < <(
xpath -q -e '//property[@name="xmldata"]/../property[@name="kdenlive:clipname"]/text()' "${FILE}"
)
Presque rien nâa changĂ©, juste un peu de prĂ©sentation ajoutĂ©e au passage.
Il ne reste plus quâĂ rechercher les Ă©lĂ©ments du fichier ayant un Ă©lĂ©ment property
avec attribut name
valant kdenlive:clipname
et un contenu correspondant au nom du clip
courant and .="${clipname}"
.
Il y a quelque problĂšme de guillemets Ă rĂ©gler au passageâŠ
Et finalement :
On peut mettre tout cela dans une fonction, et on obtient :
function extract_text {
local file="$1"
while read -r clipname ; do
echo
echo "> ${clipname} :"
echo
cat <<EOF | xpath -q -e '//kdenlivetitle/item/content/text()'
<?xml version='1.0' encoding='utf-8'?>
<root>
$(
xpath -q -e "//property[@name=\"kdenlive:clipname\" and .=\"${clipname}\" ]/../property[@name=\"xmldata\"]/text()" "${file}" | sed -e 's,<,<,g'
)
</root>
EOF
done < <( xpath -q -e '//property[@name="xmldata"]/../property[@name="kdenlive:clipname"]/text()' "${file}" | sort )
}
Que lâon peut utiliser comme suit :
extract_text ~/kdenlive/mes-projets/mon-film.kdenlive >textes-de-la-vidéo.txt
Câest cool, non ?
Limitations
On ne peut pas vraiment utiliser la mĂȘme mĂ©thode pour rĂ©injecter le texte, cela casserait la prĂ©sentation. Sinon, il faut tenir compte de la gĂ©omĂ©trie du projet, de la longueur du texte, de la gĂ©omĂ©trie de la police de caractĂšre et ce pour chaque caractĂšre.
኿