-
-
Save meise/3616d171acdbdc281eed to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Plugin for media.ccc.de | |
Supports: | |
- http://media.ccc.de (vod) | |
- http://streaming.media.ccc.de (livestreaming) | |
""" | |
import re | |
import requests | |
import json | |
from livestreamer.plugin import Plugin, PluginError | |
from livestreamer.stream import HTTPStream, HLSStream | |
API_URL_MEDIA = "https://api.media.ccc.de/public/events/" | |
API_URL_STREAMING_MEDIA = "http://streaming.media.ccc.de/streams/v1.json" | |
# http(s)://media.ccc.de/path/to/talk.html | |
_url_media_re = re.compile("(?P<scheme>http|https)" | |
":\/\/" | |
"(?P<server>media\.ccc\.de)" | |
"\/") | |
# http://streaming.media.ccc.de/room/ | |
_url_streaming_media_re = re.compile("(?P<scheme>http)" | |
":\/\/" | |
"(?P<server>streaming\.media\.ccc\.de)" | |
"\/" | |
"(?P<room>.*)" | |
"\/.*") | |
def get_event_id(url): | |
page = requests.get(url) | |
match = re.search(r"{event_id:\s(?P<event_id>\d+),.*}", page.text) | |
try: | |
event_id = int(match.group('event_id')) | |
except: | |
raise PluginError("Failed to get event id from URL.") | |
return event_id | |
def get_api_json(api_url): | |
page = requests.get(api_url) | |
return page.text | |
def create_json_object(json_string): | |
try: | |
json_object = json.loads(json_string) | |
except: | |
raise PluginError("Could not parse json from API.") | |
return json_object | |
def parse_media_json(json_string): | |
json_object = create_json_object(json_string) | |
recordings = {} | |
for recording in json_object['recordings']: | |
match = re.search(r".*\/(?P<format>.*)", recording['mime_type']) | |
file_format = match.group('format') | |
if recording['mime_type'] == 'vnd.voc/mp4-web' or\ | |
recording['display_mime_type'] == 'video/webm': | |
continue | |
elif recording['mime_type'] == 'vnd.voc/h264-hd': | |
name = "1080p" | |
elif recording['mime_type'] == 'vnd.voc/h264-lq': | |
name = "420p" | |
elif re.match(r"audio", recording['display_mime_type']): | |
name = "audio_%s" % file_format | |
else: | |
if recording['hd'] == 'True': | |
name = "1080p" | |
else: | |
name = "420p" | |
recordings[name] = recording['recording_url'] | |
return recordings | |
def parse_streaming_media_json(json_string, room_from_url): | |
json_object = create_json_object(json_string) | |
streams = {} | |
for group in json_object: | |
for room in group['rooms']: | |
# only consider to requested room | |
match = _url_streaming_media_re.match(room['link']) | |
if not match.group('room') == room_from_url: | |
continue | |
for stream in room['streams']: | |
# get stream language | |
if stream['isTranslated'] == False: | |
language = 'native' | |
else: | |
language = 'translated' | |
# get hls stream urls | |
if 'hls' in stream['urls'].keys(): | |
stream_url = stream['urls']['hls']['url'] | |
name = None | |
# create stream hash | |
if language == 'native': | |
name = "%sp" % stream['videoSize'][-1] | |
long_name = "hls_%s_%sp" % ("native",\ | |
stream['videoSize'][-1]) | |
streams[name] = stream_url | |
streams[long_name] = stream_url | |
elif language == 'translated': | |
long_name = "hls_%s_%sp" % ("translated",\ | |
stream['videoSize'][-1]) | |
streams[long_name] = stream_url | |
# get audio only mpeg urls | |
if 'mp3' in stream['urls'].keys(): | |
stream_url = stream['urls']['mp3']['url'] | |
name = "audio_%s_mpeg" % language | |
streams[name] = stream_url | |
# get audio only mpeg urls | |
if 'opus' in stream['urls'].keys(): | |
stream_url = stream['urls']['opus']['url'] | |
name = "audio_%s_opus" % language | |
streams[name] = stream_url | |
return streams | |
class media_ccc_de(Plugin): | |
@classmethod | |
def can_handle_url(self, url): | |
return _url_media_re.search(url) or _url_streaming_media_re.search(url) | |
def _get_streams(self): | |
streams = {} | |
# streaming.media.ccc.de | |
match = _url_streaming_media_re.match(self.url) | |
if match: | |
query_url = API_URL_STREAMING_MEDIA | |
live_streams = parse_streaming_media_json(get_api_json(query_url),\ | |
match.group('room')) | |
for stream_name in live_streams.keys(): | |
if re.search(r"m3u8", live_streams[stream_name]): | |
try: | |
streams[stream_name] = HLSStream(self.session,\ | |
live_streams[stream_name]) | |
except IOError as err: | |
self.logger.warning("Failed to extract HLS streams: " | |
"{0}", err) | |
else: | |
streams[stream_name] = HTTPStream(self.session, live_streams[stream_name]) | |
# media.ccc.de | |
elif _url_media_re.search(self.url): | |
event_id = get_event_id(self.url) | |
query_url = "%s%i" % (API_URL_MEDIA, event_id) | |
recordings = parse_media_json(get_api_json(query_url)) | |
for name in recordings.keys(): | |
stream_url = recordings[name] | |
streams[name] = HTTPStream(self.session, stream_url) | |
if not streams: | |
raise PluginError("This plugin does not support your " | |
"selected video.") | |
return streams | |
__plugin__ = media_ccc_de |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment