Repository: yt-dlp/yt-dlp

Issue:
Truth Social
### Checklist

- [X] I'm reporting a new site support request
- [X] I've verified that I'm running yt-dlp version **2022.05.18** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)
- [X] I've checked that all provided URLs are playable in a browser with the same IP and same login details
- [X] I've checked that none of provided URLs [violate any copyrights](https://github.com/ytdl-org/youtube-dl#can-you-add-support-for-this-anime-video-site-or-site-which-shows-current-movies-for-free) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge
- [X] I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues including closed ones. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)
- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and am willing to share it if required

### Region

US

### Example URLs

- Single video: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
- Single video: https://truthsocial.com/@RichSementa/posts/108360011206463048
- Single video: https://truthsocial.com/@KarliBonne/108360308038198927
- Single video: https://truthsocial.com/@TheBeauShow/108359711461231741
- Single video: https://truthsocial.com/@steveinman/108360194781589187
- Single video: https://truthsocial.com/@OAN/108360347038764470
- Single video: https://truthsocial.com/@benny/108357875998831094
- Single video: https://truthsocial.com/@crossroads_josh/108354271636352025
- Single video: https://truthsocial.com/@Kanekoa/108358740797291197
- Single video: https://truthsocial.com/@DevinNunes/108357404310489110
- Single video: https://truthsocial.com/@steveinman/108358989218963312
- Single video: https://truthsocial.com/@intheMatrixxx/108360102617518953
- Single video: https://truthsocial.com/@laralogan/108359772245937961
- Playlist: https://truthsocial.com/@steveinman

### Description

A new social network similar to twitter and based on mastodon I believe. Videos use rumble as a backend and they can be downloaded by using the video source link in yt-dlp, but going to the url in a browser shows it as private.

for example, this truth
[https://truthsocial.com/@realDonaldTrump/posts/108346966451100254](https://truthsocial.com/@realDonaldTrump/posts/108346966451100254) 
links to this video (which is marked as private and is not downloadable)
[https://rumble.com/v15p7on-video-upload-for-108346966451100254.html](https://rumble.com/v15p7on-video-upload-for-108346966451100254.html)
but can be downloaded with yt-dlp using the video source url
[https://sp.rmbl.ws/s8/2/N/W/l/l/NWlle.caa.mp4?u=0&b=0](https://sp.rmbl.ws/s8/2/N/W/l/l/NWlle.caa.mp4?u=0&b=0)

### Verbose log

```shell
yt-dlp -vU https://truthsocial.com/@realDonaldTrump/108346966451100254
[debug] Command-line config: ['-vU', 'https://truthsocial.com/@realDonaldTrump/108346966451100254']
[debug] User config "/Users/me/.config/yt-dlp/config": ['--cookies-from-browser', 'firefox', '--cache-dir', '/Users/me/.config/youtube-dl/', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:85.0) Gecko/20100101 Firefox/85.0', '--geo-bypass', '-u', 'PRIVATE', '-p', 'PRIVATE', '-i', '--no-mark-watched', '--no-warnings', '--retries', 'infinite', '--fragment-retries', 'infinite', '--download-archive', '/Users/me/.config/youtube-dl/downloads.txt', '-o', '/Volumes/Movies/Youtubes/%(uploader)s/%(playlist_title)s/%(upload_date)s - %(title)s.%(ext)s', '-f', 'bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a][abr<=192]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best', '--sub-format', 'srt', '--convert-subs', 'srt', '--write-subs', '--write-auto-subs', '--embed-subs', '--compat-options', 'no-keep-subs', '--sub-lang', 'en,ja', '--embed-thumbnail', '--parse-metadata', 'channel:%(meta_artist)s', '--parse-metadata', 'webpage_url:%(meta_comment)s', '--parse-metadata', 'upload_date:%(meta_date>%Y:%m:%d)s', '--embed-metadata', '--embed-chapters', '--xattrs', '--audio-format', 'm4a', '--recode-video', 'mp4', '--match-filter', 'duration >=?60 & !is_live']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version 2022.05.18 [b14d52355]
[debug] Compatibility options: no-keep-subs
[debug] Python version 3.10.4 (CPython 64bit) - macOS-12.4-arm64-arm-64bit
[debug] Checking exe version: ffprobe -bsfs
[debug] Checking exe version: ffmpeg -bsfs
[debug] exe versions: ffmpeg 5.0.1 (setts), ffprobe 5.0.1
[debug] Optional libraries: Cryptodome-3.14.1, brotli-1.0.9, certifi-2021.10.08, mutagen-1.45.1, sqlite3-2.6.0, websockets-10.3
[Cookies] Extracting cookies from firefox
[debug] Extracting cookies from: "/Users/me/Library/Application Support/Firefox/Profiles/xy4v0sei.default-release-1574345941647/cookies.sqlite"
[Cookies] Extracted 799 cookies from firefox
[debug] Proxy map: {}
[debug] Loading archive file '/Users/me/.config/youtube-dl/downloads.txt'
Latest version: 2022.05.18, Current version: 2022.05.18
yt-dlp is up to date (2022.05.18)
[debug] [generic] Extracting URL: https://truthsocial.com/@realDonaldTrump/108346966451100254
[generic] 108346966451100254: Requesting header
[generic] 108346966451100254: Downloading webpage
[generic] 108346966451100254: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://truthsocial.com/@realDonaldTrump/108346966451100254
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/yt-dlp/2022.5.18/libexec/lib/python3.10/site-packages/yt_dlp/YoutubeDL.py", line 1395, in wrapper
    return func(self, *args, **kwargs)
  File "/opt/homebrew/Cellar/yt-dlp/2022.5.18/libexec/lib/python3.10/site-packages/yt_dlp/YoutubeDL.py", line 1465, in __extract_info
    ie_result = ie.extract(url)
  File "/opt/homebrew/Cellar/yt-dlp/2022.5.18/libexec/lib/python3.10/site-packages/yt_dlp/extractor/common.py", line 642, in extract
    ie_result = self._real_extract(url)
  File "/opt/homebrew/Cellar/yt-dlp/2022.5.18/libexec/lib/python3.10/site-packages/yt_dlp/extractor/generic.py", line 4031, in _real_extract
    raise UnsupportedError(url)
yt_dlp.utils.UnsupportedError: Unsupported URL: https://truthsocial.com/@realDonaldTrump/108346966451100254
```



Discussion:
![image](https://user-images.githubusercontent.com/6623388/170252718-9a41e45b-9712-4b7b-9700-a86814557fad.png)
geo-restriction?
truthsocial.com is currently geo-restricted to the US and possibly Canada because it's a new service, but I believe it will open up worldwide shortly. I have no problem accessing it through a VPN from Asia.
@Adam-0-Moore Can you please test it using https://github.com/ytdl-patched/ytdl-patched, and send a verbose log of the results. Please note that ytdl-patched is an unofficial yt-dlp fork, so, whilst I personally do trust ytdl-patched, it's up to you whether you are comfortable installing it on your computer.

Please don't close this issue, even if the download works on ytdl-patched.

NOTE: I would advise against replacing yt-dlp with ytdl-patched, because, unlike yt-dlp, ytdl-patched isn't supposed to be stable at all. After features are tested on ytdl-patched, they are usually ported over to yt-dlp

PS: if you get an unsupported url error on ytdl-patched, please attempt it again with `--check-mastodon-instance` and send the results
@gamer191 Sure thing - here is the log with ytdl-patched:

```/Users/me/Downloads/ytdl-patched -Uv https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[debug] Command-line config: ['-Uv', 'https://truthsocial.com/@realDonaldTrump/posts/108346966451100254']
[debug] User config "/Users/me/.config/yt-dlp/config": ['--cookies-from-browser', 'firefox', '--cache-dir', '/Users/me/.config/youtube-dl/', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:85.0) Gecko/20100101 Firefox/85.0', '--geo-bypass', '-u', 'PRIVATE', '-p', 'PRIVATE', '-i', '--no-mark-watched', '--no-warnings', '--retries', 'infinite', '--fragment-retries', 'infinite', '--download-archive', '/Users/me/.config/youtube-dl/downloads.txt', '-o', '/Volumes/Movies/Youtubes/%(uploader)s/%(playlist_title)s/%(upload_date)s - %(title)s.%(ext)s', '-f', 'bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a][abr<=192]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best', '--sub-format', 'srt', '--convert-subs', 'srt', '--write-subs', '--write-auto-subs', '--embed-subs', '--compat-options', 'no-keep-subs', '--sub-lang', 'en,ja', '--embed-thumbnail', '--parse-metadata', 'channel:%(meta_artist)s', '--parse-metadata', 'webpage_url:%(meta_comment)s', '--parse-metadata', 'upload_date:%(meta_date>%Y:%m:%d)s', '--embed-metadata', '--embed-chapters', '--xattrs', '--audio-format', 'm4a', '--recode-video', 'mp4', '--match-filter', 'duration >=?60 & !is_live']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] ytdl-patched version 2022.05.24.1653412459  (zip)
[debug]      from commit e781a188a
[debug]      based on 7879e79d1
[debug] ** The command you are running is not yt-dlp.
[debug] ** Please make bug reports at https://github.com/ytdl-patched/ytdl-patched/issues/new/choose instead.
[debug] Lazy loading extractors is disabled
[debug] Compatibility options: no-keep-subs
[debug] Python version 3.10.4 (CPython 64bit) - macOS-12.4-arm64-arm-64bit
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg 5.0.1 (setts), ffprobe 5.0.1
[debug] Optional libraries: certifi-2022.05.18.1, sqlite3-2.6.0
[Cookies] Extracting cookies from firefox
[debug] Extracting cookies from: "/Users/me/Library/Application Support/Firefox/Profiles/xy4v0sei.default-release-1574345941647/cookies.sqlite"
[Cookies] Extracted 797 cookies from firefox
[debug] Proxy map: {}
[debug] Loading archive file '/Users/me/.config/youtube-dl/downloads.txt'
Latest version: 2022.05.24.1653412459, Current version: 2022.05.24.1653412459
ytdl-patched is up to date (2022.05.24.1653412459)
[debug] [generic] Extracting URL: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[generic] 108346966451100254: Requesting header
[generic] [debug] Fetching webpage from https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[generic] 108346966451100254: Downloading webpage
[generic] [debug] Fetching webpage from https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[generic] 108346966451100254: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
Traceback (most recent call last):
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/YoutubeDL.py", line 1458, in wrapper
    return func(self, *args, **kwargs)
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/YoutubeDL.py", line 1538, in __extract_info
    ie_result = ie.extract(url)
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/extractor/common.py", line 673, in extract
    ie_result = self._real_extract(url)
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/extractor/generic.py", line 4148, in _real_extract
    raise UnsupportedError(url)
yt_dlp.utils.UnsupportedError: Unsupported URL: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254

[debug] Cleaning up 1 streams
```
@gamer191 and here is with "--check-mastodon-instance"

```/Users/me/Downloads/ytdl-patched -Uv --check-mastodon-instance https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[debug] Command-line config: ['-Uv', '--check-mastodon-instance', 'https://truthsocial.com/@realDonaldTrump/posts/108346966451100254']
[debug] User config "/Users/me/.config/yt-dlp/config": ['--cookies-from-browser', 'firefox', '--cache-dir', '/Users/me/.config/youtube-dl/', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:85.0) Gecko/20100101 Firefox/85.0', '--geo-bypass', '-u', 'PRIVATE', '-p', 'PRIVATE', '-i', '--no-mark-watched', '--no-warnings', '--retries', 'infinite', '--fragment-retries', 'infinite', '--download-archive', '/Users/me/.config/youtube-dl/downloads.txt', '-o', '/Volumes/Movies/Youtubes/%(uploader)s/%(playlist_title)s/%(upload_date)s - %(title)s.%(ext)s', '-f', 'bestvideo[ext=mp4][height<=1080]+bestaudio[ext=m4a][abr<=192]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best', '--sub-format', 'srt', '--convert-subs', 'srt', '--write-subs', '--write-auto-subs', '--embed-subs', '--compat-options', 'no-keep-subs', '--sub-lang', 'en,ja', '--embed-thumbnail', '--parse-metadata', 'channel:%(meta_artist)s', '--parse-metadata', 'webpage_url:%(meta_comment)s', '--parse-metadata', 'upload_date:%(meta_date>%Y:%m:%d)s', '--embed-metadata', '--embed-chapters', '--xattrs', '--audio-format', 'm4a', '--recode-video', 'mp4', '--match-filter', 'duration >=?60 & !is_live']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] ytdl-patched version 2022.05.24.1653412459  (zip)
[debug]      from commit e781a188a
[debug]      based on 7879e79d1
[debug] ** The command you are running is not yt-dlp.
[debug] ** Please make bug reports at https://github.com/ytdl-patched/ytdl-patched/issues/new/choose instead.
[debug] Lazy loading extractors is disabled
[debug] Compatibility options: no-keep-subs
[debug] Python version 3.10.4 (CPython 64bit) - macOS-12.4-arm64-arm-64bit
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg 5.0.1 (setts), ffprobe 5.0.1
[debug] Optional libraries: certifi-2022.05.18.1, sqlite3-2.6.0
[Cookies] Extracting cookies from firefox
[debug] Extracting cookies from: "/Users/me/Library/Application Support/Firefox/Profiles/xy4v0sei.default-release-1574345941647/cookies.sqlite"
[Cookies] Extracted 797 cookies from firefox
[debug] Proxy map: {}
[debug] Loading archive file '/Users/me/.config/youtube-dl/downloads.txt'
Latest version: 2022.05.24.1653412459, Current version: 2022.05.24.1653412459
ytdl-patched is up to date (2022.05.24.1653412459)
[debug] [generic] Extracting URL: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[generic] 108346966451100254: Requesting header
[generic] [debug] Fetching webpage from https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[generic] 108346966451100254: Downloading webpage
[generic] [debug] Fetching webpage from https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
[generic] truthsocial.com: Downloading instance nodeinfo link
[generic] [debug] Fetching webpage from https://truthsocial.com/.well-known/nodeinfo
[generic] truthsocial.com: Downloading instance nodeinfo link
[generic] [debug] Fetching webpage from https://truthsocial.com/.well-known/nodeinfo
[generic] truthsocial.com: Downloading instance nodeinfo link
[generic] [debug] Fetching webpage from https://truthsocial.com/.well-known/nodeinfo
[generic] 108346966451100254: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254
Traceback (most recent call last):
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/YoutubeDL.py", line 1458, in wrapper
    return func(self, *args, **kwargs)
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/YoutubeDL.py", line 1538, in __extract_info
    ie_result = ie.extract(url)
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/extractor/common.py", line 673, in extract
    ie_result = self._real_extract(url)
  File "/Users/me/Downloads/ytdl-patched/yt_dlp/extractor/generic.py", line 4148, in _real_extract
    raise UnsupportedError(url)
yt_dlp.utils.UnsupportedError: Unsupported URL: https://truthsocial.com/@realDonaldTrump/posts/108346966451100254

[debug] Cleaning up 1 streams
```
Can you please try opening `https://truthsocial.com/.well-known/nodeinfo` in browser and paste what you see here? It's okay to be text or screenshot.

P.S. please use three graves (```) around logs so that we can see it easily
![Screenshot](https://user-images.githubusercontent.com/482367/170278976-67f0a044-7d85-4cee-a5ae-fd8909cdefe9.png)
~~Looks like it needs a separate extractor for that...~~ Manually whitelisting may work? (like I did for Gab)
If anyone's wondering, truth social is a fork of Mastodon, and it's source code is available [here](https://truthsocial.com/open-source/) (US only, not available through Tor Browser)

Here's an unofficial mirror (which I haven't verified) for people outside the US, or people who want to view it as a Git repo instead of a zip file: https://github.com/justjosias/truth-social
EDIT: I just realised that that repo is 3 months out of date
Actually, if you need a mirror, [this unofficial mirror](https://github.com/milesmcc/truthsocial) is automatically updated hourly

Resolving patch:
diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py
--- a/yt_dlp/extractor/_extractors.py
+++ b/yt_dlp/extractor/_extractors.py
@@ -1792,6 +1792,7 @@
 )
 from .trueid import TrueIDIE
 from .trunews import TruNewsIE
+from .truth import TruthIE
 from .trutv import TruTVIE
 from .tube8 import Tube8IE
 from .tubetugraz import TubeTuGrazIE, TubeTuGrazSeriesIE
diff --git a/yt_dlp/extractor/truth.py b/yt_dlp/extractor/truth.py
new file mode 100644
--- /dev/null
+++ b/yt_dlp/extractor/truth.py
@@ -0,0 +1,69 @@
+from .common import InfoExtractor
+from ..utils import (
+    clean_html,
+    format_field,
+    int_or_none,
+    strip_or_none,
+    traverse_obj,
+    unified_timestamp,
+)
+
+
+class TruthIE(InfoExtractor):
+    _VALID_URL = r'https?://truthsocial\.com/@[^/]+/posts/(?P<id>\d+)'
+    _TESTS = [
+        {
+            'url': 'https://truthsocial.com/@realDonaldTrump/posts/108779000807761862',
+            'md5': '4a5fb1470c192e493d9efd6f19e514d3',
+            'info_dict': {
+                'id': '108779000807761862',
+                'ext': 'qt',
+                'title': 'Truth video #108779000807761862',
+                'description': None,
+                'timestamp': 1659835827,
+                'upload_date': '20220807',
+                'uploader': 'Donald J. Trump',
+                'uploader_id': 'realDonaldTrump',
+                'uploader_url': 'https://truthsocial.com/@realDonaldTrump',
+                'repost_count': int,
+                'comment_count': int,
+                'like_count': int,
+            },
+        },
+        {
+            'url': 'https://truthsocial.com/@ProjectVeritasAction/posts/108618228543962049',
+            'md5': 'fd47ba68933f9dce27accc52275be9c3',
+            'info_dict': {
+                'id': '108618228543962049',
+                'ext': 'mp4',
+                'title': 'md5:debde7186cf83f60ff7b44dbb9444e35',
+                'description': 'md5:de2fc49045bf92bb8dc97e56503b150f',
+                'timestamp': 1657382637,
+                'upload_date': '20220709',
+                'uploader': 'Project Veritas Action',
+                'uploader_id': 'ProjectVeritasAction',
+                'uploader_url': 'https://truthsocial.com/@ProjectVeritasAction',
+                'repost_count': int,
+                'comment_count': int,
+                'like_count': int,
+            },
+        },
+    ]
+
+    def _real_extract(self, url):
+        video_id = self._match_id(url)
+        status = self._download_json(f'https://truthsocial.com/api/v1/statuses/{video_id}', video_id)
+        uploader_id = strip_or_none(traverse_obj(status, ('account', 'username')))
+        return {
+            'id': video_id,
+            'url': status['media_attachments'][0]['url'],
+            'title': '',
+            'description': strip_or_none(clean_html(status.get('content'))) or None,
+            'timestamp': unified_timestamp(status.get('created_at')),
+            'uploader': strip_or_none(traverse_obj(status, ('account', 'display_name'))),
+            'uploader_id': uploader_id,
+            'uploader_url': format_field(uploader_id, None, 'https://truthsocial.com/@%s'),
+            'repost_count': int_or_none(status.get('reblogs_count')),
+            'like_count': int_or_none(status.get('favourites_count')),
+            'comment_count': int_or_none(status.get('replies_count')),
+        }


Test patch: