Repository: streamlink/streamlink

Issue:
plugins.youtube: error: No plugin can handle URL: https://youtu.be/SebJIjQgdjg
<!--
Hello. for few days, the plugin isn't working anymore
-->


## Plugin Issue

<!-- Replace the space character between the square brackets with an x in order to check the boxes -->
- [x] This is a plugin issue and I have read the contribution guidelines.
- [x] I am using the latest development version from the master branch.


### Description

 
for few days, the plugin isn't working anymore getting streams from Youtube channels.

Error: No plugin can handle URL: https://youtu.be/SebJIjQgdjg


### Reproduction steps / Explicit stream URLs to test

1. URL: https://youtu.be/SebJIjQgdjg

### Log output

```
[cli][debug] OS:         Linux-3.10.0-1160.11.1.el7.x86_64-x86_64-with-centos-7.9.2009-Core
[cli][debug] Python:     3.6.8
[cli][debug] Streamlink: 2.1.1+3.gd568f43.dirty
[cli][debug] Requests(2.25.1), Socks(1.7.1), Websocket(0.58.0)
[cli][debug] Arguments:
[cli][debug]  url=https://youtu.be/SebJIjQgdjg
[cli][debug]  stream=['best']
[cli][debug]  --loglevel=debug
[cli][debug]  --player=/TheCore/web/watchdog/bridge-probe.cgi
[cli][debug]  --player-args=eyJmaWx0ZXJzX2NvbXBsZXgiOltdLCJvdXRwdXRzIjpbeyJmb3JtYXRzIjpbeyJ5IjoiNyIsImYiOiJ0aGVjb3JlZWxlbWVudHMifV0sInZpZGVvIjp7Im1hcCI6IjA6diIsInZmIjoiZnBzPWZwcz0yNTpyb3VuZD11cCIsImNvZGVjIjoiZW1wdHkiLCJmaWVsZF9vcmRlciI6InR0In0sImF1ZGlvcyI6W3sibWFwIjoiMDphIiwiY29kZWMiOiJlbXB0eSIsImFmIjoiYXJlc2FtcGxlPTQ4MDAwIn1dfV0sImlucHV0Ijp7InN0cmVhbWxpbmsiOm51bGwsInN0cmVhbWxpbmtfdHdpdGNoLW9hdXRoLXRva2VuIjoiIiwidXJsIjoiKyJ9LCJhbGlhcyI6IiJ9 --overrideurl {filename}
[cli][debug]  --player-fifo=True
[cli][debug]  --hls-segment-threads=8
[cli][debug]  --ringbuffer-size=134217728
[cli][debug]  --stream-segment-threads=8
[cli][debug]  --ffmpeg-ffmpeg=/usr/local/enctools/bin/ffmpeg
[cli][debug]  --http-no-ssl-verify=True
error: No plugin can handle URL: https://youtu.be/SebJIjQgdjg

```



Discussion:

Patch:
diff --git a/src/streamlink/plugins/youtube.py b/src/streamlink/plugins/youtube.py
index da968685..c4b9b07d 100644
--- a/src/streamlink/plugins/youtube.py
+++ b/src/streamlink/plugins/youtube.py
@@ -59,7 +59,8 @@ _config_schema = validate.Schema(
 )
 
 _ytdata_re = re.compile(r'ytInitialData\s*=\s*({.*?});', re.DOTALL)
-_url_re = re.compile(r"""(?x)https?://(?:\w+\.)?youtube\.com
+_url_re = re.compile(r"""
+    https?://(?:\w+\.)?youtube\.com
     (?:
         (?:
             /(?:
@@ -83,7 +84,9 @@ _url_re = re.compile(r"""(?x)https?://(?:\w+\.)?youtube\.com
             /(?:c/)?[^/?]+/live/?$
         )
     )
-""")
+    |
+    https?://youtu\.be/(?P<video_id_short>[0-9A-z_-]{11})
+""", re.VERBOSE)
 
 
 class YouTube(Plugin):
@@ -223,9 +226,10 @@ class YouTube(Plugin):
 
     def _find_video_id(self, url):
         m = _url_re.match(url)
-        if m.group("video_id"):
+        video_id = m.group("video_id") or m.group("video_id_short")
+        if video_id:
             log.debug("Video ID from URL")
-            return m.group("video_id")
+            return video_id
 
         res = self.session.http.get(url)
         if urlparse(res.url).netloc == "consent.youtube.com":


Test patch:
diff --git a/tests/plugins/test_youtube.py b/tests/plugins/test_youtube.py
index 897e9e3d..7bcbce62 100644
--- a/tests/plugins/test_youtube.py
+++ b/tests/plugins/test_youtube.py
@@ -22,6 +22,7 @@ class TestPluginCanHandleUrlYouTube(PluginCanHandleUrl):
         "https://www.youtube.com/user/EXAMPLE/live",
         "https://www.youtube.com/v/aqz-KE-bpKQ",
         "https://www.youtube.com/watch?v=aqz-KE-bpKQ",
+        "https://youtu.be/0123456789A",
     ]
 
     should_not_match = [
@@ -30,6 +31,10 @@ class TestPluginCanHandleUrlYouTube(PluginCanHandleUrl):
         "https://www.youtube.com/account",
         "https://www.youtube.com/feed/guide_builder",
         "https://www.youtube.com/t/terms",
+        "https://youtu.be",
+        "https://youtu.be/",
+        "https://youtu.be/c/CHANNEL",
+        "https://youtu.be/c/CHANNEL/live",
     ]