2016-01-08 07:28:02 +01:00
# -*- encoding: utf-8 -*-
2016-01-10 05:47:57 +01:00
from __future__ import unicode_literals
2016-01-08 06:39:46 +01:00
from . common import InfoExtractor , ExtractorError
2013-11-05 23:30:25 +01:00
class TvpIE ( InfoExtractor ) :
2014-11-26 12:58:53 +01:00
IE_NAME = ' tvp.pl '
2016-01-10 06:32:54 +01:00
_VALID_URL = r ' https?://( \ w+ \ .)+tvp \ .(?:pl|info)/(?P<id> \ d+)/.* '
2015-01-10 02:38:27 +01:00
2016-01-08 10:00:33 +01:00
_VIDEO_LISTING_URL = ( ' http://www.api.v3.tvp.pl/shared/listing.php '
' ?dump=json&direct=true&count=-1&parent_id= {id} ' )
_META_URL = ' http://www.tvp.pl/shared/video_data.php?dump=json&video_id= {id} '
_TOKENIZER_URL = ' http://www.tvp.pl/shared/cdn/tokenizer_v2.php?object_id= {id} '
_FILE_INFO_URL = ' http://www.tvp.pl/pub/stat/videofileinfo?video_id= {id} '
_IGNORED_MIMETYPES = ' application/vnd.ms-ss ' , ' application/x-mpegurl '
2015-01-10 02:38:27 +01:00
_TESTS = [ {
2016-01-08 06:39:46 +01:00
' url ' : ' http://vod.tvp.pl/4278035/odc-2 ' ,
2015-01-19 23:00:22 +06:00
' md5 ' : ' cdd98303338b8a7f7abab5cd14092bf2 ' ,
2015-01-10 02:38:27 +01:00
' info_dict ' : {
' id ' : ' 4278035 ' ,
' ext ' : ' wmv ' ,
' title ' : ' Ogniem i mieczem, odc. 2 ' ,
2016-01-08 06:39:46 +01:00
' description ' : ' Bohun dowiaduje się o złamaniu przez kniahinię danego mu słowa i wyrusza do Rozłogów. Helenie w ostatniej chwili udaje się uciec dzięki pomocy Zagłoby. '
2015-01-10 02:38:27 +01:00
} ,
2016-01-08 07:43:31 +01:00
} , {
' url ' : ' http://warszawa.tvp.pl/23433721/03012016 ' ,
' md5 ' : ' 8740c6e0532f37e836104f3fb38921d9 ' ,
' info_dict ' : {
' id ' : ' 23433721 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Echa tygodnia – kraj, 03.01.2016 ' ,
} ,
2016-01-08 07:20:40 +01:00
} , {
' url ' : ' http://www.rodzinka.tvp.pl/22729075/odc-169 ' ,
' md5 ' : ' 4dc102e0883555d31b120e8328c02022 ' ,
' info_dict ' : {
' id ' : ' 22353810 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' rodzinka.pl, odc. 169 ' ,
' description ' : ' Natalia szykuje dla Marii paczkę z ubrankami dla dziecka, \n ale ciężko jej się z nimi rozstać – wiążę się z tym zbyt wiele wspomnień. Kacper chce wymusić od Ludwika pieniądze opowiadając o wróżce zębuszcze. A czy zna tak zwanego „Skrzata Dlatata”? ' ,
} ,
2015-01-10 02:38:27 +01:00
} , {
2016-01-08 06:39:46 +01:00
' url ' : ' http://vod.tvp.pl/194536/i-seria-odc-13 ' ,
2015-01-19 23:00:22 +06:00
' md5 ' : ' 8aa518c15e5cc32dfe8db400dc921fbb ' ,
2015-01-10 02:38:27 +01:00
' info_dict ' : {
' id ' : ' 194536 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Czas honoru, I seria – odc. 13 ' ,
2016-01-08 06:39:46 +01:00
' description ' : ' Czesław prosi Marię o dostarczenie Władkowi zarazki tyfusu. Jeśli zachoruje zostanie przewieziony do szpitala skąd łatwiej będzie go odbić. Czy matka zdecyduje się zarazić syna? '
2015-01-10 02:38:27 +01:00
} ,
} , {
2016-01-08 06:39:46 +01:00
' url ' : ' http://vod.tvp.pl/17834272/odc-39 ' ,
' md5 ' : ' dafdadb130a45e79bab64aed94b73661 ' ,
2015-01-10 02:38:27 +01:00
' info_dict ' : {
2016-01-08 06:39:46 +01:00
' id ' : ' 17834272 ' ,
2015-01-10 02:38:27 +01:00
' ext ' : ' mp4 ' ,
2016-01-08 06:39:46 +01:00
' title ' : ' Na sygnale, odc. 39 ' ,
' description ' : ' Ekipa Wiktora ratuje młodą matkę, która spadła ze schodów trzymając na rękach noworodka. Okazuje się, że dziewczyna jest surogatką, a biologiczni rodzice dziecka próbują zmusić ją do oddania synka… ' ,
2015-01-10 02:38:27 +01:00
} ,
} , {
2016-01-08 06:39:46 +01:00
' url ' : ' http://vod.tvp.pl/4278026/ogniem-i-mieczem ' ,
2015-01-10 02:38:27 +01:00
' info_dict ' : {
2016-01-08 06:39:46 +01:00
' title ' : ' Ogniem i mieczem ' ,
' id ' : ' 4278026 ' ,
' description ' : ' Romans z historią w tle ' ,
} ,
' playlist_count ' : 4 ,
} , {
' url ' : ' http://vod.tvp.pl/9329207/ ' ,
' info_dict ' : {
' title ' : ' Boso przez świat ' ,
' id ' : ' 9329207 ' ,
' description ' : ' Docieramy do plemion w zapomnianych regionach naszej planety. Poznajemy ich kulturę, wierzenia i zwyczaje. Na ile są podobne do naszych? Wojciech Cejrowski jest naszym przewodnikiem po najbardziej dzikich zakątkach globu. ' ,
2015-01-10 02:38:27 +01:00
} ,
2016-01-08 06:39:46 +01:00
' playlist_count ' : 86 ,
2015-01-10 02:38:27 +01:00
} ]
2013-11-05 23:30:25 +01:00
2016-01-09 05:52:43 +01:00
def _get_json ( self , url , entry_id , fatal = True ) :
2016-01-08 10:00:33 +01:00
formatted_url = url . format ( id = int ( entry_id ) )
2016-01-09 05:52:43 +01:00
json = self . _download_json ( formatted_url , entry_id , fatal = fatal )
return { } if json is None else json
2016-01-08 06:39:46 +01:00
2016-01-08 10:00:33 +01:00
def _format_formats ( self , formats , video_id ) :
2016-01-08 06:39:46 +01:00
mime_ext = {
' video/x-ms-wmv ' : ' wmv ' ,
' video/mp4 ' : ' mp4 '
}
2015-01-19 23:00:22 +06:00
2016-01-08 06:39:46 +01:00
viable_formats = [ ]
for f in formats :
2016-01-09 05:41:16 +01:00
if f . get ( ' mimeType ' ) in self . _IGNORED_MIMETYPES :
continue
if ' url ' not in f :
2016-01-08 06:39:46 +01:00
continue
2016-01-09 05:41:16 +01:00
viable_formats . append (
{ ' url ' : f [ ' url ' ] ,
' ext ' : mime_ext . get ( f . get ( ' mimeType ' ) ) ,
' vbr ' : f . get ( ' totalBitrate ' ) } )
2016-01-08 06:39:46 +01:00
return viable_formats
2016-01-08 10:00:33 +01:00
@staticmethod
def _guess_title ( item ) :
title_root = item . get ( ' title_root ' )
title = item . get ( ' title ' )
website_title = item . get ( ' website_title ' )
if title_root :
return item [ ' title_root ' ]
if title and website_title :
return ' {} , {} ' . format ( website_title , title )
return title
2016-01-08 06:39:46 +01:00
def _get_video ( self , context ) :
2016-01-08 10:00:33 +01:00
video_id = str ( context [ ' material_id ' ] )
title = self . _guess_title ( context )
2016-01-08 06:39:46 +01:00
url = context [ ' url ' ]
2016-01-08 10:00:33 +01:00
description = context . get ( ' description_root ' )
formats_req = self . _get_json ( self . _TOKENIZER_URL , video_id )
req_status = formats_req [ ' status ' ]
if req_status == ' NOT_PLAYABLE ' :
raise ExtractorError ( ' ( %s ) is not playable ' % title ,
expected = True , video_id = video_id )
elif req_status != ' OK ' :
raise ExtractorError ( ' ( %s ) unknown status: %s ' % ( title , req_status ) ,
video_id = video_id )
formats = self . _format_formats ( formats_req [ ' formats ' ] , video_id )
2015-01-10 02:38:27 +01:00
self . _sort_formats ( formats )
return {
2016-01-08 10:00:33 +01:00
' id ' : video_id ,
2016-01-08 06:39:46 +01:00
' url ' : url ,
2015-01-10 02:38:27 +01:00
' title ' : title ,
2016-01-08 06:39:46 +01:00
' description ' : description ,
2015-01-10 02:38:27 +01:00
' formats ' : formats ,
}
2014-12-04 05:14:09 +01:00
2016-01-08 06:39:46 +01:00
def _get_playlist_videos ( self , playlist_id ) :
ids = [ playlist_id ]
while ids :
item_id = ids . pop ( )
2016-01-08 10:00:33 +01:00
listing = self . _get_json ( self . _VIDEO_LISTING_URL , item_id )
2016-01-08 06:39:46 +01:00
for item in listing [ ' items ' ] :
if ' directory_video ' in item [ ' types ' ] :
ids . append ( item [ ' _id ' ] )
if ' video ' in item [ ' types ' ] and item [ ' is_released ' ] :
2016-01-10 05:48:59 +01:00
yield self . url_result ( item [ ' url ' ] ,
video_id = item [ ' _id ' ] ,
video_title = self . _guess_title ( item ) )
2016-01-08 06:39:46 +01:00
def _get_playlist ( self , context ) :
2016-01-08 10:00:33 +01:00
pls_id = str ( context [ ' material_id ' ] )
2016-01-09 05:18:58 +01:00
title = self . _guess_title ( context )
2016-01-08 10:00:33 +01:00
description = context . get ( ' lead_root ' )
2016-01-08 06:39:46 +01:00
2016-01-08 10:00:33 +01:00
return self . playlist_result ( self . _get_playlist_videos ( pls_id ) ,
pls_id , title , description )
2016-01-08 06:39:46 +01:00
def _real_extract ( self , url ) :
2016-01-08 10:00:33 +01:00
entry_id = self . _match_id ( url )
ctx = self . _get_json ( self . _META_URL , entry_id ) [ ' context ' ]
2016-01-08 07:20:40 +01:00
if ctx [ ' format_id ' ] == 0 :
2016-01-09 05:52:43 +01:00
file_info = self . _get_json ( self . _FILE_INFO_URL , entry_id , fatal = False )
2016-01-08 07:20:40 +01:00
original_id = file_info . get ( ' copy_of_object_id ' )
if original_id :
2016-01-08 10:00:33 +01:00
ctx = self . _get_json ( self . _META_URL , original_id ) [ ' context ' ]
2016-01-08 07:20:40 +01:00
2016-01-08 06:39:46 +01:00
is_playlist = ctx [ ' format_id ' ] == 0
return self . _get_playlist ( ctx ) if is_playlist else self . _get_video ( ctx )
2014-12-04 05:14:09 +01:00
2016-01-08 06:39:46 +01:00
class TvpLegacyIE ( TvpIE ) :
IE_NAME = ' tvp.pl '
_VALID_URL = r ' https?://(?:vod|www) \ .tvp \ .pl/.*/(?P<id> \ d+)$ '
2014-12-04 05:14:09 +01:00
2015-01-10 02:38:27 +01:00
_TESTS = [ {
2016-01-08 06:39:46 +01:00
' url ' : ' http://vod.tvp.pl/filmy-fabularne/filmy-za-darmo/ogniem-i-mieczem/wideo/odc-2/4278035 ' ,
' md5 ' : ' cdd98303338b8a7f7abab5cd14092bf2 ' ,
2015-01-10 02:38:27 +01:00
' info_dict ' : {
2016-01-08 06:39:46 +01:00
' id ' : ' 4278035 ' ,
' ext ' : ' wmv ' ,
' title ' : ' Ogniem i mieczem, odc. 2 ' ,
' description ' : ' Bohun dowiaduje się o złamaniu przez kniahinię danego mu słowa i wyrusza do Rozłogów. Helenie w ostatniej chwili udaje się uciec dzięki pomocy Zagłoby. ' ,
2015-01-10 02:38:27 +01:00
} ,
} , {
2016-01-08 06:39:46 +01:00
' url ' : ' http://vod.tvp.pl/seriale/obyczajowe/czas-honoru/sezon-1-1-13/i-seria-odc-13/194536 ' ,
' md5 ' : ' 8aa518c15e5cc32dfe8db400dc921fbb ' ,
2015-01-10 02:38:27 +01:00
' info_dict ' : {
2016-01-08 06:39:46 +01:00
' id ' : ' 194536 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Czas honoru, I seria – odc. 13 ' ,
' description ' : ' Czesław prosi Marię o dostarczenie Władkowi zarazki tyfusu. Jeśli zachoruje zostanie przewieziony do szpitala skąd łatwiej będzie go odbić. Czy matka zdecyduje się zarazić syna? ' ,
} ,
} , {
' url ' : ' http://www.tvp.pl/there-can-be-anything-so-i-shortened-it/17916176 ' ,
' md5 ' : ' b0005b542e5b4de643a9690326ab1257 ' ,
' info_dict ' : {
' id ' : ' 17916176 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' TVP Gorzów pokaże filmy studentów z podroży dookoła świata ' ,
} ,
} , {
' url ' : ' http://vod.tvp.pl/seriale/obyczajowe/na-sygnale/sezon-2-27-/odc-39/17834272 ' ,
' md5 ' : ' dafdadb130a45e79bab64aed94b73661 ' ,
' info_dict ' : {
' id ' : ' 17834272 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Na sygnale, odc. 39 ' ,
' description ' : ' Ekipa Wiktora ratuje młodą matkę, która spadła ze schodów trzymając na rękach noworodka. Okazuje się, że dziewczyna jest surogatką, a biologiczni rodzice dziecka próbują zmusić ją do oddania synka… ' ,
2015-01-10 02:38:27 +01:00
} ,
} ]