Closed: [2024-07-12 ven. 14:37]

Le titre est peut-être mal trouvé mais l’idée est d’avoir une liste de vidéos qui puisse être téléchargée facilement.

J’ai commencé à faire une liste de vidéos que j’aurais envie de regarder hors ligne durant mes congés. Comme je suis plongé dans emacs et org-mode j’ai commencé à faire ma liste dans un nouveau fichier org. Et j’ai ajouté un bloc de commande shell pour télécharger un lien. Je ne sais pas si c’est de la programmation léttrée (literate programming) mais cela m’a permis de commencer par une bête liste, d’ajouter un bloc de code puis des commentaires et d’avoir un document qui décrit tout le processus.

Voici ci-dessous le document org brut. Il est directement utilisable.
Je trouve que c’est malgré tout lisible et qu’on peut suivre le cheminement dans l’évolution du script.

#+TITLE: Vidéos à télécharger

Une liste de vidéos à télécharger sur la surface pour regarder pendant les vacances.

* La version simple

On va déclarer des références qui vont contenir nos variables.

Tout d'abord la liste des vidéos.

#+NAME: liste-videos
- https://www.youtube.com/watch?v=4-ubCJF9htw
- https://www.youtube.com/watch?v=g6YA4tiW1eQ

Ensuite le répertoire de destination avec le paramètre avant.
Je ne sais pas comment passer juste le chemin en variable dans un autre bloc.
#+NAME: destination
--paths home:/home/montfort/Perso/videos/

Et la commande à utiliser pour télécharger les vidéos.
#+NAME: commande
yt-dlp --no-warnings --no-progress --quiet


Maintenant nous avons tout pour lancer notre commande bash.
On peut lancer l'exécution du bloc avec ~C-c C-c~.
#+begin_src bash :results verbatim :var liste=liste-videos commande=commande destination=destination :session yt-dlp :async yes
  for video in ${liste[@]}
  do
      echo ${commande}${destination} ${video}
  done
#+end_src

#+RESULTS:
#+begin_example
yt-dlp --no-warnings --no-progress --quiet --paths home:/home/montfort/Perso/videos/ https://www.youtube.com/watch?v=4-ubCJF9htw
yt-dlp --no-warnings --no-progress --quiet --paths home:/home/montfort/Perso/videos/ https://www.youtube.com/watch?v=g6YA4tiW1eQ
#+end_example

* La version avec description des vidéos

On peut améliorer notre script en ajoutant une description pour chaque lien de téléchargement de vidéo pour mieux se retrouver dans toutes les vidéos.

Pour cela on va définir une table org.
#+tblname: liste-videos-commentaire
| url                                                          | description                          |
| https://youtu.be/mLzFJcLpDFI?si=b7mYE5k_BzIu3X8_             | #Protesilaos# Introduction to denote |
| https://www.youtube.com/live/WbLPgn_L050?si=EuQ_GDMo6-T4koHm | #System crafters# Denote 3.0         |

Simplement deux colonnes, la première pour l'url et la seconde pour la description.
Et on ajoute même une première ligne avec le nom des colonnes.

En bash cela va correspondre à un hash (clef/valeur).
Le code sera un peu plus compliqué.
Il faut savoir que ~${!liste[@]}~ récupère les indices, ou clef (ici les urls).
Et que pour accéder au commentaire, ou la valeur, associé il faut utiliser ~@{liste[$indice]}~

Enfin comme on a mis un titre de colonne il faudra ajouter comme paramètre du bloc ~:colnames nil~ pour ne pas en tenir compte.

Et ensuite on retrouve les mêmes variables.
Le répertoire de destination avec le paramètre avant.
Je ne sais pas comment passer juste le chemin en variable dans un autre bloc.
#+NAME: destination
--paths home:/home/montfort/Perso/videos/

Et la commande à utiliser pour télécharger les vidéos.
#+NAME: commande
yt-dlp --no-warnings --no-progress --quiet --simulate

L'avantage de ~yt-dlp~ c'est qu'il ne télécharge pas à nouveau une vidéo déjà présente, ce qui nous épargne du code de vérification.

#+begin_src bash :results output :var liste=liste-videos-commentaire commande=commande destination=destination :session yt-dlp :async yes :colnames nil
  echo "On va télécharger les vidéos 📼"
  for url in ${!liste[@]}
  do
      echo "On télécharge : ${liste[$url]}"
      ${commande}${destination} ${url}
  done
#+end_src

#+RESULTS:
: On va télécharger les vidéos 📼
: On télécharge : #Protesilaos# Introduction to denote
: On télécharge : #System crafters# Denote 3.0

Je pensais pouvoir exporter (tangle) le bloc bash dans un fichier .sh mais autant en exécutant le bloc la variable liste est bien un hash ou dictionnaire, autant quand on exporte c’est une simple variable et le script ne fonctionne pas. En exportant le bloc et en éditant le fichier à la main on peut corriger le problème. En gros il suffit d’ajouter un declare -A liste en début de fichier et on remplace liste='ffff gggg' par liste=(ffff gggg) pour que le script fonctionne.

Pour faire correctement il faut préciser dans quel fichier on exporte avec :tangle mon_fichier.sh. Sinon le fichier aura le nom du fichier org et l’extension correspondant au langage du bloc (.sh ici). On ajoutera aussi une entrée pour le shebang : :shebang #!/usr/bin/env bash Si besoin on pourra ajouter vers le début du fichier (les blocs sont exportés dans l’ordre) un bloc qui exportera dans le même fichier et qui pourra initialiser des variables ou autre chose.

Au final le script simple avec une liste d’url est suffisant et peut être exporté correctement.