cClaude.rocks ☕ Le blog

L'informatique et les nouvelles technologies

Menu
Ce billet a été édité le : 2020-04-13

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,&lt;,<,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,&lt;,<,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,&lt;,<,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,&lt;,<,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,&lt;,<,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.

኿


â„č 2006 - 2020 | 🕾 Retour Ă  l'accueil du domaine | 🏡 Retour Ă  l'accueil du blog