aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yt_dlp/extractor/_extractors.py1
-rw-r--r--yt_dlp/extractor/mixch.py57
2 files changed, 56 insertions, 2 deletions
diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py
index 0b935fe3a..51caefd4d 100644
--- a/yt_dlp/extractor/_extractors.py
+++ b/yt_dlp/extractor/_extractors.py
@@ -1156,6 +1156,7 @@ from .mitele import MiTeleIE
from .mixch import (
MixchArchiveIE,
MixchIE,
+ MixchMovieIE,
)
from .mixcloud import (
MixcloudIE,
diff --git a/yt_dlp/extractor/mixch.py b/yt_dlp/extractor/mixch.py
index 7832784b2..4bccc81bd 100644
--- a/yt_dlp/extractor/mixch.py
+++ b/yt_dlp/extractor/mixch.py
@@ -12,7 +12,7 @@ from ..utils.traversal import traverse_obj
class MixchIE(InfoExtractor):
IE_NAME = 'mixch'
- _VALID_URL = r'https?://(?:www\.)?mixch\.tv/u/(?P<id>\d+)'
+ _VALID_URL = r'https?://mixch\.tv/u/(?P<id>\d+)'
_TESTS = [{
'url': 'https://mixch.tv/u/16943797/live',
@@ -74,7 +74,7 @@ class MixchIE(InfoExtractor):
class MixchArchiveIE(InfoExtractor):
IE_NAME = 'mixch:archive'
- _VALID_URL = r'https?://(?:www\.)?mixch\.tv/archive/(?P<id>\d+)'
+ _VALID_URL = r'https?://mixch\.tv/archive/(?P<id>\d+)'
_TESTS = [{
'url': 'https://mixch.tv/archive/421',
@@ -116,3 +116,56 @@ class MixchArchiveIE(InfoExtractor):
'formats': self._extract_m3u8_formats(info_json['archiveURL'], video_id),
'thumbnail': traverse_obj(info_json, ('thumbnailURL', {url_or_none})),
}
+
+
+class MixchMovieIE(InfoExtractor):
+ IE_NAME = 'mixch:movie'
+ _VALID_URL = r'https?://mixch\.tv/m/(?P<id>\w+)'
+
+ _TESTS = [{
+ 'url': 'https://mixch.tv/m/Ve8KNkJ5',
+ 'info_dict': {
+ 'id': 'Ve8KNkJ5',
+ 'title': '夏☀️\nムービーへのポイントは本イベントに加算されないので配信にてお願い致します🙇🏻\u200d♀️\n#TGCCAMPUS #ミス東大 #ミス東大2024 ',
+ 'ext': 'mp4',
+ 'uploader': 'ミス東大No.5 松藤百香🍑💫',
+ 'uploader_id': '12299174',
+ 'channel_follower_count': int,
+ 'view_count': int,
+ 'like_count': int,
+ 'comment_count': int,
+ 'timestamp': 1724070828,
+ 'uploader_url': 'https://mixch.tv/u/12299174',
+ 'live_status': 'not_live',
+ 'upload_date': '20240819',
+ },
+ }, {
+ 'url': 'https://mixch.tv/m/61DzpIKE',
+ 'only_matching': True,
+ }]
+
+ def _real_extract(self, url):
+ video_id = self._match_id(url)
+ data = self._download_json(
+ f'https://mixch.tv/api-web/movies/{video_id}', video_id)
+ return {
+ 'id': video_id,
+ 'formats': [{
+ 'format_id': 'mp4',
+ 'url': data['movie']['file'],
+ 'ext': 'mp4',
+ }],
+ **traverse_obj(data, {
+ 'title': ('movie', 'title', {str}),
+ 'thumbnail': ('movie', 'thumbnailURL', {url_or_none}),
+ 'uploader': ('ownerInfo', 'name', {str}),
+ 'uploader_id': ('ownerInfo', 'id', {int}, {str_or_none}),
+ 'channel_follower_count': ('ownerInfo', 'fan', {int_or_none}),
+ 'view_count': ('ownerInfo', 'view', {int_or_none}),
+ 'like_count': ('movie', 'favCount', {int_or_none}),
+ 'comment_count': ('movie', 'commentCount', {int_or_none}),
+ 'timestamp': ('movie', 'published', {int_or_none}),
+ 'uploader_url': ('ownerInfo', 'id', {lambda x: x and f'https://mixch.tv/u/{x}'}, filter),
+ }),
+ 'live_status': 'not_live',
+ }