@ -10,13 +10,14 @@ from ..utils import (
unified_strdate ,
url_basename ,
qualities ,
int_or_none ,
)
class CanalplusIE ( InfoExtractor ) :
IE_DESC = ' canalplus.fr, piwiplus.fr and d8.tv '
_VALID_URL = r ' https?://(?:www \ .(?P<site>canalplus \ .fr|piwiplus \ .fr|d8 \ .tv|itele \ .fr)/.*?/(?P<path>.*)|player \ .canalplus \ .fr/#/(?P<id>[0-9]+)) '
_VIDEO_INFO_TEMPLATE = ' http://service.canal-plus.com/video/rest/getVideosLiees/ %s / %s '
_VIDEO_INFO_TEMPLATE = ' http://service.canal-plus.com/video/rest/getVideosLiees/ %s / %s ?format=json '
_SITE_ID_MAP = {
' canalplus.fr ' : ' cplus ' ,
' piwiplus.fr ' : ' teletoon ' ,
@ -26,10 +27,10 @@ class CanalplusIE(InfoExtractor):
_TESTS = [ {
' url ' : ' http://www.canalplus.fr/c-emissions/pid1830-c-zapping.html?vid=1263092 ' ,
' md5 ' : ' b3481d7ca972f61e37420798d0a9d934 ' ,
' md5 ' : ' 12164a6f14ff6df8bd628e8ba9b10b78 ' ,
' info_dict ' : {
' id ' : ' 1263092 ' ,
' ext ' : ' flv ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Le Zapping - 13/05/15 ' ,
' description ' : ' md5:09738c0d06be4b5d06a0940edb0da73f ' ,
' upload_date ' : ' 20150513 ' ,
@ -56,10 +57,10 @@ class CanalplusIE(InfoExtractor):
' skip ' : ' videos get deleted after a while ' ,
} , {
' url ' : ' http://www.itele.fr/france/video/aubervilliers-un-lycee-en-colere-111559 ' ,
' md5 ' : ' f3a46edcdf28006598ffaf5b30e6a2d4 ' ,
' md5 ' : ' 38b8f7934def74f0d6f3ba6c036a5f82 ' ,
' info_dict ' : {
' id ' : ' 1213714 ' ,
' ext ' : ' flv ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Aubervilliers : un lycée en colère - Le 11/02/2015 à 06h45 ' ,
' description ' : ' md5:8216206ec53426ea6321321f3b3c16db ' ,
' upload_date ' : ' 20150211 ' ,
@ -82,15 +83,16 @@ class CanalplusIE(InfoExtractor):
webpage , ' video id ' , group = ' id ' )
info_url = self . _VIDEO_INFO_TEMPLATE % ( site_id , video_id )
doc = self . _download_xml ( info_url , video_id , ' Downloading video XML ' )
video_data = self . _download_json ( info_url , video_id , ' Downloading video JSON ' )
video_info = [ video for video in doc if video . find ( ' ID ' ) . text == video_id ] [ 0 ]
media = video_info . find ( ' MEDIA ' )
infos = video_info . find ( ' INFOS ' )
if isinstance ( video_data , list ) :
video_data = [ video for video in video_data if video . get ( ' ID ' ) == video_id ] [ 0 ]
media = video_data [ ' MEDIA ' ]
infos = video_data [ ' INFOS ' ]
preference = qualities ( [ ' MOBILE ' , ' BAS_DEBIT ' , ' HAUT_DEBIT ' , ' HD ' , ' HLS ' , ' HDS ' ] )
preference = qualities ( [ ' MOBILE ' , ' BAS_DEBIT ' , ' HAUT_DEBIT ' , ' HD ' ] )
fmt_url = next ( iter ( media . find ( ' VIDEOS ' ) ) ) . text
fmt_url = next ( iter ( media . get ( ' VIDEOS ' ) ) )
if ' /geo ' in fmt_url . lower ( ) :
response = self . _request_webpage (
HEADRequest ( fmt_url ) , video_id ,
@ -101,35 +103,42 @@ class CanalplusIE(InfoExtractor):
expected = True )
formats = [ ]
for fmt in media . find ( ' VIDEOS ' ) :
format_url = fmt . text
for format_id , format_url in media [ ' VIDEOS ' ] . items ( ) :
if not format_url :
continue
format_id = fmt . tag
if format_id == ' HLS ' :
formats . extend ( self . _extract_m3u8_formats (
format_url , video_id , ' mp4 ' , preference = preference ( format_id ) ) )
format_url , video_id , ' mp4 ' , ' m3u8_native ' , m3u8_id = format_id , fatal = False ) )
elif format_id == ' HDS ' :
formats . extend ( self . _extract_f4m_formats (
format_url + ' ?hdcore=2.11.3 ' , video_id , preference = preference ( format_id ) ) )
format_url + ' ?hdcore=2.11.3 ' , video_id , f4m_id = format_id , fatal = False ) )
else :
formats . append ( {
' url ' : format_url ,
# the secret extracted ya function in http://player.canalplus.fr/common/js/canalPlayer.js
' url ' : format_url + ' ?secret=pqzerjlsmdkjfoiuerhsdlfknaes ' ,
' format_id ' : format_id ,
' preference ' : preference ( format_id ) ,
} )
self . _sort_formats ( formats )
thumbnails = [ {
' id ' : image_id ,
' url ' : image_url ,
} for image_id , image_url in media . get ( ' images ' , { } ) . items ( ) ]
titrage = infos [ ' TITRAGE ' ]
return {
' id ' : video_id ,
' display_id ' : display_id ,
' title ' : ' %s - %s ' % ( infos . find ( ' TITRAGE/TITRE ' ) . text ,
infos . find ( ' TITRAGE/SOUS_TITRE ' ) . text ) ,
' upload_date ' : unified_strdate ( infos . find ( ' PUBLICATION/DATE ' ) . text ) ,
' thumbnail ' : media . find ( ' IMAGES/GRAND ' ) . text ,
' description ' : infos . find ( ' DESCRIPTION ' ) . text ,
' view_count ' : int ( infos . find ( ' NB_VUES ' ) . text ) ,
' like_count ' : int ( infos . find ( ' NB_LIKES ' ) . text ) ,
' comment_count ' : int ( infos . find ( ' NB_COMMENTS ' ) . text ) ,
' title ' : ' %s - %s ' % ( titrage [ ' TITRE ' ] ,
titrage [ ' SOUS_TITRE ' ] ) ,
' upload_date ' : unified_strdate ( infos . get ( ' PUBLICATION ' , { } ) . get ( ' DATE ' ) ) ,
' thumbnails ' : thumbnails ,
' description ' : infos . get ( ' DESCRIPTION ' ) ,
' duration ' : int_or_none ( infos . get ( ' DURATION ' ) ) ,
' view_count ' : int_or_none ( infos . get ( ' NB_VUES ' ) ) ,
' like_count ' : int_or_none ( infos . get ( ' NB_LIKES ' ) ) ,
' comment_count ' : int_or_none ( infos . get ( ' NB_COMMENTS ' ) ) ,
' formats ' : formats ,
}