Repository: streamlink/streamlink

Issue:
Unable to get the YT Live best quality hls stream url in sometimes
##  Plugin Issue

<!-- Replace [ ] with [x] in order to check the box -->
- [x] This is a plugin issue and I have read the contribution guidelines.


### Description

YouTube seems to have changed their code on July 11, especially in terms of live streaming.

The first problem is the inability to parse the video id of the user/channel 's live broadcast room address.
```
> streamlink -l debug -o test.ts https://www.youtube.com/rocketbeanstv/live best
[cli][debug] OS:         Windows 10
[cli][debug] Python:     3.7.3
[cli][debug] Streamlink: 1.1.1
[cli][debug] Requests(2.21.0), Socks(1.7.0), Websocket(0.56.0)
[cli][info] Found matching plugin youtube for URL https://www.youtube.com/rocketbeanstv/live
error: Could not find a video on this page
```
Try to fix in #2538 .

Another issue is that if a live stream video have 1080p and 1080p60 at the same time, it can't get the hls url for 1080p60. (Maybe it doesn't exist at all?)
It will try to get the http substream and program exit directly, only one frame/segment of data can be obtained (about 500k).

I found that youtube-dl has the same problem. https://github.com/ytdl-org/youtube-dl/issues/21734

### Reproduction steps / Explicit stream URLs to test

<!-- How can we reproduce this? Please note the exact steps below using the list format supplied. If you need more steps please add them. -->

1. Looking for a live broadcast room with 1080p60 quality options
2. Try to download the video at the best quality

### Log output

<!--
TEXT LOG OUTPUT IS REQUIRED for a plugin issue!
Use the `--loglevel debug` parameter and avoid using parameters which suppress log output.
https://streamlink.github.io/cli.html#cmdoption-l

Make sure to **remove usernames and passwords**
You can copy the output to https://gist.github.com/ or paste it below.
-->

Try to download best quality (1080p60) with format code 299
```
$ streamlink -o test.ts https://www.youtube.com/rocketbeanstv/live best -l debug
[cli][debug] OS:         Linux-5.1.15-arch1-1-ARCH-x86_64-with-arch
[cli][debug] Python:     3.7.3
[cli][debug] Streamlink: 1.1.1+39.g04f0b0d
[cli][debug] Requests(2.22.0), Socks(1.6.7), Websocket(0.56.0)
[cli][info] Found matching plugin youtube for URL https://www.youtube.com/rocketbeanstv/live
[plugin.youtube][debug] Video ID from currentVideoEndpoint
[plugin.youtube][debug] Using video ID: E-MsayZ_Epw
[plugin.youtube][debug] get_video_info - 1: Found data
[plugin.youtube][debug] MuxedStream: v 137 a 140 = 1080p
[plugin.youtube][debug] MuxedStream: v 299 a 140 = 1080p60
[utils.l10n][debug] Language code: zh_CN
[cli][info] Available streams: audio_mp4, 144p (worst), 240p, 360p, 480p, 720p, 1080p, 1080p60 (best)
[cli][info] Opening stream: 1080p60 (muxed-stream)
[stream.ffmpegmux][debug] Opening http substream
[stream.ffmpegmux][debug] Opening http substream
[stream.mp4mux-ffmpeg][debug] ffmpeg command: ffmpeg -nostats -y -i /tmp/ffmpeg-74555-150 -i /tmp/ffmpeg-74555-765 -c:v copy -c:a copy -map 0 -map 1 -f matroska pipe:1
[stream.ffmpegmux][debug] Starting copy to pipe: /tmp/ffmpeg-74555-150
[stream.ffmpegmux][debug] Starting copy to pipe: /tmp/ffmpeg-74555-765
[cli][debug] Pre-buffering 8192 bytes
[stream.ffmpegmux][debug] Pipe copy complete: /tmp/ffmpeg-74555-765
[cli][debug] Checking file output
[cli][debug] Writing stream to output
[stream.ffmpegmux][debug] Pipe copy complete: /tmp/ffmpeg-74555-150

[stream.ffmpegmux][debug] Closing ffmpeg thread
[stream.ffmpegmux][debug] Closed all the substreams
[cli][info] Stream ended
[cli][info] Closing currently open stream...
[stream.ffmpegmux][debug] Closing ffmpeg thread
[stream.ffmpegmux][debug] Closed all the substreams
[stream.ffmpegmux][debug] Closing ffmpeg thread
[stream.ffmpegmux][debug] Closed all the substreams
```


If you choose 1080p quality, it can download as normal.
```
$ streamlink -o test.ts https://www.youtube.com/rocketbeanstv/live 1080p -l debug
[cli][debug] OS:         Linux-5.1.15-arch1-1-ARCH-x86_64-with-arch
[cli][debug] Python:     3.7.3
[cli][debug] Streamlink: 1.1.1+39.g04f0b0d
[cli][debug] Requests(2.22.0), Socks(1.6.7), Websocket(0.56.0)
[cli][info] Found matching plugin youtube for URL https://www.youtube.com/rocketbeanstv/live
[plugin.youtube][debug] Video ID from currentVideoEndpoint
[plugin.youtube][debug] Using video ID: E-MsayZ_Epw
[plugin.youtube][debug] get_video_info - 1: Found data
[plugin.youtube][debug] MuxedStream: v 137 a 140 = 1080p
[plugin.youtube][debug] MuxedStream: v 299 a 140 = 1080p60
[utils.l10n][debug] Language code: zh_CN
[cli][info] Available streams: audio_mp4, 144p (worst), 240p, 360p, 480p, 720p, 1080p, 1080p60 (best)
[cli][info] Opening stream: 1080p (hls)
[stream.hls][debug] Reloading playlist
[stream.hls][debug] First Sequence: 72157; Last Sequence: 75755
[stream.hls][debug] Start offset: 0; Duration: None; Start Sequence: 75753; End Sequence: None
[stream.hls][debug] Adding segment 75753 to queue
[cli][debug] Pre-buffering 8192 bytes
[stream.hls][debug] Adding segment 75754 to queue
[stream.hls][debug] Adding segment 75755 to queue
```

After the live broadcast is over, it can be download normally.


Discussion:
see https://github.com/streamlink/streamlink/pull/1556
Streamlink should not use `MuxedStream` for livestreams

the `is_live` check in Streamlink doesn't work anymore

So actually that is same problem with #1520...
YouTube changed the livestream flags, so is_live check part should be rewrited.
I found a key "playabilityStatus" is that useful ? 
![9d75efe8dc5e4b3](https://user-images.githubusercontent.com/25289725/61075103-de43d280-a44b-11e9-87ab-b3f7b0c50e60.png)
![-33d54f3d836c3568](https://user-images.githubusercontent.com/25289725/61075113-e4d24a00-a44b-11e9-9186-c412895946a1.png)


Resolving patch:
diff --git a/src/streamlink/plugins/youtube.py b/src/streamlink/plugins/youtube.py
--- a/src/streamlink/plugins/youtube.py
+++ b/src/streamlink/plugins/youtube.py
@@ -82,6 +82,9 @@ def parse_fmt_list(formatsmap):
             {
                 validate.optional("streamingData"): {
                     validate.optional("hlsManifestUrl"): validate.text,
+                },
+                validate.optional("videoDetails"): {
+                    validate.optional("isLive"): validate.transform(bool),
                 }
             }
         ),
@@ -339,7 +342,8 @@ def _get_streams(self):
             log.error("Could not get video info")
             return
 
-        if info.get("livestream") == '1' or info.get("live_playback") == '1':
+        if info.get("livestream") == '1' or info.get("live_playback") == '1' \
+                or info.get("player_response", {}).get("videoDetails", {}).get("isLive") == True:
             log.debug("This video is live.")
             is_live = True
 


Test patch: