2024-05-26 13:27:21 -06:00
import base64
2021-07-13 17:36:18 -06:00
import json
2024-05-26 13:27:21 -06:00
import re
2021-07-13 17:36:18 -06:00
import urllib . parse
2024-05-26 13:27:21 -06:00
from . common import InfoExtractor
from . . utils import js_to_json
2014-12-12 11:22:24 -07:00
class RTPIE ( InfoExtractor ) :
2024-09-13 17:09:52 -06:00
_VALID_URL = r ' https?://(?:www \ .)?rtp \ .pt/play/(?:(?:estudoemcasa|palco|zigzag)/)?p(?P<program_id>[0-9]+)/(?P<id>[^/?#]+) '
2014-12-13 16:13:07 -07:00
_TESTS = [ {
2014-12-12 11:22:24 -07:00
' url ' : ' http://www.rtp.pt/play/p405/e174042/paixoes-cruzadas ' ,
2015-02-06 13:59:17 -07:00
' md5 ' : ' e736ce0c665e459ddb818546220b4ef8 ' ,
2014-12-12 11:22:24 -07:00
' info_dict ' : {
2014-12-21 07:28:40 -07:00
' id ' : ' e174042 ' ,
2014-12-12 11:22:24 -07:00
' ext ' : ' mp3 ' ,
' title ' : ' Paixões Cruzadas ' ,
' description ' : ' As paixões musicais de António Cartaxo e António Macedo ' ,
2017-01-02 05:08:07 -07:00
' thumbnail ' : r ' re:^https?://.* \ .jpg ' ,
2014-12-12 11:22:24 -07:00
} ,
2024-09-13 17:09:52 -06:00
} , {
' url ' : ' https://www.rtp.pt/play/zigzag/p13166/e757904/25-curiosidades-25-de-abril ' ,
' md5 ' : ' 9a81ed53f2b2197cfa7ed455b12f8ade ' ,
' info_dict ' : {
' id ' : ' e757904 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' 25 Curiosidades, 25 de Abril ' ,
' description ' : ' Estudar ou não estudar - Em cada um dos episódios descobrimos uma curiosidade acerca de como era viver em Portugal antes da revolução do 25 de abr ' ,
' thumbnail ' : r ' re:^https?://.* \ .jpg ' ,
} ,
2014-12-13 16:13:07 -07:00
} , {
' url ' : ' http://www.rtp.pt/play/p831/a-quimica-das-coisas ' ,
' only_matching ' : True ,
2024-09-13 17:09:52 -06:00
} , {
' url ' : ' https://www.rtp.pt/play/estudoemcasa/p7776/portugues-1-ano ' ,
' only_matching ' : True ,
} , {
' url ' : ' https://www.rtp.pt/play/palco/p13785/l7nnon ' ,
' only_matching ' : True ,
2014-12-13 16:13:07 -07:00
} ]
2014-12-12 11:22:24 -07:00
2021-07-13 17:36:18 -06:00
_RX_OBFUSCATION = re . compile ( r ''' (?xs)
atob \s * \( \s * decodeURIComponent \s * \( \s *
( \[ [ 0 - 9 A - Za - z % , ' " ]* \ ])
\s * \. \s * join \( \s * ( ? : " " | ' ' ) \s * \) \s * \) \s * \)
''' )
def __unobfuscate ( self , data , * , video_id ) :
if data . startswith ( ' { ' ) :
data = self . _RX_OBFUSCATION . sub (
lambda m : json . dumps (
base64 . b64decode ( urllib . parse . unquote (
2024-06-11 17:09:58 -06:00
' ' . join ( self . _parse_json ( m . group ( 1 ) , video_id ) ) ,
2021-07-13 17:36:18 -06:00
) ) . decode ( ' iso-8859-1 ' ) ) ,
data )
return js_to_json ( data )
2014-12-12 11:22:24 -07:00
def _real_extract ( self , url ) :
video_id = self . _match_id ( url )
webpage = self . _download_webpage ( url , video_id )
title = self . _html_search_meta (
' twitter:title ' , webpage , display_name = ' title ' , fatal = True )
2015-02-06 13:59:17 -07:00
2021-07-13 17:36:18 -06:00
f , config = self . _search_regex (
r ''' (?sx)
2024-09-13 17:09:52 -06:00
( ? : var \s + f \s * = \s * ( ? P < f > " .*? " | { [ ^ ; ] + ? } ) ; \s * ) ?
2021-07-13 17:36:18 -06:00
var \s + player1 \s + = \s + new \s + RTPPlayer \s * \( ( ? P < config > { ( ? : ( ? ! \* / ) . ) + ? } ) \) ; ( ? ! \s * \* / )
''' , webpage,
' player config ' , group = ( ' f ' , ' config ' ) )
config = self . _parse_json (
config , video_id ,
lambda data : self . __unobfuscate ( data , video_id = video_id ) )
2024-09-13 17:09:52 -06:00
f = config [ ' file ' ] if not f else self . _parse_json (
f , video_id ,
lambda data : self . __unobfuscate ( data , video_id = video_id ) )
2021-07-13 17:36:18 -06:00
formats = [ ]
if isinstance ( f , dict ) :
f_hls = f . get ( ' hls ' )
if f_hls is not None :
formats . extend ( self . _extract_m3u8_formats (
f_hls , video_id , ' mp4 ' , ' m3u8_native ' , m3u8_id = ' hls ' ) )
f_dash = f . get ( ' dash ' )
if f_dash is not None :
formats . extend ( self . _extract_mpd_formats ( f_dash , video_id , mpd_id = ' dash ' ) )
2019-05-27 21:58:12 -06:00
else :
2021-07-13 17:36:18 -06:00
formats . append ( {
' format_id ' : ' f ' ,
' url ' : f ,
' vcodec ' : ' none ' if config . get ( ' mediaType ' ) == ' audio ' else None ,
} )
subtitles = { }
vtt = config . get ( ' vtt ' )
if vtt is not None :
for lcode , lname , url in vtt :
subtitles . setdefault ( lcode , [ ] ) . append ( {
' name ' : lname ,
' url ' : url ,
} )
2015-02-06 13:59:17 -07:00
2014-12-12 11:22:24 -07:00
return {
' id ' : video_id ,
' title ' : title ,
' formats ' : formats ,
2019-05-27 21:58:12 -06:00
' description ' : self . _html_search_meta ( [ ' description ' , ' twitter:description ' ] , webpage ) ,
' thumbnail ' : config . get ( ' poster ' ) or self . _og_search_thumbnail ( webpage ) ,
2021-07-13 17:36:18 -06:00
' subtitles ' : subtitles ,
2014-12-12 11:22:24 -07:00
}