]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/adultswim.py 
3f7f8c03624a9e25611b239e89cf900b41cbce0e
   2  from  __future__ 
import  unicode_literals
   6  from  . common 
import  InfoExtractor
  15  class  AdultSwimIE ( InfoExtractor
):   16      _VALID_URL 
=  r
'https?://(?:www\.)?adultswim\.com/videos/(?P<is_playlist>playlists/)?(?P<show_path>[^/]+)/(?P<episode_path>[^/?#]+)/?'   19          'url' :  'http://adultswim.com/videos/rick-and-morty/pilot' ,   22                  'md5' :  '247572debc75c7652f253c8daa51a14d' ,   24                      'id' :  'rQxZvXQ4ROaSOqq-or2Mow-0' ,   26                      'title' :  'Rick and Morty - Pilot Part 1' ,   27                      'description' :  "Rick moves in with his daughter's family and establishes himself as a bad influence on his grandson, Morty. "   31                  'md5' :  '77b0e037a4b20ec6b98671c4c379f48d' ,   33                      'id' :  'rQxZvXQ4ROaSOqq-or2Mow-3' ,   35                      'title' :  'Rick and Morty - Pilot Part 4' ,   36                      'description' :  "Rick moves in with his daughter's family and establishes himself as a bad influence on his grandson, Morty. "   41              'id' :  'rQxZvXQ4ROaSOqq-or2Mow' ,   42              'title' :  'Rick and Morty - Pilot' ,   43              'description' :  "Rick moves in with his daughter's family and establishes himself as a bad influence on his grandson, Morty. "   45          'skip' :  'This video is only available for registered users' ,   47          'url' :  'http://www.adultswim.com/videos/playlists/american-parenting/putting-francine-out-of-business/' ,   50                  'md5' :  '2eb5c06d0f9a1539da3718d897f13ec5' ,   52                      'id' :  '-t8CamQlQ2aYZ49ItZCFog-0' ,   54                      'title' :  'American Dad - Putting Francine Out of Business' ,   55                      'description' :  'Stan hatches a plan to get Francine out of the real estate business.Watch more American Dad on [adult swim].'   60              'id' :  '-t8CamQlQ2aYZ49ItZCFog' ,   61              'title' :  'American Dad - Putting Francine Out of Business' ,   62              'description' :  'Stan hatches a plan to get Francine out of the real estate business.Watch more American Dad on [adult swim].'   65          'url' :  'http://www.adultswim.com/videos/tim-and-eric-awesome-show-great-job/dr-steve-brule-for-your-wine/' ,   68                  'md5' :  '3e346a2ab0087d687a05e1e7f3b3e529' ,   70                      'id' :  'sY3cMUR_TbuE4YmdjzbIcQ-0' ,   72                      'title' :  'Tim and Eric Awesome Show Great Job! - Dr. Steve Brule, For Your Wine' ,   73                      'description' :  'Dr. Brule reports live from Wine Country with a special report on wines.   \r\n Watch Tim and Eric Awesome Show Great Job! episode #20, "Embarrassed" on Adult Swim. \r\n\r\n ' ,   78              'id' :  'sY3cMUR_TbuE4YmdjzbIcQ' ,   79              'title' :  'Tim and Eric Awesome Show Great Job! - Dr. Steve Brule, For Your Wine' ,   80              'description' :  'Dr. Brule reports live from Wine Country with a special report on wines.   \r\n Watch Tim and Eric Awesome Show Great Job! episode #20, "Embarrassed" on Adult Swim. \r\n\r\n ' ,   84              'skip_download' :  True ,   87          # heroMetadata.trailer   88          'url' :  'http://www.adultswim.com/videos/decker/inside-decker-a-new-hero/' ,   90              'id' :  'I0LQFQkaSUaFp8PnAWHhoQ' ,   92              'title' :  'Decker - Inside Decker: A New Hero' ,   93              'description' :  'md5:c916df071d425d62d70c86d4399d3ee0' ,   98              'skip_download' :  True ,  103      def  find_video_info ( collection
,  slug
):  104          for  video 
in  collection
. get ( 'videos' ):  105              if  video
. get ( 'slug' ) ==  slug
:  109      def  find_collection_by_linkURL ( collections
,  linkURL
):  110          for  collection 
in  collections
:  111              if  collection
. get ( 'linkURL' ) ==  linkURL
:  115      def  find_collection_containing_video ( collections
,  slug
):  116          for  collection 
in  collections
:  117              for  video 
in  collection
. get ( 'videos' ):  118                  if  video
. get ( 'slug' ) ==  slug
:  119                      return  collection
,  video
 122      def  _real_extract ( self
,  url
):  123          mobj 
=  re
. match ( self
._ VALID
_U RL
,  url
)  124          show_path 
=  mobj
. group ( 'show_path' )  125          episode_path 
=  mobj
. group ( 'episode_path' )  126          is_playlist 
=  True if  mobj
. group ( 'is_playlist' )  else False  128          webpage 
=  self
._ download
_ webpage
( url
,  episode_path
)  130          # Extract the value of `bootstrappedData` from the Javascript in the page.  131          bootstrapped_data 
=  self
._ parse
_ json
( self
._ search
_ regex
(  132              r
'var bootstrappedData = ({.*});' ,  webpage
,  'bootstraped data' ),  episode_path
)  134          # Downloading videos from a /videos/playlist/ URL needs to be handled differently.  135          # NOTE: We are only downloading one video (the current one) not the playlist  137              collections 
=  bootstrapped_data
[ 'playlists' ][ 'collections' ]  138              collection 
=  self
. find_collection_by_linkURL ( collections
,  show_path
)  139              video_info 
=  self
. find_video_info ( collection
,  episode_path
)  141              show_title 
=  video_info
[ 'showTitle' ]  142              segment_ids 
= [ video_info
[ 'videoPlaybackID' ]]  144              collections 
=  bootstrapped_data
[ 'show' ][ 'collections' ]  145              collection
,  video_info 
=  self
. find_collection_containing_video ( collections
,  episode_path
)  146              # Video wasn't found in the collections, let's try `slugged_video`.  147              if  video_info 
is None :  148                  if  bootstrapped_data
. get ( 'slugged_video' , {}). get ( 'slug' ) ==  episode_path
:  149                      video_info 
=  bootstrapped_data
[ 'slugged_video' ]  151                  video_info 
=  bootstrapped_data
. get ( 'heroMetadata' , {}). get ( 'trailer' ). get ( 'video' )  153                  raise  ExtractorError ( 'Unable to find video info' )  155              show 
=  bootstrapped_data
[ 'show' ]  156              show_title 
=  show
[ 'title' ]  157              stream 
=  video_info
. get ( 'stream' )  158              if  stream 
and  stream
. get ( 'videoPlaybackID' ):  159                  segment_ids 
= [ stream
[ 'videoPlaybackID' ]]  160              elif  video_info
. get ( 'clips' ):  161                  segment_ids 
= [ clip
[ 'videoPlaybackID' ]  for  clip 
in  video_info
[ 'clips' ]]  162              elif  video_info
. get ( 'videoPlaybackID' ):  163                  segment_ids 
= [ video_info
[ 'videoPlaybackID' ]]  165                  raise  ExtractorError (  166                      'This video is only available via cable service provider subscription that'  167                      ' is not currently supported. You may want to use --cookies.'  168                      if  video_info
. get ( 'auth' )  is True else  'Unable to find stream or clips' ,  171          episode_id 
=  video_info
[ 'id' ]  172          episode_title 
=  video_info
[ 'title' ]  173          episode_description 
=  video_info
[ 'description' ]  174          episode_duration 
=  video_info
. get ( 'duration' )  177          for  part_num
,  segment_id 
in  enumerate ( segment_ids
):  178              segment_url 
=  'http://www.adultswim.com/videos/api/v0/assets?id= %s &platform=desktop'  %  segment_id
 180              segment_title 
=  ' %s  -  %s '  % ( show_title
,  episode_title
)  181              if  len ( segment_ids
) >  1 :  182                  segment_title 
+=  ' Part  %d '  % ( part_num 
+  1 )  184              idoc 
=  self
._ download
_ xml
(  185                  segment_url
,  segment_title
,  186                  'Downloading segment information' ,  'Unable to download segment information' )  188              segment_duration 
=  float_or_none (  189                  xpath_text ( idoc
,  './/trt' ,  'segment duration' ). strip ())  192              file_els 
=  idoc
. findall ( './/files/file' )  or  idoc
. findall ( './files/file' )  196              for  file_el 
in  file_els
:  197                  media_url 
=  file_el
. text
 198                  if not  media_url 
or  determine_ext ( media_url
) ==  'f4m' :  200                  if  file_el
. text 
not in  unique_urls
:  201                      unique_urls
. append ( file_el
. text
)  202                      unique_file_els
. append ( file_el
)  204              for  file_el 
in  unique_file_els
:  205                  bitrate 
=  file_el
. attrib
. get ( 'bitrate' )  206                  ftype 
=  file_el
. attrib
. get ( 'type' )  207                  media_url 
=  file_el
. text
 208                  if  determine_ext ( media_url
) ==  'm3u8' :  209                      formats
. extend ( self
._ extract
_ m
3u8_ formats
(  210                          media_url
,  segment_title
,  'mp4' ,  preference
= 0 ,  211                          m3u8_id
= 'hls' ,  fatal
= False ))  214                          'format_id' :  ' %s _ %s '  % ( bitrate
,  ftype
),  215                          'url' :  file_el
. text
. strip (),  216                          # The bitrate may not be a number (for example: 'iphone')  217                          'tbr' :  int ( bitrate
)  if  bitrate
. isdigit ()  else None ,  220              self
._ sort
_ formats
( formats
)  224                  'title' :  segment_title
,  226                  'duration' :  segment_duration
,  227                  'description' :  episode_description
 233              'display_id' :  episode_path
,  235              'title' :  ' %s  -  %s '  % ( show_title
,  episode_title
),  236              'description' :  episode_description
,  237              'duration' :  episode_duration