Repository: streamlink/streamlink

Issue:
vaughnlive plugin not working..
### Checklist

- [x] This is a bug report.
- [ ] This is a feature request.
- [ ] This is a plugin (improvement) request.
- [ ] I have read the contribution guidelines.

### Description

Vaughnlive streams are not working

### Expected / Actual behavior

...

### Reproduction steps / Explicit stream URLs to test

seems to be a replica of the closed issue https://github.com/streamlink/streamlink/issues/1034

Every stream just comes back with "error: No playable streams found" 

### Environment details

Operating system and version: Windows 10 x64
Streamlink and Python version: 0.7.0 ( and the latest dev buld from https://dl.bintray.com/streamlink/streamlink-nightly/ ) 

### Comments, logs, screenshots, etc.

This is happening even on the latest night/dev build
Doing "-l debug" doesn't seem to produce anything at all either, just throws the same error: no playable streams found even though the streams are working just fine in browser..

[Love Streamlink? Please consider supporting our collective. Thanks!](https://opencollective.com/streamlink/donate)



Discussion:
@JourneyOver which channel? I tested a few and they still work for me ... 
I tested about 5-10 of them, all in the misc section, but as you say they are working now..so idk what was going on with vaughnlive when I was trying to watch something earlier..
@beardypig I'm waiting for the 500th change where you get tired of updating it (especially considering a lot of it is stolen content).. Closing since we can't duplicate.
Seems changes have been made to the site today. The plugin was working this morning but all of a sudden I'm getting "No playable streams found" on all channels. Should I open a new issue?
@fadster No let's just open this one back up, there are already 25 vaughnlive issues...
I get the "No playable streams found" after successfully opening and playing two or three times.
Could be that Vaughnlive is doing some kind of rate limiting now to potentially try to keep people from downloading multiple streams at once which has the side effect of prohibiting Streamlink users?
I tracked down the problem to the `http.get()` call used to get the stream name in `_get_streams()`. By hardcoding the stream name instead of parsing the result of that call, I got it to work. It appears the recent changes to the site simply broke that part of the code so the fix should be trivial.

I suspect some requests may have been hitting the old version of the site's code cached on Cloudflare's servers, which would explain why the plugin was still working on a couple occasions today. Either that or the site is currently in a state of flux.
this the the problem now...

 streamlink -p "mpv --title=FUJI  --mute --screen=1 --geometry=400x225-0+770"  http://www.vaughnlive.tv/sherming5 best
[cli][info] Found matching plugin vaughnlive for URL http://www.vaughnlive.tv/sherming5
[cli][info] Available streams: live (worst, best)
[cli][info] Opening stream: live (rtmp)
[cli][error] Try 1/1: Could not open stream <RTMPStream({'playpath': 'live_sherming5', 'pageUrl': 'http://www.vaughnlive.tv/sherming5', 'live': True, 'rtmp': 'rtmp://198.255.17.18/live?xKI2Dbx2rCpwXztBIhEENEmys4WgqqFZ', 'flv': '-'}, redirect=False> (No data returned from stream)
error: Could not open stream <RTMPStream({'playpath': 'live_sherming5', 'pageUrl': 'http://www.vaughnlive.tv/sherming5', 'live': True, 'rtmp': 'rtmp://198.255.17.18/live?xKI2Dbx2rCpwXztBIhEENEmys4WgqqFZ', 'flv': '-'}, redirect=False>, tried 1 times, exiting
[cli][info] Closing currently open stream...

@c769214 I assume you hardcoded the channel's name to get this message, otherwise you would've gotten the "No playable streams found" error. If so, all you need to do is retry the command until it plays. It's just timing out a lot at the moment.
I took a closer look at the result of that broken `http.get()` call. The site now detects the request as coming from a bot and returns a captcha challenge instead of the channel's page. It uses Distil scrape protection and spoofing the user agent isn't enough to circumvent it. Perhaps we could use something like this: https://github.com/Anorov/cloudflare-scrape

However, according to that module's description, it won't work with captcha challenges. Alternatively, since we only need this request to determine the channel's internal name (ie. with the `#vl-` prefix), we could eliminate it altogether and just derive the name from the channel's URL:

```python
stream_name = "#vl-" + re.search('//.*/(.+?)$', self.url).group(1)
```

Supporting all the subdomains (`#btv`, `#igb`, etc.) would involve some trial and error until the correct name is determined as this obviously only works for `#vl`.
Thanks to this link and youtube tutorial:
https://www.youtube.com/watch?v=oNR5xKstlgY
posted in this thread 11 days ago:
https://github.com/streamlink/streamlink/issues/1034

I managed to get streamlink working again, this is example command which I'm using atm:
streamlink --http-header "Referer=https://vaughnlive.tv/unccharlie2" "hls://https://hls-ord-1a.vaughnsoft.net/nyc/live/live_unccharlie2/chunklist.m3u8" worst

I hope this will give you extra information needed to solve this problem :\
It might be reasonable, as @fadster suggests, to use the channel name from the URL and have a mapping from domain to channel id prefix. That coudflare scraper is interesting, but it does execute JavaScript to get the tokens which makes me a be wary... 

Resolving patch:
diff --git a/src/streamlink/plugins/vaughnlive.py b/src/streamlink/plugins/vaughnlive.py
--- a/src/streamlink/plugins/vaughnlive.py
+++ b/src/streamlink/plugins/vaughnlive.py
@@ -34,16 +34,17 @@ def recv(self):
 
 
 class VaughnLive(Plugin):
-    api_re = re.compile(r'new sApi\("(#(vl|igb|btv|pt|vtv)-[^"]+)",')
     servers = ["wss://sapi-ws-{0}x{1:02}.vaughnlive.tv".format(x, y) for x, y in itertools.product(range(1, 3),
                                                                                                    range(1, 6))]
     origin = "https://vaughnlive.tv"
     rtmp_server_map = {
-        "594140c69edad": "198.255.17.18",
-        "585c4cab1bef1": "198.255.17.26",
-        "5940d648b3929": "198.255.17.34",
-        "5941854b39bc4": "198.255.17.66"}
+        "594140c69edad": "66.90.93.42",
+        "585c4cab1bef1": "66.90.93.34",
+        "5940d648b3929": "66.90.93.42",
+        "5941854b39bc4": "198.255.0.10"
+    }
     name_remap = {"#vl": "live", "#btv": "btv", "#pt": "pt", "#igb": "instagib", "#vtv": "vtv"}
+    domain_map = {"vaughnlive": "#vl", "breakers": "#btv", "instagib": "#igb", "vapers": "#vtv", "pearltime": "#pt"}
 
     @classmethod
     def can_handle_url(cls, url):
@@ -88,12 +89,11 @@ def _get_rtmp_streams(self, server, domain, channel, token):
         })
 
     def _get_streams(self):
-        res = http.get(self.url, headers={"User-Agent": useragents.CHROME})
+        m = _url_re.match(self.url)
+        if m:
+            stream_name = "{0}-{1}".format(self.domain_map[(m.group("domain").lower())],
+                                           m.group("channel"))
 
-        m = self.api_re.search(res.text)
-        stream_name = m and m.group(1)
-
-        if stream_name:
             is_live, server, domain, channel, token, ingest = self._get_info(stream_name)
 
             if not is_live:


Test patch: