1
0
mirror of https://github.com/ytdl-org/youtube-dl.git synced 2025-02-21 12:30:18 +01:00

Implement C-SPAN Live information extractor

This commit introduces the `CSpanLiveIE` class to add support for C-SPAN
live streams. These streams are based on the `BrightcoveNewIE` class
which requires Adobe Pass MSO authentication.

In order to support this new information extractor, `BrightcoveNewIE`
had to be updated to support an optional Akamai token ('hdnts' query
parameter) in the final m3u8 URL used by Brightcove.
This commit is contained in:
Clay Freeman 2019-07-16 23:57:55 -05:00
parent 1824bfdcdf
commit bce2befab6
No known key found for this signature in database
GPG Key ID: E8023472A3663FDC
3 changed files with 47 additions and 4 deletions

View File

@ -12,6 +12,7 @@ from ..compat import (
compat_etree_fromstring,
compat_parse_qs,
compat_str,
compat_urllib_parse_urlencode,
compat_urllib_parse_urlparse,
compat_urlparse,
compat_xml_parse_error,
@ -611,14 +612,14 @@ class BrightcoveNewIE(AdobePassIE):
return entries
def _parse_brightcove_metadata(self, json_data, video_id, headers={}):
def _parse_brightcove_metadata(self, json_data, video_id, headers={}, options={}):
title = json_data['name'].strip()
formats = []
for source in json_data.get('sources', []):
container = source.get('container')
ext = mimetype2ext(source.get('type'))
src = source.get('src')
src = self._preprocess_metadata_url(source.get('src'), options)
# https://support.brightcove.com/playback-api-video-fields-reference#key_systems_object
if ext == 'ism' or container == 'WVM' or source.get('key_systems'):
continue
@ -723,6 +724,17 @@ class BrightcoveNewIE(AdobePassIE):
'is_live': is_live,
}
def _preprocess_metadata_url(self, url, options={}):
url = compat_urllib_parse_urlparse(url)._asdict()
query = dict(compat_parse_qs(url['query']))
if options.get('akamai_token') is not None:
query['hdnts'] = options.get('akamai_token')
url['query'] = compat_urllib_parse_urlencode(query)
return compat_urlparse.urlunparse(tuple(url.values()))
def _real_extract(self, url):
url, smuggled_data = unsmuggle_url(url, {})
self._initialize_geo_bypass({
@ -786,12 +798,16 @@ class BrightcoveNewIE(AdobePassIE):
'tveToken': tve_token,
})
options = {
'akamai_token': smuggled_data.get('akamai_token')
}
if content_type == 'playlist':
return self.playlist_result(
[self._parse_brightcove_metadata(vid, vid.get('id'), headers)
[self._parse_brightcove_metadata(vid, vid.get('id'), headers=headers, options=options)
for vid in json_data.get('videos', []) if vid.get('id')],
json_data.get('id'), json_data.get('name'),
json_data.get('description'))
return self._parse_brightcove_metadata(
json_data, video_id, headers=headers)
json_data, video_id, headers=headers, options=options)

View File

@ -0,0 +1,26 @@
# coding: utf-8
from __future__ import unicode_literals
from .brightcove import BrightcoveNewIE
from .common import InfoExtractor
from ..utils import smuggle_url
class CSpanLiveIE(InfoExtractor):
IE_NAME = 'cspanlive'
BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/3162030207001/2B2qWQJYYM_default/index.html?videoId=%s'
_VALID_URL = r'^https?://(?:www\.)?c-span\.org/networks'
def _real_extract(self, url):
webpage = self._download_webpage(url, 'stream')
akamai_token = self._html_search_regex(r'data-akamaitoken="([^"]+)"', webpage, 'akamai_token')
video_id = self._html_search_regex(r'data-bcid="([^"]+)"', webpage, 'video_id')
brightcove_url = smuggle_url(self.BRIGHTCOVE_URL_TEMPLATE % video_id, {
'akamai_token': akamai_token,
'source_url': url
})
return self.url_result(brightcove_url, ie=BrightcoveNewIE.ie_key(), video_id=video_id)

View File

@ -238,6 +238,7 @@ from .crunchyroll import (
CrunchyrollShowPlaylistIE
)
from .cspan import CSpanIE
from .cspanlive import CSpanLiveIE
from .ctsnews import CtsNewsIE
from .ctvnews import CTVNewsIE
from .cultureunplugged import CultureUnpluggedIE