Repository: streamlink/streamlink

Issue:
Atresplayer
### 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
Links Live:
https://www.atresplayer.com/directos/antena3/
https://www.atresplayer.com/directos/lasexta/
https://www.atresplayer.com/directos/neox/
https://www.atresplayer.com/directos/nova/
https://www.atresplayer.com/directos/mega/
https://www.atresplayer.com/directos/atreseries/

```
 streamlink.exe https://www.atresplayer.com/directos/antena3/ best --player ffplay -l debug
 [console][debug] OS:         Windows 7
 [console][debug] Python:     3.5.2
 [console][debug] Streamlink: 0.13.0
 [console][debug] Requests(2.18.4), Socks(1.6.7), Websocket(0.48.0)
 error: No plugin can handle URL: https://www.atresplayer.com/directos/antena3/
```

*I have executed the same command with the six links.

Sorry for English, I do not speak it.


Discussion:

Resolving patch:
diff --git a/src/streamlink/plugins/atresplayer.py b/src/streamlink/plugins/atresplayer.py
--- a/src/streamlink/plugins/atresplayer.py
+++ b/src/streamlink/plugins/atresplayer.py
@@ -1,38 +1,56 @@
 from __future__ import print_function
+
+import logging
 import re
-import time
-import random
 
 from streamlink.plugin import Plugin
-from streamlink.plugin.api import http
-from streamlink.plugin.api import validate
-from streamlink.stream import HDSStream
+from streamlink.plugin.api import http, validate
+from streamlink.stream import HLSStream
+from streamlink.utils import parse_json, update_scheme
+
+log = logging.getLogger(__name__)
 
 
 class AtresPlayer(Plugin):
-    url_re = re.compile(r"https?://(?:www.)?atresplayer.com/directos/television/(\w+)/?")
-    player_re = re.compile(r"""div.*?directo=(\d+)""")
-    stream_api = "https://servicios.atresplayer.com/api/urlVideoLanguage/v3/{id}/web/{id}|{time}|{hash}/es.xml"
-    manifest_re = re.compile(r"<resultDes>(.*?)</resultDes>")
+    url_re = re.compile(r"https?://(?:www.)?atresplayer.com/directos/([\w-]+)/?")
+    state_re = re.compile(r"""window.__PRELOADED_STATE__\s*=\s*({.*?});""", re.DOTALL)
+    channel_id_schema = validate.Schema(
+        validate.transform(state_re.search),
+        validate.any(
+            None,
+            validate.all(
+                validate.get(1),
+                validate.transform(parse_json),
+                {
+                    "programming": {
+                        validate.text: validate.all({"urlVideo": validate.text},
+                                                    validate.get("urlVideo"))
+                    }
+                },
+                validate.get("programming")
+            )))
+    stream_schema = validate.Schema(
+        validate.transform(parse_json),
+        {"sources": [
+            validate.all({"src": validate.url()},
+                         validate.get("src"))
+        ]}, validate.get("sources"))
+
 
     @classmethod
     def can_handle_url(cls, url):
         return cls.url_re.match(url) is not None
 
+    def __init__(self, url):
+        # must be HTTPS
+        super(AtresPlayer, self).__init__(update_scheme("https://", url))
+
     def _get_streams(self):
-        res = http.get(self.url)
-        match = self.player_re.search(res.text)
-        if match:
-            channel_id = match.group(1)
-
-            stream_api = self.stream_api.format(id=channel_id,
-                                                time=int(time.time()),
-                                                hash=''.join(random.choice("abcdef0123456789") for x in range(28)))
-
-            res = http.get(stream_api)
-            f4m_url = self.manifest_re.search(res.text)
-            if f4m_url:
-                return HDSStream.parse_manifest(self.session, f4m_url.group(1))
+        programming = http.get(self.url, schema=self.channel_id_schema)
+        for api_url in programming.values():
+            for src in http.get(api_url, schema=self.stream_schema):
+                for s in HLSStream.parse_variant_playlist(self.session, src).items():
+                    yield s
 
 
 __plugin__ = AtresPlayer


Test patch: