From 14bedfc938d9cba043e6aa79e43a7ad16343164a Mon Sep 17 00:00:00 2001 From: Ashutosh Chaudhary <216.ashuttosh@gmail.com> Date: Thu, 3 Dec 2020 04:15:26 +0530 Subject: [PATCH 1/3] Added Mxplayer Fixed regex --- youtube_dl/extractor/extractors.py | 1 + youtube_dl/extractor/mxplayer.py | 101 +++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 youtube_dl/extractor/mxplayer.py diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 533c074b3..e5a65fe10 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -666,6 +666,7 @@ from .mtv import ( ) from .muenchentv import MuenchenTVIE from .mwave import MwaveIE, MwaveMeetGreetIE +from .mxplayer import MxplayerIE from .mychannels import MyChannelsIE from .myspace import MySpaceIE, MySpaceAlbumIE from .myspass import MySpassIE diff --git a/youtube_dl/extractor/mxplayer.py b/youtube_dl/extractor/mxplayer.py new file mode 100644 index 000000000..0fce7a978 --- /dev/null +++ b/youtube_dl/extractor/mxplayer.py @@ -0,0 +1,101 @@ +from __future__ import unicode_literals + +import re +from urllib.parse import urljoin +from .common import InfoExtractor +from ..utils import ( + url_or_none, js_to_json, ExtractorError) + + +# VALID_STREAMS = ('dash', 'hls', ) +VALID_STREAMS = ('dash', ) + +class MxplayerIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?mxplayer\.in/movie/(?P[a-z0-9]+(?:-[a-z0-9]+)*)' + # _VALID_URL = r'https?://(?:www\.)?mxplayer\.in/movie/(?P.*)[-](?P<id>.+)$' + _TEST = { + 'url': 'https://www.mxplayer.in/movie/watch-knock-knock-hindi-dubbed-movie-online-b9fa28df3bfb8758874735bbd7d2655a?watch=true', + 'info_dict': { + 'id': 'b9fa28df3bfb8758874735bbd7d2655a', + 'ext': 'mpd', + 'title': 'watch-knock-knock-hindi-dubbed-movie-online', + }, + 'params': { + 'skip_download': True, + 'format': 'bestvideo+bestaudio' + } + } + + def _get_best_stream_url(self, stream): + best_stream = list(filter(None, [v for k, v in stream.items()])) + return best_stream.pop(0) if len(best_stream) else None + + def _get_stream_urls(self, video_dict): + stream_dict = video_dict.get('stream', {'provider': {}}) + stream_provider = stream_dict.get('provider') + + if not stream_dict[stream_provider]: + message = 'No stream provider found' + raise ExtractorError('%s said: %s' % (self.IE_NAME, message), expected=True) + + streams = [] + for stream_name, v in stream_dict[stream_provider].items(): + if stream_name in VALID_STREAMS: + stream_url = self._get_best_stream_url(v) + if stream_url is None: + continue + streams.append((stream_name, stream_url)) + return streams + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_slug = mobj.group('slug') + + video_id = video_slug.split('-')[-1] + title = "-".join(video_slug.split("-")[:-1]) + + webpage = self._download_webpage(url, video_id) + + window_state_json = self._html_search_regex( + r'(?s)<script>window\.state\s*[:=]\s(\{.+\})\n(\w+).*(</script>).*', + webpage, 'WindowState') + + source = self._parse_json(js_to_json(window_state_json), video_id) + if not source: + message = 'source not found' + raise ExtractorError('%s said: %s' % (self.IE_NAME, message), expected=True) + + config_dict = source['config'] + video_dict = source['entities'][video_id] + stream_urls = self._get_stream_urls(video_dict) + + formats = [] + headers = {'Referer': url} + for stream_name, stream_url in stream_urls: + if stream_name == 'dash': + format_url = url_or_none(urljoin(config_dict['videoCdnBaseUrl'], stream_url)) + if not format_url: + continue + formats.extend(self._extract_mpd_formats( + format_url, video_id, mpd_id='dash', headers=headers)) + + self._sort_formats(formats) + info = { + 'id': video_id, + 'ext': 'mpd', + 'title': video_dict.get('title') or title, + 'description': video_dict.get('description'), + 'formats': formats + } + + if video_dict.get('imageInfo'): + info['thumbnails'] = list(map(lambda i: dict(i, **{ + 'url': urljoin(config_dict['imageBaseUrl'], i['url']) + }) , video_dict['imageInfo'])) + + if video_dict.get('webUrl'): + last_part = video_dict['webUrl'].split("/")[-1] + info['display_id'] = last_part.replace(video_id, "").rstrip("-") + + return info + From c2f08dd505145e7d8deb12c48525403d0220ea78 Mon Sep 17 00:00:00 2001 From: Ashutosh Chaudhary <216.ashutosh@gmail.com> Date: Sat, 12 Dec 2020 18:47:02 +0530 Subject: [PATCH 2/3] Fixed flake8 Search title from multiple sources --- youtube_dl/extractor/mxplayer.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/mxplayer.py b/youtube_dl/extractor/mxplayer.py index 0fce7a978..153b234b6 100644 --- a/youtube_dl/extractor/mxplayer.py +++ b/youtube_dl/extractor/mxplayer.py @@ -10,6 +10,7 @@ from ..utils import ( # VALID_STREAMS = ('dash', 'hls', ) VALID_STREAMS = ('dash', ) + class MxplayerIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?mxplayer\.in/movie/(?P<slug>[a-z0-9]+(?:-[a-z0-9]+)*)' # _VALID_URL = r'https?://(?:www\.)?mxplayer\.in/movie/(?P<title>.*)[-](?P<id>.+)$' @@ -69,6 +70,9 @@ class MxplayerIE(InfoExtractor): video_dict = source['entities'][video_id] stream_urls = self._get_stream_urls(video_dict) + if not title: + title = self._og_search_title(webpage, fatal=True, default=video_dict['title']) + formats = [] headers = {'Referer': url} for stream_name, stream_url in stream_urls: @@ -77,13 +81,13 @@ class MxplayerIE(InfoExtractor): if not format_url: continue formats.extend(self._extract_mpd_formats( - format_url, video_id, mpd_id='dash', headers=headers)) + format_url, video_id, mpd_id='dash', headers=headers)) self._sort_formats(formats) info = { 'id': video_id, 'ext': 'mpd', - 'title': video_dict.get('title') or title, + 'title': title, 'description': video_dict.get('description'), 'formats': formats } @@ -91,11 +95,10 @@ class MxplayerIE(InfoExtractor): if video_dict.get('imageInfo'): info['thumbnails'] = list(map(lambda i: dict(i, **{ 'url': urljoin(config_dict['imageBaseUrl'], i['url']) - }) , video_dict['imageInfo'])) + }), video_dict['imageInfo'])) if video_dict.get('webUrl'): last_part = video_dict['webUrl'].split("/")[-1] info['display_id'] = last_part.replace(video_id, "").rstrip("-") return info - From 2103cec4a5b3931c9a5d31dd9aed673773bba26e Mon Sep 17 00:00:00 2001 From: Ashutosh Chaudhary <216.ashutosh@gmail.com> Date: Sat, 12 Dec 2020 19:12:35 +0530 Subject: [PATCH 3/3] Fix: title from meta --- youtube_dl/extractor/mxplayer.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/youtube_dl/extractor/mxplayer.py b/youtube_dl/extractor/mxplayer.py index 153b234b6..1dffac36d 100644 --- a/youtube_dl/extractor/mxplayer.py +++ b/youtube_dl/extractor/mxplayer.py @@ -18,8 +18,8 @@ class MxplayerIE(InfoExtractor): 'url': 'https://www.mxplayer.in/movie/watch-knock-knock-hindi-dubbed-movie-online-b9fa28df3bfb8758874735bbd7d2655a?watch=true', 'info_dict': { 'id': 'b9fa28df3bfb8758874735bbd7d2655a', - 'ext': 'mpd', - 'title': 'watch-knock-knock-hindi-dubbed-movie-online', + 'ext': 'mp4', + 'title': 'Knock Knock Movie | Watch 2015 Knock Knock Full Movie Online- MX Player', }, 'params': { 'skip_download': True, @@ -53,7 +53,6 @@ class MxplayerIE(InfoExtractor): video_slug = mobj.group('slug') video_id = video_slug.split('-')[-1] - title = "-".join(video_slug.split("-")[:-1]) webpage = self._download_webpage(url, video_id) @@ -70,8 +69,7 @@ class MxplayerIE(InfoExtractor): video_dict = source['entities'][video_id] stream_urls = self._get_stream_urls(video_dict) - if not title: - title = self._og_search_title(webpage, fatal=True, default=video_dict['title']) + title = self._og_search_title(webpage, fatal=True, default=video_dict['title']) formats = [] headers = {'Referer': url}