2021-01-01 05:26:37 -07:00
import re
2016-08-16 06:43:33 -06:00
from . theplatform import ThePlatformIE
from . . utils import (
2016-08-16 07:49:32 -06:00
int_or_none ,
2017-07-26 13:04:51 -06:00
parse_age_limit ,
try_get ,
update_url_query ,
2016-08-16 06:43:33 -06:00
)
2022-11-15 17:57:43 -07:00
class AMCNetworksIE ( ThePlatformIE ) : # XXX: Do not subclass from concrete IE
2021-01-01 05:26:37 -07:00
_VALID_URL = r ' https?://(?:www \ .)?(?P<site>amc|bbcamerica|ifc|(?:we|sundance)tv) \ .com/(?P<id>(?:movies|shows(?:/[^/]+)+)/[^/?#&]+) '
2016-08-16 06:43:33 -06:00
_TESTS = [ {
2021-01-01 05:26:37 -07:00
' url ' : ' https://www.bbcamerica.com/shows/the-graham-norton-show/videos/tina-feys-adorable-airline-themed-family-dinner--51631 ' ,
2016-08-16 06:43:33 -06:00
' info_dict ' : {
2021-01-01 05:26:37 -07:00
' id ' : ' 4Lq1dzOnZGt0 ' ,
2016-08-16 06:43:33 -06:00
' ext ' : ' mp4 ' ,
2021-01-01 05:26:37 -07:00
' title ' : " The Graham Norton Show - Season 28 - Tina Fey ' s Adorable Airline-Themed Family Dinner " ,
' description ' : " It turns out child stewardesses are very generous with the wine! All-new episodes of ' The Graham Norton Show ' premiere Fridays at 11/10c on BBC America. " ,
' upload_date ' : ' 20201120 ' ,
' timestamp ' : 1605904350 ,
2016-08-16 06:43:33 -06:00
' uploader ' : ' AMCN ' ,
} ,
' params ' : {
# m3u8 download
' skip_download ' : True ,
} ,
2023-10-06 17:56:19 -06:00
' skip ' : ' 404 Not Found ' ,
2016-08-16 06:43:33 -06:00
} , {
' url ' : ' http://www.bbcamerica.com/shows/the-hunt/full-episodes/season-1/episode-01-the-hardest-challenge ' ,
' only_matching ' : True ,
} , {
' url ' : ' http://www.amc.com/shows/preacher/full-episodes/season-01/episode-00/pilot ' ,
' only_matching ' : True ,
} , {
' url ' : ' http://www.wetv.com/shows/million-dollar-matchmaker/season-01/episode-06-the-dumped-dj-and-shallow-hal ' ,
' only_matching ' : True ,
} , {
' url ' : ' http://www.ifc.com/movies/chaos ' ,
' only_matching ' : True ,
2016-11-22 05:40:57 -07:00
} , {
' url ' : ' http://www.bbcamerica.com/shows/doctor-who/full-episodes/the-power-of-the-daleks/episode-01-episode-1-color-version ' ,
' only_matching ' : True ,
2017-02-24 12:51:53 -07:00
} , {
' url ' : ' http://www.wetv.com/shows/mama-june-from-not-to-hot/full-episode/season-01/thin-tervention ' ,
' only_matching ' : True ,
} , {
' url ' : ' http://www.wetv.com/shows/la-hair/videos/season-05/episode-09-episode-9-2/episode-9-sneak-peek-3 ' ,
' only_matching ' : True ,
2018-01-28 03:30:20 -07:00
} , {
' url ' : ' https://www.sundancetv.com/shows/riviera/full-episodes/season-1/episode-01-episode-1 ' ,
' only_matching ' : True ,
2016-08-16 06:43:33 -06:00
} ]
2021-01-01 05:26:37 -07:00
_REQUESTOR_ID_MAP = {
' amc ' : ' AMC ' ,
' bbcamerica ' : ' BBCA ' ,
' ifc ' : ' IFC ' ,
' sundancetv ' : ' SUNDANCE ' ,
' wetv ' : ' WETV ' ,
}
2016-08-16 06:43:33 -06:00
def _real_extract ( self , url ) :
2021-08-18 19:41:24 -06:00
site , display_id = self . _match_valid_url ( url ) . groups ( )
2021-01-01 05:26:37 -07:00
requestor_id = self . _REQUESTOR_ID_MAP [ site ]
2021-03-20 04:41:11 -06:00
page_data = self . _download_json (
2024-06-11 17:09:58 -06:00
f ' https://content-delivery-gw.svc.ds.amcn.com/api/v2/content/amcn/ { requestor_id . lower ( ) } /url/ { display_id } ' ,
display_id ) [ ' data ' ]
2021-03-20 04:41:11 -06:00
properties = page_data . get ( ' properties ' ) or { }
2016-08-16 06:43:33 -06:00
query = {
' mbr ' : ' true ' ,
' manifest ' : ' m3u ' ,
}
2021-03-20 04:41:11 -06:00
video_player_count = 0
try :
for v in page_data [ ' children ' ] :
if v . get ( ' type ' ) == ' video-player ' :
2024-06-11 17:09:58 -06:00
release_pid = v [ ' properties ' ] [ ' currentVideo ' ] [ ' meta ' ] [ ' releasePid ' ]
tp_path = ' M_UwQC/ ' + release_pid
2021-03-20 04:41:11 -06:00
media_url = ' https://link.theplatform.com/s/ ' + tp_path
video_player_count + = 1
except KeyError :
pass
if video_player_count > 1 :
self . report_warning (
2024-06-11 17:09:58 -06:00
f ' The JSON data has { video_player_count } video players. Only one will be extracted ' )
2021-03-20 04:41:11 -06:00
# Fall back to videoPid if releasePid not found.
# TODO: Fall back to videoPid if releasePid manifest uses DRM.
if not video_player_count :
tp_path = ' M_UwQC/media/ ' + properties [ ' videoPid ' ]
media_url = ' https://link.theplatform.com/s/ ' + tp_path
2021-01-01 05:26:37 -07:00
theplatform_metadata = self . _download_theplatform_metadata ( tp_path , display_id )
2016-08-16 06:43:33 -06:00
info = self . _parse_theplatform_metadata ( theplatform_metadata )
video_id = theplatform_metadata [ ' pid ' ]
title = theplatform_metadata [ ' title ' ]
2017-07-26 13:04:51 -06:00
rating = try_get (
theplatform_metadata , lambda x : x [ ' ratings ' ] [ 0 ] [ ' rating ' ] )
2021-01-01 05:26:37 -07:00
video_category = properties . get ( ' videoCategory ' )
if video_category and video_category . endswith ( ' -Auth ' ) :
2017-02-15 06:18:50 -07:00
resource = self . _get_mvpd_resource (
requestor_id , title , video_id , rating )
query [ ' auth ' ] = self . _extract_mvpd_auth (
url , video_id , requestor_id , resource )
2016-08-16 06:43:33 -06:00
media_url = update_url_query ( media_url , query )
2017-02-15 06:18:50 -07:00
formats , subtitles = self . _extract_theplatform_smil (
media_url , video_id )
2021-03-20 04:41:11 -06:00
thumbnails = [ ]
thumbnail_urls = [ properties . get ( ' imageDesktop ' ) ]
if ' thumbnail ' in info :
thumbnail_urls . append ( info . pop ( ' thumbnail ' ) )
for thumbnail_url in thumbnail_urls :
if not thumbnail_url :
continue
mobj = re . search ( r ' ( \ d+)x( \ d+) ' , thumbnail_url )
thumbnails . append ( {
' url ' : thumbnail_url ,
' width ' : int ( mobj . group ( 1 ) ) if mobj else None ,
' height ' : int ( mobj . group ( 2 ) ) if mobj else None ,
} )
2016-08-16 06:43:33 -06:00
info . update ( {
2021-03-20 04:41:11 -06:00
' age_limit ' : parse_age_limit ( rating ) ,
' formats ' : formats ,
2016-08-16 06:43:33 -06:00
' id ' : video_id ,
2016-08-16 09:20:07 -06:00
' subtitles ' : subtitles ,
2021-03-20 04:41:11 -06:00
' thumbnails ' : thumbnails ,
2016-08-16 06:43:33 -06:00
} )
2016-08-16 07:49:32 -06:00
ns_keys = theplatform_metadata . get ( ' $xmlns ' , { } ) . keys ( )
if ns_keys :
2024-06-11 17:09:58 -06:00
ns = next ( iter ( ns_keys ) )
2021-03-20 04:41:11 -06:00
episode = theplatform_metadata . get ( ns + ' $episodeTitle ' ) or None
2017-02-15 06:18:50 -07:00
episode_number = int_or_none (
theplatform_metadata . get ( ns + ' $episode ' ) )
2021-03-20 04:41:11 -06:00
season_number = int_or_none (
theplatform_metadata . get ( ns + ' $season ' ) )
series = theplatform_metadata . get ( ns + ' $show ' ) or None
2016-08-16 07:49:32 -06:00
info . update ( {
' episode ' : episode ,
' episode_number ' : episode_number ,
2021-03-20 04:41:11 -06:00
' season_number ' : season_number ,
' series ' : series ,
2016-08-16 07:49:32 -06:00
} )
2016-08-16 06:43:33 -06:00
return info