aboutsummaryrefslogtreecommitdiffstats
path: root/hypervideo_dl/extractor/mediasite.py
diff options
context:
space:
mode:
Diffstat (limited to 'hypervideo_dl/extractor/mediasite.py')
-rw-r--r--hypervideo_dl/extractor/mediasite.py69
1 files changed, 60 insertions, 9 deletions
diff --git a/hypervideo_dl/extractor/mediasite.py b/hypervideo_dl/extractor/mediasite.py
index d6eb157..ace86c2 100644
--- a/hypervideo_dl/extractor/mediasite.py
+++ b/hypervideo_dl/extractor/mediasite.py
@@ -26,7 +26,7 @@ _ID_RE = r'(?:[0-9a-f]{32,34}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0
class MediasiteIE(InfoExtractor):
- _VALID_URL = r'(?xi)https?://[^/]+/Mediasite/(?:Play|Showcase/(?:default|livebroadcast)/Presentation)/(?P<id>%s)(?P<query>\?[^#]+|)' % _ID_RE
+ _VALID_URL = r'(?xi)https?://[^/]+/Mediasite/(?:Play|Showcase/[^/#?]+/Presentation)/(?P<id>%s)(?P<query>\?[^#]+|)' % _ID_RE
_TESTS = [
{
'url': 'https://hitsmediaweb.h-its.org/mediasite/Play/2db6c271681e4f199af3c60d1f82869b1d',
@@ -122,9 +122,55 @@ class MediasiteIE(InfoExtractor):
r'(?xi)<iframe\b[^>]+\bsrc=(["\'])(?P<url>(?:(?:https?:)?//[^/]+)?/Mediasite/Play/%s(?:\?.*?)?)\1' % _ID_RE,
webpage)]
+ def __extract_slides(self, *, stream_id, snum, Stream, duration, images):
+ slide_base_url = Stream['SlideBaseUrl']
+
+ fname_template = Stream['SlideImageFileNameTemplate']
+ if fname_template != 'slide_{0:D4}.jpg':
+ self.report_warning('Unusual slide file name template; report a bug if slide downloading fails')
+ fname_template = re.sub(r'\{0:D([0-9]+)\}', r'{0:0\1}', fname_template)
+
+ fragments = []
+ for i, slide in enumerate(Stream['Slides']):
+ if i == 0:
+ if slide['Time'] > 0:
+ default_slide = images.get('DefaultSlide')
+ if default_slide is None:
+ default_slide = images.get('DefaultStreamImage')
+ if default_slide is not None:
+ default_slide = default_slide['ImageFilename']
+ if default_slide is not None:
+ fragments.append({
+ 'path': default_slide,
+ 'duration': slide['Time'] / 1000,
+ })
+
+ next_time = try_get(None, [
+ lambda _: Stream['Slides'][i + 1]['Time'],
+ lambda _: duration,
+ lambda _: slide['Time'],
+ ], expected_type=(int, float))
+
+ fragments.append({
+ 'path': fname_template.format(slide.get('Number', i + 1)),
+ 'duration': (next_time - slide['Time']) / 1000
+ })
+
+ return {
+ 'format_id': '%s-%u.slides' % (stream_id, snum),
+ 'ext': 'mhtml',
+ 'url': slide_base_url,
+ 'protocol': 'mhtml',
+ 'acodec': 'none',
+ 'vcodec': 'none',
+ 'format_note': 'Slides',
+ 'fragments': fragments,
+ 'fragment_base_url': slide_base_url,
+ }
+
def _real_extract(self, url):
url, data = unsmuggle_url(url, {})
- mobj = re.match(self._VALID_URL, url)
+ mobj = self._match_valid_url(url)
resource_id = mobj.group('id')
query = mobj.group('query')
@@ -198,15 +244,20 @@ class MediasiteIE(InfoExtractor):
'ext': mimetype2ext(VideoUrl.get('MimeType')),
})
- # TODO: if Stream['HasSlideContent']:
- # synthesise an MJPEG video stream '%s-%u.slides' % (stream_type, snum)
- # from Stream['Slides']
- # this will require writing a custom downloader...
+ if Stream.get('HasSlideContent', False):
+ images = player_options['PlayerLayoutOptions']['Images']
+ stream_formats.append(self.__extract_slides(
+ stream_id=stream_id,
+ snum=snum,
+ Stream=Stream,
+ duration=presentation.get('Duration'),
+ images=images,
+ ))
# disprefer 'secondary' streams
if stream_type != 0:
for fmt in stream_formats:
- fmt['preference'] = -1
+ fmt['quality'] = -10
thumbnail_url = Stream.get('ThumbnailUrl')
if thumbnail_url:
@@ -276,7 +327,7 @@ class MediasiteCatalogIE(InfoExtractor):
}]
def _real_extract(self, url):
- mobj = re.match(self._VALID_URL, url)
+ mobj = self._match_valid_url(url)
mediasite_url = mobj.group('url')
catalog_id = mobj.group('catalog_id')
current_folder_id = mobj.group('current_folder_id') or catalog_id
@@ -352,7 +403,7 @@ class MediasiteNamedCatalogIE(InfoExtractor):
}]
def _real_extract(self, url):
- mobj = re.match(self._VALID_URL, url)
+ mobj = self._match_valid_url(url)
mediasite_url = mobj.group('url')
catalog_name = mobj.group('catalog_name')