From 951aa74cbeb08a4220e265e769a263dcedf46282 Mon Sep 17 00:00:00 2001 From: nomevi <108267441+nomevi@users.noreply.github.com> Date: Mon, 27 Jun 2022 13:58:07 +0200 Subject: [PATCH] [livestreamfails] Add new extractor --- youtube_dl/extractor/extractors.py | 3 ++ youtube_dl/extractor/livestreamfails.py | 49 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 youtube_dl/extractor/livestreamfails.py diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 751fc38b6..c01461f54 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -627,6 +627,9 @@ from .livestream import ( LivestreamOriginalIE, LivestreamShortenerIE, ) +from .livestreamfails import ( + LivestreamfailsIE, +) from .lnkgo import LnkGoIE from .localnews8 import LocalNews8IE from .lovehomeporn import LoveHomePornIE diff --git a/youtube_dl/extractor/livestreamfails.py b/youtube_dl/extractor/livestreamfails.py new file mode 100644 index 000000000..b92eca047 --- /dev/null +++ b/youtube_dl/extractor/livestreamfails.py @@ -0,0 +1,49 @@ +from .common import InfoExtractor +import json +import time +import calendar + + +class LivestreamfailsIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?livestreamfails\.com/clip/(?P[0-9]+)' + _TESTS = [{ + 'url': 'https://livestreamfails.com/clip/139200', + 'md5': '8a03aea1a46e94a05af6410337463102', + 'info_dict': { + 'id': '139200', + 'ext': 'mp4', + 'display_id': 'ConcernedLitigiousSalmonPeteZaroll-O8yo9W2L8OZEKhV2', + 'title': 'Streamer jumps off a trampoline at full speed', + 'creator': 'paradeev1ch', + 'thumbnail': 'https://livestreamfails-image-prod.b-cdn.net/image/3877b1d38db083fa25c82685bbaf645637e575ea.png', + 'timestamp': 1656271785, + 'upload_date': '20220626', + } + }] + + def _real_extract(self, url): + result = {} + result['id'] = self._match_id(url) + + # https://livestreamfails.com/clip/id uses https://api.livestreamfails.com/clip/ to fetch the video metadata + # Use the same endpoint here to avoid loading and parsing the provided page (which requires JS) + apiResponse = json.loads(self._download_webpage('https://api.livestreamfails.com/clip/' + result['id'], result['id'])) + + # Twitch ID of clip + result['display_id'] = apiResponse.get('sourceId') + + # Get the input timestamp (test case gives 2022-06-26T19:29:45.515Z) + result['timestamp'] = apiResponse.get('createdAt') + if(result.get('timestamp')): + # Parse it into a struct_time + result['timestamp'] = time.strptime(result['timestamp'], '%Y-%m-%dT%H:%M:%S.%fZ') + # Convert the struct_time to a UNIX timestamp while ignoring the local timezone attached by time.strptime() + result['timestamp'] = calendar.timegm(result['timestamp']) + + # Other fields + result['url'] = 'https://livestreamfails-video-prod.b-cdn.net/video/' + apiResponse.get('videoId') + result['title'] = apiResponse.get('label') + result['creator'] = apiResponse.get('streamer', {}).get('label') + result['thumbnail'] = 'https://livestreamfails-image-prod.b-cdn.net/image/' + apiResponse.get('imageId') + + return result