Repository: streamlink/streamlink

Issue:
tvtoya.py
### Checklist

- [X] This is a plugin issue and not a different kind of issue
- [X] [I have read the contribution guidelines](https://github.com/streamlink/streamlink/blob/master/CONTRIBUTING.md#contributing-to-streamlink)
- [X] [I have checked the list of open and recently closed plugin issues](https://github.com/streamlink/streamlink/issues?q=is%3Aissue+label%3A%22plugin+issue%22)
- [X] [I have checked the commit log of the master branch](https://github.com/streamlink/streamlink/commits/master)

### Streamlink version

Latest stable release

### Description

Can I ask for a fix to the action
https://tvtoya.pl/player/live

### Debug log

```text
root@zgemmah7:~# /usr/sbin/streamlinksrv manualstart debug
[streamlinksrv][info] ####################mod j00zek#####################
[streamlinksrv][info] Fri Jun  3 18:49:11 2022 Server (1.8.3 - 22.05.28.0954) started
[streamlinksrv][info] Host:            zgemmah7
[streamlinksrv][info] Port:            8088
[streamlinksrv][info] OS:              Linux-4.10.12-armv7l-with-glibc2.35
[streamlinksrv][info] Python:          3.10.4
[streamlinksrv][info] Streamlink:      4.1.0+0.gea7a243a.dirty
[streamlinksrv][info] Log level:       debug
[streamlinksrv][debug] Options Parser: N/A
[streamlinksrv][debug] youtube-dl:     2021.12.17
[streamlinksrv][info] Requests(2.27.1), Socks(1.7.1), Websocket(1.3.2)
[streamlinksrv][info] ###################################################
[streamlinksrv][debug] Received URL: http://tvtoya.pl/live
[streamlinksrv][info] Processing URL: http://tvtoya.pl/live
[streamlinksrv][debug] Arguments:
[streamlinksrv][debug]  url=http://tvtoya.pl/live
[streamlinksrv][debug]  stream=['best']
[streamlinksrv][info] Found matching plugin tvtoya for URL http://tvtoya.pl/live
[streamlinksrv][error] Plugin error: Unable to open URL: http://tvtoya.pl/live (404 Client Error: Not Found for url: https://tvtoya.pl/live)
[streamlinksrv][debug] Send Offline clip: /usr/lib/enigma2/python/Plugins/Extensions/StreamlinkConfig/streams/PluginError.mp4
127.0.0.1 - - [03/Jun/2022 18:49:26] "GET /http://tvtoya.pl/live HTTP/1.1" 200 -
[streamlinksrv][debug] finish >>>
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 49746)
Traceback (most recent call last):
  File "/usr/lib/python3.10/socketserver.py", line 683, in process_request_thread
  File "/usr/lib/python3.10/socketserver.py", line 360, in finish_request
  File "/usr/lib/python3.10/socketserver.py", line 747, in __init__
  File "/usr/sbin/streamlinksrv", line 1156, in handle
    BaseHTTPRequestHandler.handle(self)
  File "/usr/lib/python3.10/http/server.py", line 425, in handle
  File "/usr/lib/python3.10/http/server.py", line 414, in handle_one_request
ValueError: I/O operation on closed file.
----------------------------------------
```



Discussion:

Resolving patch:
diff --git a/src/streamlink/plugins/tvtoya.py b/src/streamlink/plugins/tvtoya.py
--- a/src/streamlink/plugins/tvtoya.py
+++ b/src/streamlink/plugins/tvtoya.py
@@ -4,30 +4,42 @@
 $type live
 """
 
-import logging
 import re
 
-from streamlink.plugin import Plugin, pluginmatcher
+from streamlink.plugin import Plugin, PluginError, pluginmatcher
+from streamlink.plugin.api import validate
 from streamlink.stream.hls import HLSStream
 
-log = logging.getLogger(__name__)
-
 
 @pluginmatcher(re.compile(
-    r"https?://(?:www\.)?tvtoya\.pl/live"
+    r"https?://(?:www\.)?tvtoya\.pl/player/live"
 ))
 class TVToya(Plugin):
-    _playlist_re = re.compile(r'<source src="([^"]+)" type="application/x-mpegURL">')
-
     def _get_streams(self):
-        self.session.set_option('hls-live-edge', 10)
-        res = self.session.http.get(self.url)
-        playlist_m = self._playlist_re.search(res.text)
-
-        if playlist_m:
-            return HLSStream.parse_variant_playlist(self.session, playlist_m.group(1))
-        else:
-            log.debug("Could not find stream data")
+        try:
+            hls = self.session.http.get(self.url, schema=validate.Schema(
+                validate.parse_html(),
+                validate.xml_xpath_string(".//script[@type='application/json'][@id='__NEXT_DATA__']/text()"),
+                str,
+                validate.parse_json(),
+                {
+                    "props": {
+                        "pageProps": {
+                            "type": "live",
+                            "url": validate.all(
+                                str,
+                                validate.transform(lambda url: url.replace("https:////", "https://")),
+                                validate.url(path=validate.endswith(".m3u8")),
+                            )
+                        }
+                    }
+                },
+                validate.get(("props", "pageProps", "url")),
+            ))
+        except PluginError:
+            return
+
+        return HLSStream.parse_variant_playlist(self.session, hls)
 
 
 __plugin__ = TVToya


Test patch:
diff --git a/tests/plugins/test_tvtoya.py b/tests/plugins/test_tvtoya.py
--- a/tests/plugins/test_tvtoya.py
+++ b/tests/plugins/test_tvtoya.py
@@ -6,14 +6,15 @@ class TestPluginCanHandleUrlTVRPlus(PluginCanHandleUrl):
     __plugin__ = TVToya
 
     should_match = [
-        "https://tvtoya.pl/live",
-        "http://tvtoya.pl/live",
+        "http://tvtoya.pl/player/live",
+        "https://tvtoya.pl/player/live",
     ]
 
     should_not_match = [
-        "https://tvtoya.pl",
         "http://tvtoya.pl",
-        "http://tvtoya.pl/other-page",
         "http://tvtoya.pl/",
+        "http://tvtoya.pl/live",
+        "https://tvtoya.pl",
         "https://tvtoya.pl/",
+        "https://tvtoya.pl/live",
     ]