Repository: yt-dlp/yt-dlp

Issue:
Facebook "reel" support
### 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

_No response_

### Example URLs

https://www.facebook.com/reel/1195289147628387
https://www.facebook.com/reel/522098049695565
https://www.facebook.com/reel/422980049829939
https://www.facebook.com/reel/790250902360374
https://www.facebook.com/reel/1056059878651934

### Description

Looks like Facebook has a new video option, as the URL indicates "reel".

yt-dlp can't handle it - "Unsupported URL" :(

 nb, identifying information and login credentials have been replaced with "xxx" in the verbose log.

### Verbose log

```shell
[debug] Command-line config: ['-vU', '--ignore-config', '--add-header', 'cookie:sb=xxx; datr=xxx; c_user=xxx; m_pixel_ratio=1; usida=xxx; wd=1278x800; x-referer=xxx; xs=xxx; fr=xxx; presence=xxx', 'https://www.facebook.com/reel/1195289147628387']
[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] (zip)
[debug] Plugins: ['Youtube_AgeGateBypassIE']
[debug] Python version 3.8.10 (CPython 64bit) - Linux-5.4.0-113-generic-x86_64-with-glibc2.29
[debug] Checking exe version: ffprobe -bsfs
[debug] Checking exe version: ffmpeg -bsfs
[debug] exe versions: ffmpeg 4.2.7, ffprobe 4.2.7, phantomjs 2.1.1, rtmpdump 2.4
[debug] Optional libraries: certifi-2019.11.28, mutagen-1.45.1, pycrypto-2.6.1, pyxattr-0.6.1, secretstorage-2.3.1, sqlite3-2.6.0
[debug] Proxy map: {}
Latest version: 2022.05.18, Current version: 2022.05.18
yt-dlp is up to date (2022.05.18)
[debug] [generic] Extracting URL: https://www.facebook.com/reel/1195289147628387
[generic] 1195289147628387: Requesting header
WARNING: [generic] Falling back on generic information extractor.
[generic] 1195289147628387: Downloading webpage
[generic] 1195289147628387: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://www.facebook.com/reel/1195289147628387
Traceback (most recent call last):
  File "/home/atom/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 1395, in wrapper
    return func(self, *args, **kwargs)
  File "/home/atom/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 1465, in __extract_info
    ie_result = ie.extract(url)
  File "/home/atom/bin/yt-dlp/yt_dlp/extractor/common.py", line 642, in extract
    ie_result = self._real_extract(url)
  File "/home/atom/bin/yt-dlp/yt_dlp/extractor/generic.py", line 4031, in _real_extract
    raise UnsupportedError(url)
yt_dlp.utils.UnsupportedError: Unsupported URL: https://www.facebook.com/reel/1195289147628387
```



Discussion:
From this page - https://www.facebook.com/reel/443200603990817 - I can browse to this reel - https://www.facebook.com/reel/1105738683694651

nb, the URL in the address bar does not change as I browse reels.

In the html, there's two "permalink_url" elements. One of them is formatted like this:
`"https:\/\/www.facebook.com\/HomeDesign24h\/videos\/3046081548977829\/"`

After removing the backslashes, that works fine with yt-dlp to get the desired video.

The other "permalink_url" is formatted like this:
`"permalink_url":"https:\/\/www.facebook.com\/\u0025EF\u0025BF\u0025BD\/videos\/443200603990817\/"`

After converting the `\u` parts to utf8 and removing the backslashes, that looks like this:
`https://www.facebook.com/◯▿▽/videos/443200603990817`

And that brings me to the video that corresponds to the URL in the address-bar, ie the "original" reel I clicked on, not the video being viewed.

The "permalink_url" that I want is on a line that starts with:
`</td></tr><tr><td class="line-html">`

The "permalink_url" that I don't want is on a line that starts with:
`</td></tr><tr><td class="line-html-diff"><ins>`




Any news about this issue? 
> Any news about this issue?
This issue appear to be duplicated of:
https://github.com/yt-dlp/yt-dlp/issues/4112#issuecomment-1159726856
I see these properties hold urls in json/js on page source are downloadable.

playable_url
playable_url_quality_hd 
Obviously, we will need a cookie file for this to work.
> Obviously, we will need a cookie file for this to work.

Not necessarily.

All of the "reels" I've seen are "public", and don't require any cookies to view.

For videos that do require login/cookies, something this works fine:
`--add-header 'cookie: sb=xxxx; datr=xxxx; c_user=xxxx; m_pixel_ratio=xxxx; x-referer=xxxx; usida=xxxx; wd=xxxx; presence=xxxx; xs=xxxx; fr=xxxx'`
for me, I'm using this trike to convert  the URL of a `real` video to a simple `Facebook` URL, that is supported by `youtube-dl` and `yt-dlp`  
so, for example:
```
https://www.facebook.com/reel/386515896914789
==>
https://m.facebook.com/story.php?story_fbid=386515896914789&id=100013560072595&_rdr
```

- download the page of the version `fb` mobile

because the desktop version does not contain the `user id` in `index.html
```bash
/sbin/curl --cookie m.facebook.com/reel/386515896914789 cookies.txt   -L --output index.html 
```
- get user-id
```bash
user=$(cat index.html | grep -Eo 'story_id=S%3A_I[0-9]*' | sort| uniq | sed 's#^story_id.......##')
```
- final URL is:
```bash
video_id=$(echo  https://www.facebook.com/reel/386515896914789 | grep -Eo '[0-9]{14,16}')
url="https://m.facebook.com/story.php?story_fbid=${video_id}&id=${user}&_rdr"
```
> All of the "reels" I've seen are "public", and don't require any cookies to view.

@atom-smasher All examples given by OP asks me for login. If you have example that doesn't need login, pls provide it


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
@@ -500,6 +500,7 @@
     FacebookIE,
     FacebookPluginsVideoIE,
     FacebookRedirectURLIE,
+    FacebookReelIE,
 )
 from .fancode import (
     FancodeVodIE,
diff --git a/yt_dlp/extractor/facebook.py b/yt_dlp/extractor/facebook.py
--- a/yt_dlp/extractor/facebook.py
+++ b/yt_dlp/extractor/facebook.py
@@ -772,3 +772,30 @@ def _real_extract(self, url):
         if not redirect_url:
             raise ExtractorError('Invalid facebook redirect URL', expected=True)
         return self.url_result(redirect_url)
+
+
+class FacebookReelIE(InfoExtractor):
+    _VALID_URL = r'https?://(?:[\w-]+\.)?facebook\.com/reel/(?P<id>\d+)'
+    IE_NAME = 'facebook:reel'
+
+    _TESTS = [{
+        'url': 'https://www.facebook.com/reel/1195289147628387',
+        'md5': 'c4ff9a7182ff9ff7d6f7a83603bae831',
+        'info_dict': {
+            'id': '1195289147628387',
+            'ext': 'mp4',
+            'title': 'md5:9f5b142921b2dc57004fa13f76005f87',
+            'description': 'md5:24ea7ef062215d295bdde64e778f5474',
+            'uploader': 'Beast Camp Training',
+            'uploader_id': '1738535909799870',
+            'duration': 9.536,
+            'thumbnail': r're:^https?://.*',
+            'upload_date': '20211121',
+            'timestamp': 1637502604,
+        }
+    }]
+
+    def _real_extract(self, url):
+        video_id = self._match_id(url)
+        return self.url_result(
+            f'https://m.facebook.com/watch/?v={video_id}&_rdr', FacebookIE, video_id)


Test patch: