Edit 23/04/2012 : Modification du script pour télécharger via http au lieu de rtmp

 

Mieux vaut tard que jamais, j’ai découvert la série Bref ce week-end.

Cette série diffusé durant le grand-journal fait le buzz et est surtout très drôle, rythmé, bref superbe.

Par contre la regarder en direct pendant le grand journal, ce n’est pas possible pour moi, la regarder en différé sur le site de Canal+ non plus, il me fallait donc trouver un moyen pour la télécharger automatiquement et pouvoir la regarder tranquillement sur mon HTPC.

Il existe divers scripts et programmes pour télécharger les émissions de Canal+, je devais en trouver un qui fonctionne, qui puisse être planifié (exécuté tous les jours et qui garde en mémoire les épisode déjà téléchargés) et surtout headless (en ligne de commande).

Mon point de départ, ce thread d’Ubuntu-fr.org et j’ai trouvé mon bonheur en page 16 avec le script de vincentp010 (recopié en fin d’article)

Ce script en Python se base sur un tableau des ids des émissions à télécharger :

emissions=[
48,    # GUIGNOLS
252,   # SAV
254,   # GROLAND
201,   # ZAPPING
104# GRAND JOURNAL
249# PETIT JOURNAL
37,   # ACTION DISCRETE
39,   # LA MATINALE
47,   # PEPITES DU NET
62,   # LE BOUCAN DU JOUR
215# LE MEILLEUR DU HIER
]

Restait à trouver l’id de l’émission Bref.

Après quelques recherches infructueuses je suis tombé sur cette URL qui liste toutes les émissions de Canal+.

Bref à l’id 627, j’ai donc modifié le tableau émission ainsi :

emissions=[
627,    # BREF
]

Paramétré les chemins (penser à créer les répertoires) et nom de fichier :

homedir = os.path.expanduser('~/bin')
HISTORIQUE = homedir + "/.cplus_hist"
output_dir = "/data/downloads/videos/canalplus"

Installé flvstreamer :

sudo aptitude install flvstreamer

Pour finir le script est planifié en crontab et le boulot est fait….

 

Script de téléchargement des séries Canal+ de vincentp010 :

#!/usr/bin/python
# -*- coding:Utf-8 -*-
 
###########################################################################
# Copyright (C) 2010  La_Poigne                                           #
# This program is free software: you can redistribute it and/or modify    #
#  it under the terms of the GNU General Public License as published by   #
#  the Free Software Foundation, either version 2 of the License, or      #
#  any later version.                                                     #
# This program is distributed in the hope that it will be useful,         #
#  but WITHOUT ANY WARRANTY without even the implied warranty of          #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          #
#  GNU General Public License for more details.                           #
# You should have received a copy of the GNU General Public License       #
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.  #
###########################################################################
#
#Script pour telecharger les emission du site canalplus.fr
#Fonctionne en theorie sur tous les OS
#
#Changelog:
#V 0.1
#21-12-2010 : Creation
#V 0.2
#22-12-2010 : Reglage probleme encodage dans fichier log
#V 0.3
#23-12-2010 : Ajout d'une option "--log" et prise en compte de l'absence du tag sous-titre
 
 
 
import os, urllib, subprocess, time, sys 
from xml.dom import minidom
 
 
# Numeros des emissions a telecharger, commentez celles que vous ne voulez pas
emissions=[
627,	# BREF
#48,    # GUIGNOLS
#252,   # SAV
#254,   # GROLAND
#201,   # ZAPPING
#104,  # GRAND JOURNAL
#249,  # PETIT JOURNAL
#37,   # ACTION DISCRETE
#39,   # LA MATINALE
#47,   # PEPITES DU NET
#62,   # LE BOUCAN DU JOUR
#215,  # LE MEILLEUR DU HIER
]
 
# Qualite de la video
#qualite = "BAS_DEBIT"
#qualite = "HAUT_DEBIT"
qualite = "HD"
 
# Repertoires (pensez a les creer avant)
homedir = os.path.expanduser('~/bin')
HISTORIQUE = homedir + "/.cplus_hist"
output_dir = "/data/downloads/videos/canalplus"
 
 
 
# Ne rien modifier sous cette ligne
# Sauf pour ameliorer le fonctionnement ;)
 
logfile = os.path.join(homedir, "canal.log")
urlXMLEmissions = "http://www.canalplus.fr/rest/bootstrap.php?/bigplayer/getMEAs/"
urlXMLVid = "http://www.canalplus.fr/rest/bootstrap.php?/bigplayer/getVideos/"
 
# Parse Mea file to get videos id
def ParseMeas(xmldoc):
   ids = []
   meas = xmldoc.getElementsByTagName('MEA')
   for i in meas:
      if i.getElementsByTagName('ID')[0].childNodes != []:
         id = i.getElementsByTagName('ID')[0].childNodes[0].nodeValue
         ids.append(id)
   return ids
 
# Parse video file to get name and url
def ParseVid(xmldoc):
   names = []
   urlVids = []
   videos = xmldoc.getElementsByTagName('VIDEO')
   for i in videos:
      titrage = i.getElementsByTagName('INFOS')[0].getElementsByTagName('TITRAGE')[0]
      if titrage.getElementsByTagName('TITRE')[0].childNodes != []:
         titre = titrage.getElementsByTagName('TITRE')[0].childNodes[0].nodeValue
         if titrage.getElementsByTagName('SOUS_TITRE')[0].childNodes != []:
            stitre = titrage.getElementsByTagName('SOUS_TITRE')[0].childNodes[0].nodeValue
            date = "_" + stitre
         else:
            date = ""
         name = titre + date
         name = name.replace(' ', '.').replace('/', '-')
         videos = i.getElementsByTagName('MEDIA')[0].getElementsByTagName('VIDEOS')[0]
         rtmp= videos.getElementsByTagName(qualite)[0].childNodes[0].nodeValue
         names.append(name)
         urlVids.append(rtmp)
   return names, urlVids
 
# Execute command and write stdout in file var
def execute(params, file):
   p = subprocess.Popen(params,stdout=file)
   p.wait()
   return p.returncode
 
def addHistory(name):
   file = open(HISTORIQUE, 'a')
   file.write(name.encode('utf-8') + '\n')
   file.close()
 
def checkHistory(name):
   findvalue = 0
   file = open(HISTORIQUE, 'r')
   for line in file:
      if line.decode('utf-8') == name + '\n':
         findvalue = 1
   file.close()
   return findvalue
 
def downXml(url):
   try:
      xmlFileSock=urllib.urlopen(url)
      xmlFile = xmlFileSock.read()
   except Exception, e:
      return 1
   try:
      xmldoc = minidom.parseString(xmlFile)
   except Exception, e:
      xmldoc = 1
   return xmldoc
 
 
if __name__ == "__main__":
 
   debug = False
   if len(sys.argv) == 2:     
     if sys.argv[1] == "--log":
        debug = True
        print "Debug ON"
        logf = open(logfile, "w")
 
   if os.path.exists(HISTORIQUE) == False:
     file = open(HISTORIQUE, 'w')
     file.close()
 
   for num in emissions:
      url = urlXMLEmissions + str(num)
      if debug:
         logf.write(time.strftime("%Y-%m-%d %H:%M:%S") + '\n')
         logf.write("Downloading " + url + '\n')
      xmldoc = downXml(url)
      if xmldoc == 1:
         print "Erreur durant la recuperation de la liste " + str(num)
         if debug:
            logf.write(url + " download error" + '\n')
      else:
         id = ParseMeas(xmldoc)
         if debug:
            logf.write("-> Ids " + str(id) + '\n')
 
         for vid in id:
            url2 = urlXMLVid + vid
            if debug:
              logf.write("Downloading " + url2 + '\n')
            xmldoc2 = downXml(url2)
            if xmldoc2 == 1:
               if debug:
                  logf.write(url2 + " download error" + '\n')
            else:
               names, urlVids = ParseVid(xmldoc2)
               if debug:
                  logf.write("--> names " + str(names) + '\n')
                  logf.write("---> urlvid " + str(urlVids) + '\n')
 
               i = 0
               loop = 0
               while i < len(names):
 
                  check = checkHistory(names[i])
                  if check == 0:
                     if debug:
                       logf.write("Try to download file ")
 
                     basename, extension = os.path.splitext(urlVids[i])
                     flvFile = os.path.join(output_dir , names[i] + extension)
                     if urlVids[i].find("rtmp")!=-1:
                        if debug:
                           logf.write("with flvstreamer" + '\n')
                        params=['flvstreamer', '-r', urlVids[i]]
                        file = open(flvFile, 'w')
                        r = execute(params, file)
                        file.close()
                     else:
                        if debug:
                           logf.write("direct download" + '\n')
                        try:
                           urllib.urlretrieve(urlVids[i], flvFile)
                           r=0
                        except Exception:
                           r=1
                     # If returncode OK, next file
                     if r == 0:
                        if debug:
                          logf.write("Download finished, add file to history " + '\n')
                        addHistory(names[i])
                        loop = 0
                        i += 1
                     else:
                        if os.path.exists(flvFile):
                           os.remove(flvFile)
                        loop += 1
                        # After 5 retry abord file
                        if loop == 5:
                           if debug:
                              logf.write("Download aborded" + '\n')
                           i += 1
                           loop = 0
                        else:
                           if debug:
                              logf.write("Download error" + '\n')
                           print "Download error, retry in 30 seconds"
                           time.sleep(30)
                  else:
                     print "File already downloaded"
                     if debug:
                       logf.write("File already downloaded" + '\n')
 
                     i += 1
 
   if debug:
      logf.close()

PS : si vous cherchez un programme avec une interface graphique qui fait la même chose et bien plus encore, il existe tvdownloader qui est parfait

flvFile = os.path.join(output_dir , names[i] + extension)
if urlVids[i].find(« rtmp »)!=-1:
if debug:
logf.write(« with flvstreamer » + ‘\n’)
params=['flvstreamer', '-r', urlVids[i]]
file = open(flvFile, ‘w’)
r = execute(params, file)
file.close()
else:
if debug:
logf.write(« direct download » + ‘\n’)
try:
urllib.urlretrieve(urlVids[i], flvFile)
r=0
except Exception:
r=1

Les commentaires sont fermés.