Skip to content

Instantly share code, notes, and snippets.

@meise
Forked from MaZderMind/media_ccc_de.py
Last active August 29, 2015 14:18
Show Gist options
  • Save meise/3616d171acdbdc281eed to your computer and use it in GitHub Desktop.
Save meise/3616d171acdbdc281eed to your computer and use it in GitHub Desktop.
"""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