2014-02-24 08:00:31 -05:00
from __future__ import unicode_literals
2013-08-27 06:38:30 -04:00
import re
from . common import InfoExtractor
2015-12-19 19:43:42 -05:00
from . . compat import compat_HTTPError
2014-12-13 06:24:42 -05:00
from . . utils import (
2014-07-22 19:47:18 -04:00
ExtractorError ,
find_xpath_attr ,
2015-05-04 09:53:05 -04:00
lowercase_escape ,
2015-12-08 10:16:14 -05:00
smuggle_url ,
2015-05-04 09:53:05 -04:00
unescapeHTML ,
2014-07-22 19:47:18 -04:00
)
2013-08-27 06:38:30 -04:00
2014-02-25 17:57:54 -05:00
class NBCIE ( InfoExtractor ) :
2015-03-28 09:18:11 -04:00
_VALID_URL = r ' https?://www \ .nbc \ .com/(?:[^/]+/)+(?P<id>n? \ d+) '
2014-12-12 11:10:32 -05:00
_TESTS = [
{
2015-02-19 09:00:39 -05:00
' url ' : ' http://www.nbc.com/the-tonight-show/segments/112966 ' ,
2014-12-12 11:10:32 -05:00
' info_dict ' : {
2016-01-30 15:34:46 -05:00
' id ' : ' 112966 ' ,
' ext ' : ' mp4 ' ,
2015-02-19 09:00:39 -05:00
' title ' : ' Jimmy Fallon Surprises Fans at Ben & Jerry \' s ' ,
' description ' : ' Jimmy gives out free scoops of his new " Tonight Dough " ice cream flavor by surprising customers at the Ben & Jerry \' s scoop shop. ' ,
2014-12-12 11:10:32 -05:00
} ,
2016-01-30 15:34:46 -05:00
' params ' : {
# m3u8 download
' skip_download ' : True ,
} ,
2014-02-25 17:57:54 -05:00
} ,
2014-12-12 11:10:32 -05:00
{
' url ' : ' http://www.nbc.com/the-tonight-show/episodes/176 ' ,
' info_dict ' : {
2016-01-30 15:34:46 -05:00
' id ' : ' 176 ' ,
2014-12-12 11:10:32 -05:00
' ext ' : ' flv ' ,
' title ' : ' Ricky Gervais, Steven Van Zandt, ILoveMakonnen ' ,
' description ' : ' A brand new episode of The Tonight Show welcomes Ricky Gervais, Steven Van Zandt and ILoveMakonnen. ' ,
} ,
2016-01-30 15:34:46 -05:00
' skip ' : ' 404 Not Found ' ,
2014-12-12 11:10:32 -05:00
} ,
2015-05-04 07:09:18 -04:00
{
' url ' : ' http://www.nbc.com/saturday-night-live/video/star-wars-teaser/2832821 ' ,
' info_dict ' : {
2016-01-30 15:34:46 -05:00
' id ' : ' 2832821 ' ,
' ext ' : ' mp4 ' ,
2015-05-04 07:09:18 -04:00
' title ' : ' Star Wars Teaser ' ,
' description ' : ' md5:0b40f9cbde5b671a7ff62fceccc4f442 ' ,
} ,
2016-01-30 15:34:46 -05:00
' params ' : {
# m3u8 download
' skip_download ' : True ,
} ,
2015-05-04 07:09:18 -04:00
' skip ' : ' Only works from US ' ,
2015-05-04 09:53:05 -04:00
} ,
{
# This video has expired but with an escaped embedURL
' url ' : ' http://www.nbc.com/parenthood/episode-guide/season-5/just-like-at-home/515 ' ,
' skip ' : ' Expired '
2015-05-04 07:09:18 -04:00
}
2014-12-12 11:10:32 -05:00
]
2014-02-25 17:57:54 -05:00
def _real_extract ( self , url ) :
2014-10-26 20:14:17 -04:00
video_id = self . _match_id ( url )
2014-02-25 17:57:54 -05:00
webpage = self . _download_webpage ( url , video_id )
2015-05-04 09:53:05 -04:00
theplatform_url = unescapeHTML ( lowercase_escape ( self . _html_search_regex (
2015-05-04 07:09:18 -04:00
[
r ' (?:class= " video-player video-player-full " data-mpx-url|class= " player " src)= " (.*?) " ' ,
2015-12-08 10:16:58 -05:00
r ' <iframe[^>]+src= " ((?:https?:)?//player \ .theplatform \ .com/[^ " ]+) " ' ,
2015-05-04 07:09:18 -04:00
r ' " embedURL " \ s*: \ s* " ([^ " ]+) " '
] ,
2015-05-04 09:53:05 -04:00
webpage , ' theplatform url ' ) . replace ( ' _no_endcard ' , ' ' ) . replace ( ' \\ / ' , ' / ' ) ) )
2014-02-25 17:57:54 -05:00
if theplatform_url . startswith ( ' // ' ) :
theplatform_url = ' http: ' + theplatform_url
2016-01-30 15:34:46 -05:00
return {
' _type ' : ' url_transparent ' ,
' url ' : smuggle_url ( theplatform_url , { ' source_url ' : url } ) ,
' id ' : video_id ,
}
2014-02-25 17:57:54 -05:00
2015-03-30 14:47:18 -04:00
class NBCSportsVPlayerIE ( InfoExtractor ) :
2015-03-30 15:36:09 -04:00
_VALID_URL = r ' https?://vplayer \ .nbcsports \ .com/(?:[^/]+/)+(?P<id>[0-9a-zA-Z_]+) '
2015-03-30 14:21:27 -04:00
2015-03-30 15:38:45 -04:00
_TESTS = [ {
2015-03-30 14:21:27 -04:00
' url ' : ' https://vplayer.nbcsports.com/p/BxmELC/nbcsports_share/select/9CsDKds0kvHI ' ,
' info_dict ' : {
' id ' : ' 9CsDKds0kvHI ' ,
' ext ' : ' flv ' ,
' description ' : ' md5:df390f70a9ba7c95ff1daace988f0d8d ' ,
' title ' : ' Tyler Kalinoski hits buzzer-beater to lift Davidson ' ,
}
2015-03-30 15:38:45 -04:00
} , {
' url ' : ' http://vplayer.nbcsports.com/p/BxmELC/nbc_embedshare/select/_hqLjQ95yx8Z ' ,
' only_matching ' : True ,
} ]
2015-03-30 14:21:27 -04:00
2015-03-30 14:47:18 -04:00
@staticmethod
def _extract_url ( webpage ) :
iframe_m = re . search (
r ' <iframe[^>]+src= " (?P<url>https?://vplayer \ .nbcsports \ .com/[^ " ]+) " ' , webpage )
if iframe_m :
return iframe_m . group ( ' url ' )
2015-03-30 14:21:27 -04:00
def _real_extract ( self , url ) :
video_id = self . _match_id ( url )
webpage = self . _download_webpage ( url , video_id )
theplatform_url = self . _og_search_video_url ( webpage )
return self . url_result ( theplatform_url , ' ThePlatform ' )
2015-03-30 14:47:18 -04:00
class NBCSportsIE ( InfoExtractor ) :
2016-01-10 10:17:47 -05:00
# Does not include https because its certificate is invalid
2015-03-30 14:47:18 -04:00
_VALID_URL = r ' http://www \ .nbcsports \ .com//?(?:[^/]+/)+(?P<id>[0-9a-z-]+) '
_TEST = {
' url ' : ' http://www.nbcsports.com//college-basketball/ncaab/tom-izzo-michigan-st-has-so-much-respect-duke ' ,
' info_dict ' : {
' id ' : ' PHJSaFWbrTY9 ' ,
' ext ' : ' flv ' ,
' title ' : ' Tom Izzo, Michigan St. has \' so much respect \' for Duke ' ,
' description ' : ' md5:ecb459c9d59e0766ac9c7d5d0eda8113 ' ,
}
}
def _real_extract ( self , url ) :
video_id = self . _match_id ( url )
webpage = self . _download_webpage ( url , video_id )
return self . url_result (
NBCSportsVPlayerIE . _extract_url ( webpage ) , ' NBCSportsVPlayer ' )
2013-08-27 06:38:30 -04:00
class NBCNewsIE ( InfoExtractor ) :
2015-02-14 06:42:12 -05:00
_VALID_URL = r ''' (?x)https?://(?:www \ .)?nbcnews \ .com/
( ? : video / . + ? / ( ? P < id > \d + ) |
2015-08-01 11:43:33 -04:00
( ? : watch | feature | nightly - news ) / [ ^ / ] + / ( ? P < title > . + ) )
2014-05-29 18:38:57 -04:00
'''
2013-08-27 06:38:30 -04:00
2014-05-29 18:38:57 -04:00
_TESTS = [
{
' url ' : ' http://www.nbcnews.com/video/nbc-news/52753292 ' ,
' md5 ' : ' 47abaac93c6eaf9ad37ee6c4463a5179 ' ,
' info_dict ' : {
' id ' : ' 52753292 ' ,
' ext ' : ' flv ' ,
' title ' : ' Crew emerges after four-month Mars food study ' ,
' description ' : ' md5:24e632ffac72b35f8b67a12d1b6ddfc1 ' ,
} ,
2013-08-27 06:38:30 -04:00
} ,
2014-05-29 18:38:57 -04:00
{
' url ' : ' http://www.nbcnews.com/feature/edward-snowden-interview/how-twitter-reacted-snowden-interview-n117236 ' ,
' md5 ' : ' b2421750c9f260783721d898f4c42063 ' ,
' info_dict ' : {
' id ' : ' I1wpAI_zmhsQ ' ,
2014-10-26 20:14:17 -04:00
' ext ' : ' mp4 ' ,
2014-05-29 18:38:57 -04:00
' title ' : ' How Twitter Reacted To The Snowden Interview ' ,
' description ' : ' md5:65a0bd5d76fe114f3c2727aa3a81fe64 ' ,
} ,
' add_ie ' : [ ' ThePlatform ' ] ,
} ,
2015-01-20 10:23:51 -05:00
{
' url ' : ' http://www.nbcnews.com/feature/dateline-full-episodes/full-episode-family-business-n285156 ' ,
' md5 ' : ' fdbf39ab73a72df5896b6234ff98518a ' ,
' info_dict ' : {
' id ' : ' Wjf9EDR3A_60 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' FULL EPISODE: Family Business ' ,
' description ' : ' md5:757988edbaae9d7be1d585eb5d55cc04 ' ,
} ,
} ,
2015-02-14 05:10:23 -05:00
{
' url ' : ' http://www.nbcnews.com/nightly-news/video/nightly-news-with-brian-williams-full-broadcast-february-4-394064451844 ' ,
' md5 ' : ' b5dda8cddd8650baa0dcb616dd2cf60d ' ,
' info_dict ' : {
' id ' : ' sekXqyTVnmN3 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' Nightly News with Brian Williams Full Broadcast (February 4) ' ,
' description ' : ' md5:1c10c1eccbe84a26e5debb4381e2d3c5 ' ,
} ,
} ,
2015-08-01 11:43:33 -04:00
{
' url ' : ' http://www.nbcnews.com/watch/dateline/full-episode--deadly-betrayal-386250819952 ' ,
' only_matching ' : True ,
} ,
2014-05-29 18:38:57 -04:00
]
2013-08-27 06:38:30 -04:00
def _real_extract ( self , url ) :
mobj = re . match ( self . _VALID_URL , url )
video_id = mobj . group ( ' id ' )
2014-05-29 18:38:57 -04:00
if video_id is not None :
all_info = self . _download_xml ( ' http://www.nbcnews.com/id/ %s /displaymode/1219 ' % video_id , video_id )
info = all_info . find ( ' video ' )
2013-08-27 06:38:30 -04:00
2014-05-29 18:38:57 -04:00
return {
' id ' : video_id ,
' title ' : info . find ( ' headline ' ) . text ,
' ext ' : ' flv ' ,
' url ' : find_xpath_attr ( info , ' media ' , ' type ' , ' flashVideo ' ) . text ,
2015-12-19 19:43:42 -05:00
' description ' : info . find ( ' caption ' ) . text ,
2014-05-29 18:38:57 -04:00
' thumbnail ' : find_xpath_attr ( info , ' media ' , ' type ' , ' thumbnail ' ) . text ,
}
else :
2015-02-14 05:10:23 -05:00
# "feature" and "nightly-news" pages use theplatform.com
2014-05-29 18:38:57 -04:00
title = mobj . group ( ' title ' )
webpage = self . _download_webpage ( url , title )
2015-02-14 06:42:12 -05:00
bootstrap_json = self . _search_regex (
r ' var \ s+(?:bootstrapJson|playlistData) \ s*= \ s*( { .+});? \ s*$ ' ,
webpage , ' bootstrap json ' , flags = re . MULTILINE )
bootstrap = self . _parse_json ( bootstrap_json , video_id )
2014-05-29 18:38:57 -04:00
info = bootstrap [ ' results ' ] [ 0 ] [ ' video ' ]
mpxid = info [ ' mpxId ' ]
2014-07-21 12:06:21 -04:00
base_urls = [
info [ ' fallbackPlaylistUrl ' ] ,
info [ ' associatedPlaylistUrl ' ] ,
]
for base_url in base_urls :
2014-10-26 20:14:17 -04:00
if not base_url :
continue
2014-07-21 12:06:21 -04:00
playlist_url = base_url + ' ?form=MPXNBCNewsAPI '
try :
2015-01-20 10:23:51 -05:00
all_videos = self . _download_json ( playlist_url , title )
except ExtractorError as ee :
if isinstance ( ee . cause , compat_HTTPError ) :
continue
raise
2015-01-21 04:36:15 -05:00
if not all_videos or ' videos ' not in all_videos :
2015-01-20 10:23:51 -05:00
continue
try :
info = next ( v for v in all_videos [ ' videos ' ] if v [ ' mpxId ' ] == mpxid )
2014-07-21 12:06:21 -04:00
break
except StopIteration :
continue
if info is None :
raise ExtractorError ( ' Could not find video in playlists ' )
2014-05-29 18:38:57 -04:00
return {
' _type ' : ' url ' ,
# We get the best quality video
' url ' : info [ ' videoAssets ' ] [ - 1 ] [ ' publicUrl ' ] ,
' ie_key ' : ' ThePlatform ' ,
}
2015-08-19 13:41:18 -04:00
class MSNBCIE ( InfoExtractor ) :
# https URLs redirect to corresponding http ones
_VALID_URL = r ' http://www \ .msnbc \ .com/[^/]+/watch/(?P<id>[^/]+) '
_TEST = {
' url ' : ' http://www.msnbc.com/all-in-with-chris-hayes/watch/the-chaotic-gop-immigration-vote-314487875924 ' ,
' md5 ' : ' 6d236bf4f3dddc226633ce6e2c3f814d ' ,
' info_dict ' : {
' id ' : ' n_hayes_Aimm_140801_272214 ' ,
' ext ' : ' mp4 ' ,
' title ' : ' The chaotic GOP immigration vote ' ,
' description ' : ' The Republican House votes on a border bill that has no chance of getting through the Senate or signed by the President and is drawing criticism from all sides. ' ,
' thumbnail ' : ' re:^https?://.* \ .jpg$ ' ,
' timestamp ' : 1406937606 ,
' upload_date ' : ' 20140802 ' ,
' categories ' : [ ' MSNBC/Topics/Franchise/Best of last night ' , ' MSNBC/Topics/General/Congress ' ] ,
} ,
}
def _real_extract ( self , url ) :
video_id = self . _match_id ( url )
webpage = self . _download_webpage ( url , video_id )
embed_url = self . _html_search_meta ( ' embedURL ' , webpage )
return self . url_result ( embed_url )