Indicateur de téléchargement youtube-dl

Le problème exposé dans ce sujet a été résolu.

Bonjour !

Je me suis fais un petit script pour télécharger des vidéos, avec une fenêtre de progression. Pour cela, j’utilise yad (Yet Another Dialog, un fork de Zenity, plus complet) et un script Python qui récupère les URLs des vidéos d’une playlist YouTube.

Voilà le script :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
for url in "$@"
do
  playlist=$($HOME/Softs/youParse.py $url)

  if [[ $playlist = "Incorrect Playlist." ]]
  then
    playlist="$url"
  fi

  compteur=0
  total=$(echo $playlist | wc -w)

  for item in $playlist
  do
    compteur=$(( $compteur + 1 ))
    text=$(youtube-dl -e $item)
    youtube-dl --newline $item |
      grep --line-buffered -oP '^\[download\].*?\K([0-9.]+\%)' |
      yad --progress \
      --title="Téléchargement" \
      --text="Téléchargement $compteur sur $total\n$text" \
      --percentage=0 --auto-kill --no-buttons --no-escape
  done
done

J’aimerais afficher une seconde barre de progression (avec --multi-progressde yad), même si à mon avis, en Bash, ça risque d’être difficile.

Cette seconde barre afficherait la progression totale (par rapport au nombre d’arguments passés), ou la progression de la playlist (ce qui est actuellement plus ou moins fait).

Pour cela, il faut que la sortie soit la suivante :

1
2
3
4
5
6
7
8
2:20%
1:1.0%
1:2.0%
1:…
1:100.0%
2:40%
1:1.0%
…

Il faut donc ajouter X: devant la progression de youtube-dl, et parser les changement de vidéo de youtube-dl ( [download] Downloading video 1 of 12, il me semble).

Je pense devoir faire un second script qui affichera ce qu’il faut sur la sortie standard, ou une fonction, mais je n’ai aucune idée de comment gérer, et si c’est possible.

Auriez-vous des idées ?

Breizh.

+0 -0

Bon, en fait, il faut forcément un script à part. Tout simplement parce que ce script ne fonctionne pas, je suis obligé de mettre --auto-close, sinon il faut fermer la fenêtre après chaque téléchargement, mais youtube-dl télécharge parfois deux fichier (l’audio et la vidéo) pour les fusionner ensuite, or --auto-close ferme à 100%, ce qui fait planter le script, puisque qu’une fois la vidéo à 100%, il se ferme, alors que l’audio n’a pas été téléchargé.

Edit : YAD et Youtube-DL étant disponibles en Python, je vais m’attaquer à un script Python, tout bien réfléchi. Ce sera probablement plus simple.

+0 -0

Et voilà, un code Python qui fonctionne. Il prends en paramètre n’importe quel URL supportée par Youtube-DL, il peut en prendre plusieurs. Les playlists YouTube sont gérées spécialement pour faire fonctionner la barre de progression nommée playlist. Ce script peut être amélioré de différentes façons, mais il me suffit, et je n’ai pas l’intention d’y toucher à nouveau, c’est juste à titre d’exemple.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
#!/usr/bin/python

from __future__ import unicode_literals
from yad import YAD
import youtube_dl
import sys
import re
import urllib.request
import urllib.error
import time
import os

# arguments : sys.argv = [ 'commande', 'arg1', … ]

if len(sys.argv) < 2:
    os.system('notify-send "Youtube-DL" "Veuillez entrer au moins une URL"')
    exit(1)

yad = YAD()
progress = yad.MultiProgress(bar=(("Fichier","NORM"),("Playlist","NORM"),("URL traitées","NORM")),autoclose=1)


def crawl(url):
    sTUBE = ''
    cPL = ''
    amp = 0
    final_url = []

    if 'list=' in url:
        eq = url.rfind('=') + 1
        cPL = url[eq:]

    else:
        return None # URL invalide

    try:
        yTUBE = urllib.request.urlopen(url).read()
        sTUBE = str(yTUBE)
    except urllib.error.URLError as e:
        print(e.reason)

    tmp_mat = re.compile(r'watch\?v=\S+?list=' + cPL)
    mat = re.findall(tmp_mat, sTUBE)

    if mat:

        for PL in mat:
            yPL = str(PL)
            if '&' in yPL:
                yPL_amp = yPL.index('&')
            final_url.append('http://www.youtube.com/' + yPL[:yPL_amp])

        all_url = list(set(final_url))

        return all_url

    else:
        return None # pas de vidéo

def hook(infos):
    if infos['status']=='downloading' and infos['total_bytes']!=None:
        perc=infos['downloaded_bytes']*100/infos['total_bytes']
        progress(perc,1,msg=infos['filename']+" ("+"{:.2f}%".format(perc)+" @ "+bytes_format(infos['speed'])+")")

def bytes_format(bytes):
    if bytes < 1024:
        return "{:.2f}B/s".format(bytes)
    elif bytes >= 1024:
        return "{:.2f}KiB/s".format(bytes/1024)
    elif bytes >= 1024**2:
        return "{:.2f}MiB/s".format(bytes/1024**2)
    else:
        return "{:.2f}GiB/s".format(bytes/1024**3)

total_index=0

ydl_opts = {
    'format':'bestvideo[height<=?1100]+bestaudio/best', # 1100 pour avoir du 1080p, y compris en cas d'erreur d'encodage
    'outtmpl':'%(title)s.%(ext)s',  # titre.extension
    'progress_hooks': [hook], # appelle la fonction de mise à jour de la première barre de progression
}

for url in sys.argv[1:]:

    playlist=crawl(url)
    print(playlist)

    if playlist==None:
        playlist=[sys.argv[total_index+1]]

    print(playlist)
    playlist_index=0
    progress(0,2)

    for video in playlist:
        print(video)
        progress(0,1)
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            ydl.download([video])

        playlist_index += 1
        progress(100,1)
        progress(playlist_index*100/len(playlist),2)

    total_index += 1
    progress(total_index*100/len(sys.argv[1:]),3)

exit(0)
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte