From a59f77ebabc3ed4d7f6f2d0a43ba687ed0c76ef4 Mon Sep 17 00:00:00 2001
From: tabjy <kxu@tabjy.com>
Date: Sun, 2 Oct 2022 05:26:06 -0400
Subject: [PATCH] [VXXX] Support "friend" site: bdsmx.tube

---
 youtube_dl/extractor/bdsmxtube.py  | 39 ++++++++++++++++++++++++++++++
 youtube_dl/extractor/extractors.py |  1 +
 youtube_dl/extractor/vxxx.py       | 16 ++++++------
 3 files changed, 47 insertions(+), 9 deletions(-)
 create mode 100644 youtube_dl/extractor/bdsmxtube.py

diff --git a/youtube_dl/extractor/bdsmxtube.py b/youtube_dl/extractor/bdsmxtube.py
new file mode 100644
index 000000000..a7c5299ed
--- /dev/null
+++ b/youtube_dl/extractor/bdsmxtube.py
@@ -0,0 +1,39 @@
+from .vxxx import VXXXIE
+
+
+class BdsmxTubeIE(VXXXIE):
+    _VALID_URL = r'https?://bdsmx\.tube/video/(?P<id>\d+)'
+    _TESTS = [{
+        'url': 'https://bdsmx.tube/video/127583/latex-puppy-leashed/',
+        'md5': '06b6000c19207cb068bc0009f243345d',
+        'info_dict': {
+            'id': '127583',
+            'ext': 'mp4',
+            'title': 'Latex Puppy Leashed',
+            'display_id': 'latex-puppy-leashed',
+            'thumbnail': 'https://tn.bdsmx-porn.com/contents/videos_screenshots/127000/127583/480x270/1.jpg',
+            'description': '',
+            'timestamp': 1651003323,
+            'upload_date': '20220426',
+            'duration': 68.0,
+            'categories': ['Asian', 'Brunette', 'Cosplay', 'Fetish',
+                           'Fuck Machine', 'Gagging', 'Japanese',
+                           'JAV Uncensored', 'Latex', 'Leather', 'POV']}
+    }]
+
+    def _download_info_object(self, video_id):
+        return self._download_json(
+            'https://bdsmx.tube/api/json/video/86400/0/{}/{}.json'.format(
+                int(video_id) // 1000 * 1000,
+                video_id,
+            ), video_id, headers={'Referer': 'https://bdsmx.tube'})['video']
+
+    def _download_format_object(self, video_id):
+        return self._download_json(
+            'https://bdsmx.tube/api/videofile.php?video_id={}'.format(video_id),
+            video_id,
+            headers={'Referer': 'https://bdsmx.tube'}
+        )
+
+    def _get_video_host(self):
+        return 'bdsmx.tube'
diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py
index a567225a5..3eb9a11c8 100644
--- a/youtube_dl/extractor/extractors.py
+++ b/youtube_dl/extractor/extractors.py
@@ -106,6 +106,7 @@ from .bbc import (
     BBCCoUkPlaylistIE,
     BBCIE,
 )
+from .bdsmxtube import BdsmxTubeIE
 from .beeg import BeegIE
 from .behindkink import BehindKinkIE
 from .bellmedia import BellMediaIE
diff --git a/youtube_dl/extractor/vxxx.py b/youtube_dl/extractor/vxxx.py
index 6d7dc7bc6..bcde6555f 100644
--- a/youtube_dl/extractor/vxxx.py
+++ b/youtube_dl/extractor/vxxx.py
@@ -23,10 +23,6 @@ class VXXXIE(InfoExtractor):
             'timestamp': 1607167706,
             'upload_date': '20201205',
             'duration': 2373.0,
-            'view_count': 1071,
-            'like_count': 1,
-            'dislike_count': 0,
-            'average_rating': 5.0,
             'categories': ['Anal', 'Asian', 'BDSM', 'Brunette', 'Toys',
                            'Fetish', 'HD', 'Interracial', 'MILF'],
         }}]
@@ -50,8 +46,8 @@ class VXXXIE(InfoExtractor):
 
     def _decode_base164(self, e):
         """
-        Some non-standard encoding called "base164" in the JavaScript code. It
-        is similar to base 64 with some alphabets replaced:
+        Some non-standard encoding called "base164" in the JavaScript code. It's
+        similar to the regular base64 with a slightly different alphabet:
             - "АВСЕМ" are Cyrillic letters instead of uppercase English letters
             - "." is used instead of "+"; "," is used instead of "/"
             - "~" is used for padding instead of "="
@@ -91,9 +87,11 @@ class VXXXIE(InfoExtractor):
         }
 
         qualities = {
-            '_fhd.mp4': -1,
-            '_hd.mp4': -2,
-            '_sd.mp4': -3
+            '_fhd.mp4': -1,  # 1080p
+            '_hd.mp4': -2,   # 720p
+            '_hq.mp4': -2,   # 720p
+            '_sd.mp4': -3,   # 480p
+            '_lq.mp4': -3    # 480p
         }
 
         format_object = self._download_format_object(video_id)