Contenu | Rechercher | Menus

Annonce

T-shirt Seiche Cosmic, Série limitée

L'équipe des administrateurs et modérateurs du forum vous invite à prendre connaissance des nouvelles règles.
En cas de besoin, vous pouvez intervenir dans cette discussion.

Ubuntu 18.10
T-shirt Ubuntu-FR « Seiche Cosmique » en série limitée ! Prix spécial pré-vente (15€) jusqu'au 4 novembre 2018.

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#301 Le 13/06/2013, à 21:39

bibichouchou

Re : TVDownloader: télécharger les médias du net ! [2]

Salut,
A Nai2Lille

la ligne de commande pour la vidéo que tu veux est obtenue avec le script watdl.py, débuté par k3c et "entretenu" par k3c, pacome et moi-même (mais c'est surtout pacome en ce moment, merci à lui wink). regarde le message 288 pour avoir la dernière version du-dit script. copie + colle dans un fichier que tu nommes watdl.py. puis tu télécharges en tapant :

python watdl.py http://adresse_video_de_tf1_ou_tmc_ou_hd1_ou_nt1

ou alors tu peux aussi rendre le script exécutable avec

chmod u+x watdl.py

et après il suffit de faire

./watdl.py http://adresse_video_de_tf1_ou_tmc_ou_hd1_ou_nt1

Pour connaître les protocoles utilisés par tel ou tel site, il faut se tenir informé ici par exemple. En effet, les chaînes mettent à jour régulièrement leur site de rattrapage et éventuellement, changent les protocoles. exemple m6/6ter/w9 utilisait du rtmp et maintenant du Adobe HDS + verrous numériques (ce qui rend toute récupération impossible).
Voilà !
A+

Dernière modification par bibichouchou (Le 13/06/2013, à 21:41)

Hors ligne

#302 Le 13/06/2013, à 22:01

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

Salut tout le monde!

@thom83 & k3c:
Je n'ai pas eu de 403 (avec ou sans -s sur cette url). J'essayerai quand même de rajouter un try: except: pour sortir proprement mais n'hésitez pas à fournir des détails si vous en avez.

@Nai2Lille:
Tu peux récupérer la ligne de commande rtmpdump en lançant le script avec l'option -V:

./watdl.py -s -V  http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html
INFO:	21:37:48: verbose mode
INFO:	21:37:48: url: ['http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html']
INFO:	21:37:51: rtmpdump --resume --rtmp "rtmpe://wske.wat.tv/ondemand/mp4:vod/H264-384x288/40/41/10584041.h264" --port 443 --timeout 10 --swfVfy http://www.wat.tv/images/v40/PlayerWat.swf -o "episode-10-saison-09-bar-clandestin-8000620-10584041.mp4"

(ici à 21:37:51)
Pour l'utiliser (au cas où...) il faut:

  1. copier le code du script (sélection à la souris)

  2. ouvrir un éditeur de texte (gedit par exemple)

  3. coller le code copié

  4. enregistrer (dans watdl.py par exemple)

  5. rendre le fichier exécutable (optionnel, mais plus pratique)

    chmod u+x watdl.py

Et voilà! wink

Pour les différents scripts à utiliser en fonction des sites de replay, il faut rechercher dans ce fil: je m'étais dit que ce serait cool de tous les rassembler en un seul, mais pour le moment ça reste un projet... big_smile

À+

Édit:
@bibichouchou: Grilled! lol
j'ai donc mis au moins 20min pour rédiger mon post!
Édit 2: et en plus je fais des fautes!! roll

Dernière modification par pacome (Le 13/06/2013, à 22:24)

Hors ligne

#303 Le 13/06/2013, à 22:13

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

@ pacome

Voici les erreurs (qu'il n'y a plus maintenant)

gg@gg-SATELLITE-L755:~$ python watdl.py http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html
Traceback (most recent call last):
  File "watdl.py", line 379, in <module>
    main()
  File "watdl.py", line 376, in main
    args.swfComputeHashSize)
  File "watdl.py", line 249, in downloadWatVideo
    data = urllib2.urlopen(req).read()
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 406, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 519, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 444, in error
    return self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 527, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: No proxy for this secured delivery.

Archlinux sur Xiaomi Air 13

Hors ligne

#304 Le 13/06/2013, à 22:23

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

@k3c:
Nickel, merci!
J'essayerai de récupérer sur cette erreur, ou au moins de sortir proprement.

À bientôt.

Hors ligne

#305 Le 14/06/2013, à 01:57

11gjm

Re : TVDownloader: télécharger les médias du net ! [2]

Re-... ,

@k3c :
> php est connu par contre
Pas vrai ( sous windows ) ; il m'a fallu le rentrer dans les variables d'environnement .

@Nai2Lille :
> Autre question, comment obtiens-tu le lien à utiliser pour rtmpe ?
Il faut jongler entre plusieurs programmes : streamstransport , etc.

> Aussi, comment sais-tu que tel ou tel site de replay utilise telle ou telle manière de diffusion ?
Faut tâtonner . C'est long et fastitdieux et cela change n'importe quand .
Mais , watdl.py nous facilite le travail pour certaines chaines . Par exemple .

@Pacome :
Dans ma réponse #289 , je parle de : http.../swfpu/250250nIc0K1110584041
On obtient des tas d'infos .

Merci aux programmeurs !!!
Cordialement .

Dernière modification par 11gjm (Le 14/06/2013, à 02:06)

Hors ligne

#306 Le 14/06/2013, à 08:54

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

@ 11gjm

Désolé  pour php, je disais cela pour la minorité de personnes qui fréquentent les forums de ubuntu-fr.org ET sont sous Linux

O:-)


Archlinux sur Xiaomi Air 13

Hors ligne

#307 Le 14/06/2013, à 10:51

thom83

Re : TVDownloader: télécharger les médias du net ! [2]

k3c a écrit :

la minorité de personnes qui fréquentent les forums de ubuntu-fr.org ET sont sous Linux

Je ferais donc partie d'une minorité ? wink

Hors ligne

#308 Le 14/06/2013, à 12:24

11gjm

Re : TVDownloader: télécharger les médias du net ! [2]

Bonjour ,

@thom83 : k3c plaisante , c'est l'inverse qu'il faut comprendre !!!

A+ .

Hors ligne

#309 Le 16/06/2013, à 01:05

abecidofugy

Re : TVDownloader: télécharger les médias du net ! [2]

Salut,

Pour raring y'a un dépôt ?
deb http://ppa.launchpad.net/chaoswizard/tv … der/ubuntu raring main : ne marche pas
Et videodownload helper ne marche pas sur Pluzz.fr avec mon Firefox !

Merci.


Kubuntu et Neon 18.04 LTS en VM dans host Windows 8.1 (24 Go de ram) / Kubuntu en double-boot avec Win10 / Ubuntu 14.04 et 16.04 serveur sur machines dédiées.
Agence de communication en AlsaceKDE neon

Hors ligne

#310 Le 16/06/2013, à 09:19

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

@ abecidofugy

Si tu veux télécharger des vidéos de pluzz, tvdownloader ne marchera pas.

Il te faut utiliser soit
pluzzdl
soit
AdobeHDS.php

Pacome a fait un superbe post explicatif dans cette discussion récemment.


Archlinux sur Xiaomi Air 13

Hors ligne

#311 Le 16/06/2013, à 10:31

bibichouchou

Re : TVDownloader: télécharger les médias du net ! [2]

salut à tous,

bon, trouver son bonheur sur ce fil gigantesque est un problème récurrent. il s'avère, par un concours de circonstance, que je suis l'auteur du premier message. donc je veux bien mettre des liens vers les messages les plus importants sous la forme d'un sommaire par exemple, le lien vers la dernière version de tel ou tel script le lien vers tel ou tel tuto. ou alors faudrait faire une page de doc mais là je ne sais pas faire. bon, c'est une idée comme une autre...

bon dimanche à vous !

Hors ligne

#312 Le 16/06/2013, à 23:08

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

Bonsoir,

@bibichouchou:
C'est vrai qu'une table de liens serait bien pratique (pour info le lien direct vers un post est disponible sous la date du post: clic-droit→copier l'adresse du lien et hop!); amha une page de doc serait toute indiquée: je n'en ai pas encore fait non plus, mais il y déjà le bac-à-sable big_smile.
Dans le même ordre d'idée, que pensez-vous de créer un dépôt git (par exemple) pour gérer les versions des scripts? Ça serait bien pratique pour les retrouver et s'y retrouver, non? (j'avoue que je commence à avoir pas mal de versions dans mes répertoires et que j'aimerais savoir me servir de git... tongue)

En ce qui concerne watdl.py, voici une version 0.9.4.7 (v0.9.4.6) qui intègre les modifications suivantes:

  • boucle de reprise pour les téléchargements par curl (depuis l'temps!)

  • effacement du fichier temporaire créé par ffmpeg en cas d'échec de la conversion (inutile et ça prend de la place)

  • effacement préalable du fichier source (flv) avant renommage du fichier temporaire (mp4) quand la conversion a réussi (ça devrait éviter la WindowsError rencontrée par 11gjm)

  • ajout d'un timeout (de 30s) pour les urlopen

  • modification de la liste des User-Agents (versions récentes de firefox)

  • nouveau player swf trouvé dans LoaderExportV3.swf

  • nom du fichier de log (sans le .py)

  • ajout/modif de log

  • modification du port pour rtmpdump (443→1935)

J'ai fini par reproduire (mais pas systématiquement) le problème du 403 rencontré par thom83 et k3c , en demandant la version HD. Pour gérer cela le script affiche des messages proposant d'utiliser l'option --standard-definition si il est appelé sans et rencontre une 403, ou si la conversion ffmpeg échoue; j'ai du aussi ajouter la suppression du fichier vidéo invalide lors de la reprise.

#!/usr/bin/python
#-*- coding:utf-8 -*-
# TF1 TMC NT1 HD1 V0.9.4.7 par k3c, bibichouchou et pacome

# args & log
import argparse
from time import localtime, strftime
import logging

import subprocess, re, sys, shlex
import socket
import urllib2                  # → urlopen & exceptions
import hashlib                  # → sha256sum
import hmac
import zlib
import StringIO
import time, md5, random, urllib2, json
import bs4 as BeautifulSoup
import os                       # → os.rename
from urlparse import urlparse

# global var
scriptName='watdl.py'
scriptVersion='0.9.4.7'

# programmes externes utilisés
ffmpegEx='ffmpeg'               # ou avconv
rtmpdumpEx='rtmpdump'
curlEx='curl'

# Player swf
#defaultSwfPlayerUrl='http://www.wat.tv/images/v40/PlayerWat.swf'
defaultSwfPlayerUrl='http://www.wat.tv/images/v60/PlayerWat.swf'
KEY = "Genuine Adobe Flash Player 001"

urlOpenTimeout = 30

listeUserAgents = [
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0',
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0',
    'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:23.0) Gecko/20131011 Firefox/23.0',
    'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20130331 Firefox/21.0',
    'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.',
    'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312',
    'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.940.0 Safari/535.8',
    'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.107 Safari/535.1',
    'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1',
    'Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) midori',
    'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; fr-fr) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11' ]

WEBROOTWAT="http://www.wat.tv"
wat_url="/web/"
jsonVideosInfos=""

# random user agent
ua=random.choice(listeUserAgents)

# global logger
log=logging.getLogger(__name__)

def checkExternalProgram(prog, optArg='', expectedValue=''):
    """ Permet de vérifier la présence des programmes externes requis """
    log.debug('→checkExternalProgram(%s, %s, %s)'%(prog, optArg, expectedValue))
    args=shlex.split('%s %s' % (prog, optArg))
    try:
        process=subprocess.Popen(args,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT)
        stdout, stderr = process.communicate()
        if expectedValue == '':
            return True
        else:
            if expectedValue in stdout: # à améliorer pour versions > ...
                return True
            else:
                return False
    except OSError:
        log.error('Le programme %s n\'est pas présent sur votre système' % (prog))
        return False

def get_soup(url, referer, ua):
    """ on récupère la soupe """
    req  = urllib2.Request(url)
    req.add_header('User-Agent', ua)
    req.add_header('Referer', referer)
    soup = urllib2.urlopen(req, None, urlOpenTimeout).read()
    log.debug('←get_soup(%s, %s, %s): %s' % (url, referer, ua, soup))
    return soup

def get_wat(id, HDFlag):
    """la fonction qui permet de retrouver une video sur wat"""
    def base36encode(number):
        if not isinstance(number, (int, long)):
            raise TypeError('number must be an integer')
        if number < 0:
            raise ValueError('number must be positive')
        alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
        base36 = ''
        while number:
            number, i = divmod(number, 36)
            base36 = alphabet[i] + base36
        return base36 or alphabet[0]
    if HDFlag:
        wat_url = "/webhd/"
    else:
        wat_url = "/web/"
    ts = base36encode(int(time.time())-60)
    timesec = hex(int(ts, 36))[2:]
    while(len(timesec)<8):
        timesec = "0"+timesec
    token = md5.new(
        "9b673b13fa4682ed14c3cfa5af5310274b514c4133e9b3a81e6e3aba00912564" +
        wat_url + str(id) + "" + timesec).hexdigest()
    id_url1 = (WEBROOTWAT + "/get" + wat_url + str(id) + "?token=" + token +
    "/" + str(timesec) + "&country=FR&getURL=1")
    log.debug('←get_wat(%s, %s): %s' %(id, HDFlag, id_url1))
    return id_url1

def swfPlayerHashAndSize(swfPlayerUrl):
    """
    Calcule et renvoie le tuple (hash, taille) du player swf
    ← (swfHash, swfSize)
    """
    global KEY
    try:
        swfPlayer= urllib2.urlopen(swfPlayerUrl, None, urlOpenTimeout).read()
    except (ValueError, urllib2.URLError):
        log.error('→swfPlayerHashAndSize(%s): Url invalide!' % (swfPlayerUrl))
        raise
    except urllib2.HTTPError:
        log.error('→swfPlayerHashAndSize(%s): Pb http!' % (swfPlayerUrl))
        raise

    swfPlayerHash=hashlib.sha256(swfPlayer).hexdigest()
    if type(swfPlayer) is str:
        swfData=StringIO.StringIO(swfPlayer)
    swfData.seek(0, 0)
    magic=swfData.read(3)
    if magic != "CWS":
        log.error("Pas de CWS...")
        raise ValueError('NoCWS')
    else:
        unzPlayer="FWS" + swfData.read(5) + zlib.decompress(swfData.read())
        unzPlayerSize=len(unzPlayer)
        unzPlayerHash = hmac.new(KEY, unzPlayer, hashlib.sha256).hexdigest()
    log.debug('←computeSwfPlayerHash(%s):(%s, %s)' %(
            swfPlayerUrl, unzPlayerHash, unzPlayerSize))
    return (unzPlayerHash, unzPlayerSize)

def rtmpDownload(rtmpUrl,
                 swfPlayerUrl,
                 swfForceRefresh,
                 swfComputeHashSize,
                 fileName,
                 swfHash=None,
                 swfSize=None):
    """ Appel de rtmpdump avec traitement des options et reprise (récursif)
    """
    log.debug('→rtmpDownload(%s, %s, %s, %s, %s, %s, %s)' % (
            rtmpUrl, swfPlayerUrl, swfForceRefresh, swfComputeHashSize,
            fileName, swfHash, swfSize))
    rtmpCmd = '%s --resume --rtmp "%s" --port 1935 --timeout 10' % (
        rtmpdumpEx, rtmpUrl)    # initialisation de la commande

    if swfComputeHashSize:
        if not swfHash and not swfSize: # pour ne pas recalculer en récursion
            try:
                (swfHash, swfSize)=swfPlayerHashAndSize(swfPlayerUrl)
            except:
                log.warning('Impossible de calculer le hash/size du player swf!')
                log.info('calcul du hash/size par %s' % (rtmpdumpEx))
                return rtmpDownload(rtmpUrl, swfPlayerUrl, swfForceRefresh,
                                    False, fileName)
            if swfForceRefresh:
                log.warning('pas encore codé!')
                # et je ne sais pas si ça le sera... ;)
            rtmpCmd += ' --swfhash %s --swfsize %i' % (swfHash, swfSize)
    else:
        if swfForceRefresh:
            rtmpCmd += ' --swfVfy %s --swfAge 0' % (swfPlayerUrl)
        else:
            rtmpCmd += ' --swfVfy %s' % (swfPlayerUrl)
    rtmpCmd += ' -o "%s"' % (fileName)
    log.info(rtmpCmd)
    rtmpCall = shlex.split(rtmpCmd)
    rtmpProc = subprocess.Popen(rtmpCall,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)
    (stdout, stderr) = rtmpProc.communicate()
    if rtmpProc.returncode == 1:   # sortie en erreur →
        log.debug('rtmpdump output: %s' % (stdout))
        if 'corrupt file!' in stdout: # ERROR: Last tag...corrupt file!
            log.warning('Le fichier %s est corrompu!\n\t le téléchargement doit reprendre du début...' % (fileName))
            os.remove(fileName)
            return rtmpDownload(rtmpUrl, swfPlayerUrl, swfForceRefresh,
                                swfComputeHashSize, fileName, swfHash, swfSize)
        else:                      # ERROR: RTMP_ReadPacket...?
            if swfComputeHashSize: # on ré-essaye avec le calcul par rtmpdump
                return rtmpDownload(rtmpUrl, swfPlayerUrl, swfForceRefresh,
                                    False, fileName)
            elif not swfForceRefresh: # on ré-essaye en forçant le recalcul
                return rtmpDownload(rtmpUrl, swfPlayerUrl, True,
                                    False, fileName)
            else:               # rtmpdump computation & refresh KO →
                log.warning ('Veuillez ré-essayer plus tard...')
    elif rtmpProc.returncode == 2:   # téléchargement incomplet →
        log.info('Téléchargement incomplet: nouvel essai dans 3s...')
        time.sleep(3)                # petite temporisation
        if swfComputeHashSize:       # pas la peine de les recalculer
            return rtmpDownload(rtmpUrl, swfPlayerUrl, swfForceRefresh,
                                swfComputeHashSize, fileName, swfHash, swfSize)
        elif swfForceRefresh:   # pas la peine de le refaire
            return rtmpDownload(rtmpUrl, swfPlayerUrl, False,
                                swfComputeHashSize , fileName)
        else:                   # on rappelle avec les mêmes options
            return rtmpDownload(rtmpUrl, swfPlayerUrl, swfForceRefresh,
                                swfComputeHashSize, fileName, swfHash, swfSize)
    else:
        return rtmpProc.returncode # = 0

def downloadWatVideo(videoUrl,
                     swfPlayerUrl,
                     swfForceRefresh,
                     swfComputeHashSize,
                     standardDefinition):
    """ recuperation de vidéos sur TF1/TMC/NT1/HD1 (donc WAT)"""
    log.debug('→downloadWatVideo(%s, %s, %s, %s, %s)' % (
            videoUrl, swfPlayerUrl, swfForceRefresh, swfComputeHashSize, standardDefinition))
    # timeout en secondes
    socket.setdefaulttimeout(90)
    debut_id = ''
    html = urllib2.urlopen(videoUrl, None, urlOpenTimeout).read()
    # log.debug('html=%s' %(html))
    nom = videoUrl.split('/')[-1:][0]
    no = nom.split('.')[-2:][0]
    soup = BeautifulSoup.BeautifulSoup(html)
    log.debug('soup=%s' %(soup))
    site = urlparse(videoUrl).netloc
    if 'tmc.tv' in site or 'tf1.fr' in site:
        debut_id = str(soup.find('div', attrs={'class' : 'unique' }))
    if 'nt1.tv' in site or 'hd1.tv' in site:
        debut_id = str(soup.find('section', attrs={'class' : 'player-unique' }))
    id = [x.strip() for x in re.findall("mediaId :([^,]*)", debut_id)][0]
    referer = [x.strip() for x in re.findall('url : "(.*?)"', debut_id)][0]
    jsonVideoInfos = get_soup(WEBROOTWAT+'/interface/contentv3/'+id, referer, ua)
    videoInfos = json.loads(jsonVideoInfos)
    log.debug('videoInfos=%s' % (videoInfos))
    if not standardDefinition:
        try:
            HD = videoInfos["media"]["files"][0]["hasHD"]
        except:
            HD = False
    else:
        HD = False

    NumberOfParts = len(videoInfos["media"]["files"])
    ListOfIds = []
    for iPart in range(NumberOfParts):
        ListOfIds.append(videoInfos["media"]["files"][iPart]["id"])
    log.debug('NumberOfParts=%s' % (NumberOfParts))
    for PartId in ListOfIds:
        id_url1 = get_wat(PartId, HD)
        req = urllib2.Request(id_url1)
        req.add_header('User-Agent', ua)
        req.add_header('Referer', referer)
        try:
            log.debug('User-Agent: %s' % (ua))
            log.debug('Referer: %s' % (referer))
            resp = urllib2.urlopen(req, None, urlOpenTimeout)
            data = resp.read()
        except urllib2.HTTPError, error:
            if not standardDefinition:
                log.error('Impossible de récupérer la vidéo en HD. Veuillez ré-essayer avec l\'option --standard-definition')
            else:
                log.error('HTTP error avec User-Agent: %s\tReferer: %s' % (ua, referer))
                
            data = error.read()
        log.debug('data=%s' % (data))
        if data[0:4] == 'http':
            if not checkExternalProgram(curlEx):
                log.warning('Ce script requiert %s' % (curlEx))
            else:
                curlCmd = '%s "%s" -C - -L -g -A "%s" -o "%s.mp4"' % (
                    curlEx, data, ua, no + "-" + str(PartId))
                log.info(curlCmd)
                isDownloaded = False
                while not isDownloaded:
                    curlProc = subprocess.Popen(curlCmd,
                                                stdout=subprocess.PIPE,
                                                shell=True)
                    (stdout, stderr) = curlProc.communicate()
                    if curlProc.returncode == 0:
                        isDownloaded = True
                    else:
                        log.debug('curl output:%s' % (stdout))
                        if 'Cannot resume' in stdout:
                            log.warning('Le fichier obtenu est complet ou corrompu')
                            isDownloaded = True # pour sortir quand même...

        if data[0:4] == 'rtmp':
            # vérification de la présence de rtmpdump v2.4 ou v2.5
            if not (checkExternalProgram(rtmpdumpEx, '-help', 'v2.4') or 
                    checkExternalProgram(rtmpdumpEx, '-help', 'v2.5')): # pas top
                log.warning('Ce script requiert %s v2.4 ou v2.5' % (rtmpdumpEx))
            else:
                if '.hd' in data:
                    rtmpUrl = re.search('rtmpte://(.*)hd', data).group(0)
                if '.h264' in data:
                    rtmpUrl = re.search('rtmpte://(.*)h264', data).group(0)
                # log.debug('rtmpUrl=%s'%(rtmpUrl))
                rtmpUrl = rtmpUrl.replace('rtmpte','rtmpe')
                fName=str(no) + '-' + str(PartId) # nom du fichier sans extension
                fileName=fName+'.mp4'             # nom du fichier avec extension
                if rtmpDownload(rtmpUrl, swfPlayerUrl, swfForceRefresh,
                                swfComputeHashSize, fileName) == 0:
                    log.info('Téléchargement terminé')
                    # ffmpeg est-il disponible?
                    if not checkExternalProgram(ffmpegEx):
                        log.info("L'installation de ffmpeg sur votre système permettrait de corriger automatiquement le conteneur de la vidéo (flash→mp4).")
                    else:
                        log.info('conversion ffmpeg fileName → tmpFileName (pour corriger le conteneur)')
                        tmpFileName = fName+'.tmp.mp4'
                        ffmpegCmd = '%s -i "%s" -acodec copy -vcodec copy "%s"' % (ffmpegEx, fileName, tmpFileName)
                        ffmpegCall = shlex.split(ffmpegCmd)
                        ffmpegProc = subprocess.Popen(ffmpegCall,
                                                      stdout=subprocess.PIPE,
                                                      stderr=subprocess.STDOUT)
                        (stdout, stderr) = ffmpegProc.communicate()
                        if ffmpegProc.returncode != 0:
                            log.error('La conversion ffmpeg s\'est terminée en erreur.\nLe fichier %s est vraisemblablement illisible...' % (fileName))
                            if not standardDefinition:
                                log.error('Veuillez ré-essayer avec l\'option --standard-definition')
                            try:
                                os.remove(tmpFileName) # à effacer si il existe
                            except:
                                pass
                        else:
                            log.debug('remplacement %s → %s' % (
                                    tmpFileName, fileName))
                            os.remove(fileName) # pour éviter les WindowsError
                            os.rename(tmpFileName, fileName)
                        log.info('%s est maintenant disponible!' % (fileName))
                else:
                    log.info('Problème réseau ou algo?')

def main():
    """
    Analyse les arguments et lance le téléchargement
    """
    parser=argparse.ArgumentParser(prog=scriptName,
                                   description='Récuperation de vidéos sur TF1/TMC/NT1/HD1 (donc WAT).',
                                   version='%s v%s' % (scriptName,
                                                       scriptVersion))
    verbOrLog=parser.add_mutually_exclusive_group()
    verbOrLog.add_argument('-V', '--verbose',
                           help="affiche des messages",
                           dest='verbose',
                           action='store_true',
                           default=False)
    verbOrLog.add_argument('-l', '--log',
                           help="logue les messages",
                           dest='log',
                           action='store_const',
                           const='%s-%s.log' % (re.sub('\.py', '', scriptName),
                                                strftime("%Y%m%d%H%M%S",
                                                         localtime())),
                           metavar='FILE')
    parser.add_argument('-p', '--swf-player-url',
                        help='url du player swf à utiliser (défaut= %s)' % (defaultSwfPlayerUrl),
                        dest='swfPlayerUrl',
                        default=defaultSwfPlayerUrl,
                        action='store',
                        metavar='URL')
    parser.add_argument('-f', '--swf-force-refresh',
                        help='force la vérification du hash/size du player swf (met éventuellement à jour ~/.swfinfo)',
                        dest='swfForceRefresh',
                        default=False,
                        action='store_true')
    parser.add_argument('-c', '--swf-compute-hash-size',
                        help='calcul du hash/size par le script',
                        dest='swfComputeHashSize',
                        default=False,
                        action='store_true')
    parser.add_argument('-s', '--standard-definition',
                        help='ne recherche pas de version Haute-Définition',
                        dest='standardDefinition',
                        default=False,
                        action='store_true')
    parser.add_argument('url',
                        help='url de la page de la video',
                        metavar='URL',
                        nargs='+')
    args=parser.parse_args()

    if args.verbose:
        logging.basicConfig(format='%(levelname)s:\t%(asctime)s: %(message)s',
                            datefmt='%H:%M:%S',
                            level=logging.INFO)
    else:
        if args.log:
            logging.basicConfig(filename=args.log,
                                format='%(levelname)s:\t%(asctime)s: %(message)s',
                                datefmt='%H:%M:%S',
                                level=logging.DEBUG)
        else:
            logging.basicConfig(format='%(message)s',
                                datefmt='%H:%M:%S',
                                level=logging.WARNING)
    if args.url:
        for url in args.url:
            log.info('Traitement de l\'url: %s' % (url))
            downloadWatVideo(url,
                             args.swfPlayerUrl,
                             args.swfForceRefresh,
                             args.swfComputeHashSize,
                             args.standardDefinition)

if __name__ == "__main__":
    main()

À+

Édit: modif port

Dernière modification par pacome (Le 18/06/2013, à 12:27)

Hors ligne

#313 Le 17/06/2013, à 12:06

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

@ pacome

merci pour ton script

Oui ça il faudrait poser tous ces scripts sur un github, sourceforge, tuxfamily  ou autre site quelconque

Éviter googlecode  de préférence

Je pourrai y mettre tous mes scripts
Tv5monde
nrj12
cherie25
et draft  pour toutv
..
fourniture d'un proxy GB pour get_iplayer


Archlinux sur Xiaomi Air 13

Hors ligne

#314 Le 17/06/2013, à 13:23

11gjm

Re : TVDownloader: télécharger les médias du net ! [2]

Bonjour ,

@Pacome : Déroulement et résultat , avec "watdl_0947.py" .

".\python.exe" "watdl_0947.py" -V -s "http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html"
INFO:   13:05:00: Traitement de l'url: http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html
INFO:   13:05:01: rtmpdump --resume --rtmp "rtmpe://wske.wat.tv/ondemand/mp4:vod/H264-384x288/40/41/10584041.h264" --port 1935 --timeout 10 --swfVfy http://www.wat.tv/images/v60/PlayerWat.swf -o "episode-10-saison-09-bar-clandestin-8000620-10584041.mp4"
INFO:   13:13:17: T├®l├®chargement termin├®
INFO:   13:13:17: conversion ffmpeg fileName  tmpFileName (pour corriger le conteneur)
INFO:   13:13:20: episode-10-saison-09-bar-clandestin-8000620-10584041.mp4 est maintenant disponible!
...

_ Durée du téléchargement très RAPIDE !!!
_ Vidéo excellente .

Merci .

Cordialement .

Hors ligne

#315 Le 17/06/2013, à 19:06

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

Salut,

@k3c:
J'ai commencé à bricoler avec git en local; s'il n'y a pas d'objection je vais m'intéresser de plus près à github wink

@11gjm:
À priori tu as obtenu un fichier de 116Mo en SD; je pense que c'est pour ça que le tu as trouvé le téléchargement rapide, mais le changement de port (oubli dans le changelog) et de player sont peut-être en cause...

[hs]chez vous aussi les smileys sont devenus bleus?[/hs]

À+

Hors ligne

#316 Le 17/06/2013, à 19:32

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

pacome a écrit :

Salut,

@k3c:
J'ai commencé à bricoler avec git en local; s'il n'y a pas d'objection je vais m'intéresser de plus près à github wink

@11gjm:
À priori tu as obtenu un fichier de 116Mo en SD; je pense que c'est pour ça que le tu as trouvé le téléchargement rapide, mais le changement de port (oubli dans le changelog) et de player sont peut-être en cause...

[hs]chez vous aussi les smileys sont devenus bleus?[/hs]

À+

Je suis plus Mercurial que git, mais pour ce que je ferai (git clone, git push, git pull...), ça ira très bien, et en plus ça me fera utiliser git.
Parfait.


Archlinux sur Xiaomi Air 13

Hors ligne

#317 Le 17/06/2013, à 22:39

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

Hello,

J'ai initialisé un dépôt github: https://github.com/pacomod/replaydl.git

Pour le moment il ne contient que mes essais sur getSwfInfo.py, mais je vais m'occuper de watdl.py.

À+

Hors ligne

#318 Le 17/06/2013, à 22:51

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

@ pacome

Si tu veux y mettre ce script qui marche pour cherie25 et nrj12

exemple (je l'ai arrêté)

 python nrj/plugin.video.NRJ12Replay/cherie_1.py http://www.cherie25.fr/replay-4272/media/video/700071-mort-sur-ordonnance.html
le findAll 
msdl -c --no-proxy http://r.nrj.fr/mogador/web/00113348_h264_cherie.mp4 -s 5 -o "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4"
['msdl', '-c', '--no-proxy', 'http://r.nrj.fr/mogador/web/00113348_h264_cherie.mp4', '-s', '5', '-o', 'THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4']
download [ THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4 ]
Host: [ 95.81.165.1:80 ]    connected!
get_filesize THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4: stat() error
No such file or directory
http resume: no such file "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4", not resuming
redirect to http://95.81.146.19/1Ub-sygEJp7iHcPtaj8ugNsCdeTQb4z9bbCQ=/mogador/web/00113348_h264_cherie.mp4
Host: [ 95.81.146.19:80 ]    connected!
get_filesize THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4: stat() error
No such file or directory
http resume: no such file "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4", not resuming
DL: 15678757/363838176 B --   4%                       1.9M/s     ETA 03:37    ^CTraceback (most recent call last):
# -*- coding: utf-8 -*-
# os and lib modules
# cherie25 et nrj  v 0.3 k3c
import subprocess
import sys 
import urllib2
import shlex
from urlparse import urlparse
# pyamf
from pyamf.remoting.client import RemotingService
# parseDOM
import bs4 as BeautifulSoup
import unicodedata
import string

__addonID__      = "plugin.video.NRJ12Replay"
__author__       = "k3c,JUL1EN094 ,vilain_mamuth"
__date__         = "05-04-2013"
__version__      = "0.3"
__credits__      = "Merci aux auteurs des autres addons replay du dépôt Passion-XBMC et de la communauté open-source"  

# Web variable
#WEBROOT = "http://www.nrj12.fr"
#WEBSITE = WEBROOT + "/replay-4203/collectionvideo/"        
INFOSITE = "http://prod-kernnrj12v5.integra.fr/videoinfo"        
validFilenameChars = "-_.() %s%s" % (string.ascii_letters, string.digits)

def removeDisallowedFilenameChars(filename):
    "Remove invalid filename characters" 
    filename = filename.decode('ASCII', 'ignore')
    cleanedFilename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore')
    cleanedFilename = cleanedFilename.replace(' ', '_')
    return ''.join(c for c in cleanedFilename if c in validFilenameChars)              

def get_soup(url):
    "analyse de la page par BeautifulSoup"
    req = urllib2.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 5.1; rv:15.0) Gecko/20100101 Firefox/15.0.1')           
    sou = urllib2.urlopen(req).read()
    soup = BeautifulSoup.BeautifulSoup(sou)
    print "le findAll "
    zz = urlparse(sys.argv[1])
    mediaiId = ''
    try: 
        if 'cherie25' in zz.netloc:
            mediaId = soup.findAll('div', attrs={"class":u"page_video"})[0]('img')[0]['id'] 
        elif 'nrj' in zz.netloc:
            mediaId = soup.findAll('div', attrs={"class":u"img-une"})[0]('img')[0]['id']
        else:
            print "cette video ne vient ni de nrj12 ni de cherie25"
            sys.exit()
# on enlève mediaId_
        mediaId = mediaId[8:]
#    print mediaId
    except:
        print 'impossible de trouver l\'id de la  video'
        sys.exit()
    return mediaId

def get_url(url, mediaId):
    "appel à pyamf pour l'adresse de la vidéo"
    client = RemotingService(url)
    vi = client.getService('Nrj_VideoInfos')
    mi = vi.mediaInfo(mediaId)
    url_episode = mi["url"]
    titre = mi["title"].replace(' ','_') 
    return url_episode, titre 
                                       
#######################################################################################################################    
# BEGIN !
#######################################################################################################################
def main():
    "main function"
    mediaId = get_soup(sys.argv[1])
    url_episode, titre = get_url(INFOSITE, mediaId)
    cmds = 'msdl -c --no-proxy %s -s 5 -o \"%s_%s.mp4\"' % (url_episode, titre, mediaId)
    print cmds
    arguments = shlex.split( cmds )
    print arguments
    subprocess.Popen( arguments, stdout = subprocess.PIPE).communicate()[0]
#    stdout, stderr = p.communicate()
#    if p.returncode != 0:
#        print "Erreur : le sous-process s\'est terminé avec (le code d\'erreur est " + str(p.returncode) + ")"

if __name__ == '__main__':
    main()

Archlinux sur Xiaomi Air 13

Hors ligne

#319 Le 17/06/2013, à 23:19

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

Hé hé...

Je l'avais déjà mis de coté, et j'avais bien l'intention de l'ajouter. wink

Le seul bémol c'est que je ne l'ai jamais fait fonctionner car je n'ai pas msdl:

$ msdl
No command 'msdl' found, did you mean:
 Command 'wsdl' from package 'mono-devel' (main)
msdl: command not found

S'agit-il bien de msdl?

[hs]Sérieusement, il n'y a que moi qui vois des smileys couleur schtroumpf?[/hs]

Dernière modification par pacome (Le 17/06/2013, à 23:20)

Hors ligne

#320 Le 17/06/2013, à 23:27

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

@pacome

tu peux utiliser curl à la place de msdl, sinon

gg@gg-SATELLITE-L755:~$ which msdl
/usr/bin/msdl
gg@gg-SATELLITE-L755:~$ msdl --help
msdl 1.2.7-r2 : Media Stream DownLoader
Usage: msdl [options] targets
  -o, --output <localfile>    specify output file name. '-o -': stdout.
  -l, --logfile <logfile>     print log to logfile instead of console.
  -v, --verbose               show verbose messages.
  -V, --version               show version information.
  -q, --quiet                 do quietly. no output.
  -c, --continue <url>        continue (resume) downloading.
  -a, --auto-retry <num>      auto-retry aborted download. (num times).
  -b, --bandwidth <bandwidth> set bandwidth.
  -s, --speed <speed>         set streaming speed.
  -r, --range <range>         set range (for RTSP), default "0.000-".
  -m, --metafile <url>        treat url as metafile.
  -n, --no-metafile <url>     DO NOT treat url as metafile.
  -h, --help                  display this help.
  -p, --protocol <protocol>   specify download protocol.
      --byterange <range>     set byte range (for http and ftp).
      --username <username>   user name for basic authentication.
      --password <password>   password for basic authentication.
      --no-proxy              DO NOT use proxy, even if HTTP_PROXY set.
      --no-passive-ftp        DO NOT use passive mode in FTP.
      --stream-timeout <time> Quit Streaming after time.
      --debug                 show debug message (super verbose).
Supported protocols: mms(mmst) mmsh rtsp http ftp
To use proxy for mms, mmsh, and http, set HTTP_PROXY variable.
"-s" and "-r" are for *-rtsp, and these options may be ignored.
If you find any bugs, please report to <me_t_ro@yahoo.com>.
gg@gg-SATELLITE-L755:~$ 

Edit, oui je suis moi aussi devenu daltonien :-)

Dernière modification par k3c (Le 17/06/2013, à 23:29)


Archlinux sur Xiaomi Air 13

Hors ligne

#321 Le 17/06/2013, à 23:54

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

C'est cool!
Du coup je viens de tester les branches de git (j'en avais créé une pour charger les modifs de tf1_tmc/watdl): pratique! cool
[hs]merci de m'avoir rassuré sur ma santé visuelle lol[/hs]

Hors ligne

#322 Le 18/06/2013, à 07:23

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

Pour tv5mondeplus.com il faudrait re-analyser, mais au moins pour certaines vidéos, aller chercher dans le source de la page, soit l'identifiant de la vidéo, soit l'adresse de la vidéo.
L'identifiant de la vidéo est en général 6 chiffres, parfois à la fin de la vidéo.

Exemple, dans le source de http://www.tv5mondeplus.com/video/17-06 … 011-484463

  <script type="text/javascript">
        function finished(){
            TV5.Videoplayer.embed({path:"http://www.tv5mondeplus.com/sites/tv5mondeplus.com/modules/custom/tv5monde_xml/main.swf",container:"player",contentID:'http://www.tv5mondeplus.com/video-xml/get/484463'});

contentID nous donne l'adresse de la vidéo :-)
sinon il semble que
http://www.tv5mondeplus.com/video-xml/get/
suivi de l'identifiant de la vidéo suffise

Aller lire le xml
http://www.tv5mondeplus.com/video-xml/get/484463
par exemple avec

    root = get_url(the_url,0,1)
#    print root
    for element in root.iter():
        print element.tag,element.text
        # la vidéo est sur videoUrl, dans un .smil, que l'on va ouvrir
        # http://fr.wikipedia.org/wiki/Synchronized_Multimedia_Integration_Language
        if element.tag == "videoUrl":
            print 'dans la boucle root.iter' 
            video = element.text
            # exemple de fichier .smil
            # <?xml version="1.0"?>
            #    <!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd">
            #    <smil xmlns="http://www.w3.org/2001/SMIL20/Language">
            #    <head>
            #        <meta name="title" content="COURTS SEJOURS" />
            #        <meta name="httpBase" content="http://vodhdflash.tv5monde.com/" />
            #        <meta name="rtmpAuthBase" content="" />
            #    </head>
            #    <body>
            #        <switch id="tv5_catchup">
            #            <video src="tv5mondeplus/hq/3137682.mp4" system-bitrate="500000"/>
            #            <video src="tv5mondeplus/bq/3137682.mp4" system-bitrate="300000"/>
            #        </switch>
            #    </body>
            #    </smil>
            print video
            root = get_url(video,1,1)
            # le début de l'emplacement de la vidéo est à httpBase, c'est normalement 
            # http://vodhdflash.tv5monde.com/ 
            for x in root.head.getchildren():
                if x.get('name') == 'httpBase':
                    content = x.get('content')
            # la suite de l'emplacement de la video est à video src, 
            # et on prend la ligne avec le bit-rate le plus élevé
            # exemple de suite de l'emplacement, à concaténer
            # tv5mondeplus/hq/3137682.mp4
            itc = root.body.switch.getchildren()
            url = itc.pop()
            for x in itc:
                if x.get('system-bitrate') > url.get('system-bitrate'):
                    url = x
            url = url.get('src')

et

def get_url(the_url, skip_line=0,obj=0):
    try:
        file = urlopen(the_url)
    except URLError, e:
        print e.code
        if hasattr(e, 'reason'):
            print 'Nous avons échoué à joindre le serveur.'
            print 'Raison: ', e.reason
        elif hasattr(e, 'code'):
            print 'Le serveur n\'a pu satisfaire la demande.'
            print 'Code d\' erreur : ', e.code
        raise
    for i in range(skip_line):
        file.readline()
    data = file.read()
#    print data
    file.close()
    return objectify.fromstring(data) if obj else data

Le fichier que j'accédais à l'époque commençait par une ligne blanche qui perturbait lxml, de là le

def get_url(the_url, skip_line=0,obj=0)

à vérifier tout ça !


Archlinux sur Xiaomi Air 13

Hors ligne

#323 Le 18/06/2013, à 07:42

k3c

Re : TVDownloader: télécharger les médias du net ! [2]

Pour tou.tv en théorie on peut télécharger les vidéos visibles depuis la France (sans proxy) avec ce qu'il y a là
http://store-it.appspot.com/tou
surtout
http://store-it.appspot.com/tou/tou_mobile.txt
http://store-it.appspot.com/tou/mtou.sh.html
http://store-it.appspot.com/tou/mtou.sh

mais je n'arrive  rien !

L'exécution de mon draft de script sur une vidéo accessbile depuis la France, combustion

gg@gg-SATELLITE-L755:~$ python toutvnew3.py http://www.tou.tv/combustion
http://api.radio-canada.ca/validationMedia/v1/Validation.html?deviceType=flashhd&idMedia=tAeubxwmInIYq10NwYhcflYdUJZkXDp1&connectionType=broadband&appCode=thePlatform&multibitrate=true&output=jsonp&timeout=66&callback=Player_srcAV_21378044.validationSuccess
Player_srcAV_21378044.validationSuccess({"url":"http://cp143903-f.akamaihd.net/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_,500,800,1200,.mp4.csmil/manifest.f4m?hdnea=st=1371534055~exp=1371534070~acl=/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_*~hmac=d35fe0a167370c56e83f7fcc5a022d6c8318315e51497867d3a3b94dae3145a5","message":null,"errorCode":0,"params":[{"name":"mediaType","value":"video"},{"name":"streamType","value":"akamaiHDN2"},{"name":"tokenType","value":"flashHDNetSession"}],"bitrates":[{"bitrate":1200,"width":852,"height":480,"lines":"480p","param":null},{"bitrate":800,"width":640,"height":360,"lines":"360p","param":null},{"bitrate":500,"width":640,"height":360,"lines":"270p","param":null}]},66)
back from the  API of RAdio Canada  Player_srcAV_21378044.validationSuccess({"url":"http://cp143903-f.akamaihd.net/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_,500,800,1200,.mp4.csmil/manifest.f4m?hdnea=st=1371534055~exp=1371534070~acl=/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_*~hmac=d35fe0a167370c56e83f7fcc5a022d6c8318315e51497867d3a3b94dae3145a5","message":null,"errorCode":0,"params":[{"name":"mediaType","value":"video"},{"name":"streamType","value":"akamaiHDN2"},{"name":"tokenType","value":"flashHDNetSession"}],"bitrates":[{"bitrate":1200,"width":852,"height":480,"lines":"480p","param":null},{"bitrate":800,"width":640,"height":360,"lines":"360p","param":null},{"bitrate":500,"width":640,"height":360,"lines":"270p","param":null}]},66)
 what we look for  http://cp143903-f.akamaihd.net/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_,500,800,1200,.mp4.csmil/manifest.f4m?hdnea=st=1371534055~exp=1371534070~acl=/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_*~hmac=d35fe0a167370c56e83f7fcc5a022d6c8318315e51497867d3a3b94dae3145a5
The manifest  <?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns="http://ns.adobe.com/f4m/1.0" xmlns:akamai="uri:akamai.com/f4m/1.0">
  <akamai:version>2.0</akamai:version>
  <akamai:bw>5000</akamai:bw>
  <id>/005/mp4/c/2013-03-04_08_00_00_combustion_0001_,500,800,1200,.mp4.csmil_0</id>
  <streamType>recorded</streamType>
  <akamai:streamType>vod</akamai:streamType>
  <duration>253.795</duration>
  <streamBaseTime>0.000</streamBaseTime>
  <pv-2.0>;hdntl=exp=1371620455~acl=%2fz%2f005%2fmp4%2fc%2f2013-03-04_08_00_00_combustion_0001_*~data=hdntl~hmac=10fa98c99686625181876cf6bd41f6de9f606480e2126b5e5004b4dc23337fbf</pv-2.0>
  <bootstrapInfo profile="named" id="bootstrap_0">AAAAi2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAD32MAAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAACoBAAAARmFmcnQAAAAAAAAD6AAAAAADAAAAAQAAAAAAAAAAAAAXcAAAACoAAAAAAAPA8AAAHnMAAAAAAAAAAAAAAAAAAAAAAA==</bootstrapInfo>
  <bootstrapInfo profile="named" id="bootstrap_1">AAAAi2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAD32MAAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAACoBAAAARmFmcnQAAAAAAAAD6AAAAAADAAAAAQAAAAAAAAAAAAAXcAAAACoAAAAAAAPA8AAAHnMAAAAAAAAAAAAAAAAAAAAAAA==</bootstrapInfo>
  <bootstrapInfo profile="named" id="bootstrap_2">AAAAi2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAD32MAAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAACoBAAAARmFmcnQAAAAAAAAD6AAAAAADAAAAAQAAAAAAAAAAAAAXcAAAACoAAAAAAAPA8AAAHnMAAAAAAAAAAAAAAAAAAAAAAA==</bootstrapInfo>
  <media bitrate="560" url="0_f368b7f80eef9e44_" bootstrapInfoId="bootstrap_0">
    <metadata>AgAKb25NZXRhRGF0YQgAAAAMAAhkdXJhdGlvbgBAb7lwo9cKPQAFd2lkdGgAQIAAAAAAAAAABmhlaWdodABAcgAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAfzq+t3lsxAAJZnJhbWVyYXRlAEA3+d3/Q38SAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQE7RNT1USXgAD2F1ZGlvc2FtcGxlcmF0ZQBA5YiAAAAAAAAPYXVkaW9zYW1wbGVzaXplAEAwAAAAAAAAAAZzdGVyZW8BAQAMYXVkaW9jb2RlY2lkAEAkAAAAAAAAAAhmaWxlc2l6ZQBBcPtuoAAAAAAACQ==</metadata>
  </media>
  <media bitrate="860" url="1_f368b7f80eef9e44_" bootstrapInfoId="bootstrap_1">
    <metadata>AgAKb25NZXRhRGF0YQgAAAAMAAhkdXJhdGlvbgBAb7lwo9cKPQAFd2lkdGgAQIQAAAAAAAAABmhlaWdodABAdoAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAiPs6JdkWOgAJZnJhbWVyYXRlAEA3+d3/Q38SAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQE7RNT1USXgAD2F1ZGlvc2FtcGxlcmF0ZQBA5YiAAAAAAAAPYXVkaW9zYW1wbGVzaXplAEAwAAAAAAAAAAZzdGVyZW8BAQAMYXVkaW9jb2RlY2lkAEAkAAAAAAAAAAhmaWxlc2l6ZQBBegzq8AAAAAAACQ==</metadata>
  </media>
  <media bitrate="1324" url="2_f368b7f80eef9e44_" bootstrapInfoId="bootstrap_2">
    <metadata>AgAKb25NZXRhRGF0YQgAAAAMAAhkdXJhdGlvbgBAb7lwo9cKPQAFd2lkdGgAQIqgAAAAAAAABmhlaWdodABAfgAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAkrxandNNDgAJZnJhbWVyYXRlAEA3+d3/Q38SAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQF9nmW2zr0cAD2F1ZGlvc2FtcGxlcmF0ZQBA5YiAAAAAAAAPYXVkaW9zYW1wbGVzaXplAEAwAAAAAAAAAAZzdGVyZW8BAQAMYXVkaW9jb2RlY2lkAEAkAAAAAAAAAAhmaWxlc2l6ZQBBhAoRKAAAAAAACQ==</metadata>
  </media>
</manifest>

The command ---------------------------> 
   avconv -i http://cp143903-f.akamaihd.net/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_,500,800,1200,.mp4.csmil/manifest.f4m?hdnea=st=1371534055~exp=1371534070~acl=/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_*~hmac=d35fe0a167370c56e83f7fcc5a022d6c8318315e51497867d3a3b94dae3145a5 -c copy out.ts
avconv version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
  built on Apr  2 2013 17:00:59 with gcc 4.6.3
http://cp143903-f.akamaihd.net/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_,500,800,1200,.mp4.csmil/manifest.f4m?hdnea=st=1371534055~exp=1371534070~acl=/z/005/mp4/c/2013-03-04_08_00_00_combustion_0001_*~hmac=d35fe0a167370c56e83f7fcc5a022d6c8318315e51497867d3a3b94dae3145a5: Invalid data found when processing input
gg@gg-SATELLITE-L755:~$ cat toutvnew3.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# TOU.TV version 0.8 par k3c
# passage de proxy en 2 ème parametre
import subprocess, optparse, re, sys, shlex
import socket, random
import urllib2 
from urllib2 import ProxyHandler, Request, urlopen, URLError, HTTPError
import bs4 as BeautifulSoup
from lxml import objectify
from lxml import etree
listeUserAgents = [ 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10']
def get_proxy():
    opener = urllib2.build_opener()
    opener.addheaders = [('User-agent', random.choice(listeUserAgents))]
    data = opener.open('http://www.xroxy.com/proxy-country-CA.htm').read()
    opener.close()
    s = BeautifulSoup.BeautifulSoup(data)
    hrefs = s.find_all(attrs={'href' : re.compile("host=\d")})
    href = random.choice(hrefs)
    mastr =  href.attrs['href']
    m = re.search('host=(([0-9\.])+)?.*port=(([0-9\.])+)?',str(mastr))
    port = m.group(3)
    host = m.group(1)
    return host, port

def main():
    # timeout en secondes
    timeout = 900
    socket.setdefaulttimeout(timeout)
    usage   = "usage: python toutv   [options] <url de l'emission>"
    parser  = optparse.OptionParser( usage = usage )
    parser.add_option( "--nocolor",         action = 'store_true', default = False, help = 'desactive la couleur dans le terminal' )
    parser.add_option( "-v", "--verbose",   action = "store_true", default = False, help = 'affiche les informations de debugage' )
    ( options, args ) = parser.parse_args()
    if( len( args ) == 0 or args[ 0 ] == "" ):
        parser.print_help()
        parser.exit( 1 )
    html = urlopen(sys.argv[1]).read()
    nom = sys.argv[1][18:].replace('/', '_')
    soup = BeautifulSoup.BeautifulSoup(html)
    elems = [elem for elem in soup.find('div',{'class':'emissionEpisode_containerPlayer'})]
    mastr = elems[1].attrs['src']
    m = re.search('"idMedia":"([A-Za-z0-9_]*)', mastr)
    if m:
        id = m.group(1)
    head = random.choice( listeUserAgents )
    platform1 = 'http://api.radio-canada.ca/validationMedia/v1/Validation.html?deviceType=flashhd&idMedia='
    platform2 = '&connectionType=broadband&appCode=thePlatform&multibitrate=true&output=jsonp&timeout=66&callback=Player_srcAV_21378044.validationSuccess'
    print platform1+id+platform2
    response = urllib2.urlopen(urllib2.Request(platform1+id+platform2))
    newfile = response.read()
    print newfile
    print "back from the  API of RAdio Canada ",newfile
    mm = re.search('url":"(.*)message',str(newfile))
    zzz =  mm.group(1)[:-3]
    print " what we look for ",zzz
    z = urlopen(zzz).read()
    print "The manifest ",z
    f = open("mani.f4m", 'w')
    f.write(z)
    f.close()
#    auth = re.search('<pv-2.0>;(.*)</pv-2.0>',str(z))
#    aut2 = auth.group(1)
#    print "aut2 ",aut2
#    z = urlopen(zzz).read()
    cmds = 'avconv -i %s -c copy out.ts' %(zzz)
    arguments = shlex.split( cmds )
    print "The command ---------------------------> \n  ",cmds
    process = subprocess.Popen( arguments, stdout = subprocess.PIPE).communicate()[0]
if __name__ == "__main__":
    main()

Archlinux sur Xiaomi Air 13

Hors ligne

#324 Le 18/06/2013, à 13:16

11gjm

Re : TVDownloader: télécharger les médias du net ! [2]

Bonjour ,

@Pacome : Pour Info .

Suite des tests concernant "watdl" :
sans "-s" dans la ligne de commandes , Obtenu UNIQUEMENT la piste AUDIO ( 30.020 ko ) (???) .

".\python.exe" "watdl_0947.py" -V "http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html"
INFO:   12:56:34: Traitement de l'url: http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html
INFO:   12:56:36: rtmpdump --resume --rtmp "rtmpe://wske.wat.tv/ondemand/mp4:get/3/HD-1280x720/40/41/10584041.hd" --port 1935 --timeout 10 --swfVfy http://www.wat.tv/images/v60/PlayerWat.swf -o "episode-10-saison-09-bar-clandestin-8000620-10584041.mp4"
INFO:   12:58:42: Téléchargement terminé
INFO:   12:58:42: conversion ffmpeg fileName  tmpFileName (pour corriger le conteneur)
INFO:   12:58:44: episode-10-saison-09-bar-clandestin-8000620-10584041.mp4 est maintenant disponible!
...

Tests concernant msdl et cherie25

msdl -c --no-proxy http://r.nrj.fr/mogador/web/00113348_h264_cherie.mp4 -s 5 -o "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4"
---------------
download [ THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4 ]
Host: [ 95.81.165.1:80 ]    connected!
get_filesize THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4: stat() error
No such file or directory
http resume: no such file "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4", not resuming
redirect to http://http-out.od.orange.fr.tdf-cdn.com/mogador/web/00113348_h264_cherie.mp4?IS=0&ET=1371554117&CIP=12.34.56.78&KO=15&KN=1&US=5ff632b7956ed34a9092dcacd58b6743
Host: [ 80.12.3.45:80 ]    connected!
get_filesize THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4: stat() error
No such file or directory
http resume: no such file "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4", not resuming
redirect to http://CDMONS01.se.http-out.od.orange.fr.tdf-cdn.com/mogador/web/00113348_h264_cherie.mp4?IS=0&ET=1371554117&CIP=12.34.56.78&KO=15&KN=1&US=5ff632b7956ed34a9092dcacd58b6743
Host: [ 80.12.3.141:80 ]    connected!
get_filesize THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4: stat() error
No such file or directory
http resume: no such file "THE_BORDER_:_POLICE_DES_FRONTIERES_700071.mp4", not resuming
DL: 363838176/363838176 B -- 100%                      248.3K/s   Complete
finished!!

L'adresse , ci-dessous , entrée directement dans VLC , fonctionne .

http://CDMONS01...._cherie.mp4?IS=0&ET=1371554117&CIP=12.34.56.78&KO=15&KN=1&US=5ff632b7956ed34a9092dcacd58b6743
NB: CIP=12.34.56.78 correspond à notre adresse IP perso !!!

A+ .

Hors ligne

#325 Le 18/06/2013, à 15:04

pacome

Re : TVDownloader: télécharger les médias du net ! [2]

Bonjour,

J'ai terminé "l'historisation" des versions de watdl (>tmc_tf1) dont je disposais et poussé le tout sur github: ça m'a pris un peu de temps mais c'était aussi l'occasion de me faire à git (commandes, raccourcis emacs).
Je vais faire de même avec d8_d17.

De cette façon les dernières versions des scripts (mais aussi les précédentes) seront accessibles sur le répo, et pour ceux d'entre vous qui souhaitent faire évoluer les scripts ou en ajouter n'hésitez pas à me communiquer votre compte github que je le rajoute à la liste des collaborateurs.

@k3c:
J'avais cherie25_nrj12, mais pas de tv5mondeplus ni de tou.tv dans mes répertoires... tu as un compte github? big_smile

@11gjm:
Tant que la version HD ne sera pas visible directement sur le site de replay (je n'ai toujours pas d'image en HD avec un ◌ qui tourne à la place de ╍ ou ▸, et j'ai eu une màj de flash récemment) je ne crois pas qu'on pourra récupérer des flux HD...
Par contre la conversion ffmpeg n'a pas planté chez toi et du coup tu n'as pas l'avertissement; avconv produit effectivement une "vidéo" ne contenant que le son...
Chez oim par contre:

$ watdl -V http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html
INFO:	13:34:13: Traitement de l'url: http://videos.tf1.fr/les-experts-manhattan/episode-10-saison-09-bar-clandestin-8000620.html
INFO:	13:34:16: rtmpdump --resume --rtmp "rtmpe://wske.wat.tv/ondemand/mp4:get/3/HD-1280x720/40/41/10584041.hd" --port 1935 --timeout 10 --swfVfy http://www.wat.tv/images/v60/PlayerWat.swf -o "episode-10-saison-09-bar-clandestin-8000620-10584041.mp4"
INFO:	13:35:30: Téléchargement incomplet: nouvel essai dans 3s...
INFO:	13:35:33: rtmpdump --resume --rtmp "rtmpe://wske.wat.tv/ondemand/mp4:get/3/HD-1280x720/40/41/10584041.hd" --port 1935 --timeout 10 --swfVfy http://www.wat.tv/images/v60/PlayerWat.swf -o "episode-10-saison-09-bar-clandestin-8000620-10584041.mp4"
INFO:	13:36:50: Téléchargement terminé
INFO:	13:36:50: conversion ffmpeg fileName → tmpFileName (pour corriger le conteneur)
ERROR:	13:36:50: La conversion ffmpeg s'est terminée en erreur.
Le fichier episode-10-saison-09-bar-clandestin-8000620-10584041.mp4 est vraisemblablement illisible...
ERROR:	13:36:50: Veuillez ré-essayer avec l'option --standard-definition
INFO:	13:36:50: episode-10-saison-09-bar-clandestin-8000620-10584041.mp4 est maintenant disponible!

À la sortie: un fichier de ~31Mo illisible

Pour msdl, cherie 25 et nrj12: je n'ai pas encore testé...

À+

Dernière modification par pacome (Le 18/06/2013, à 15:05)

Hors ligne