prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  plugins.vidio: 403 Client Error on stream token acquirement
  ### Checklist
  
  - [X] This is a [plugin issue](https://streamlink.github.io/plugins.html) and not [a different kind of issue](https://github.com/streamlink/streamlink/issues/new/choose)
  - [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
  
  Unable to open URL: https://www.vidio.com/live/204/tokens (403 Client Error: Forbidden for url: https://www.vidio.com/live/204/tokens?type=hls)
  
  ### Description
  
  The live stream:  https://www.vidio.com/live/204-sctv
  the output: https://www.vidio.com/live/204/tokens (403 Client Error: Forbidden for url: https://www.vidio.com/live/204/tokens?type=hls)
  
  It is missing sctv
  
  ### Debug log
  
  ```text
  streamlink https://www.vidio.com/live/204-sctv best
  [cli][info] Found matching plugin vidio for URL https://www.vidio.com/live/204-sctv
  error: Unable to open URL: https://www.vidio.com/live/204/tokens (403 Client Error: Forbidden for url: https://www.vidio.com/live/204/tokens?type=hls)
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/streamlink/plugins/vidio.py`
  Content:
  ```
  1 """
  2 $description Indonesian & international live TV channels and video on-demand service. OTT service from Vidio.
  3 $url vidio.com
  4 $type live, vod
  5 """
  6 import logging
  7 import re
  8 from urllib.parse import urlsplit, urlunsplit
  9 
  10 from streamlink.plugin import Plugin, pluginmatcher
  11 from streamlink.plugin.api import validate
  12 from streamlink.stream.dash import DASHStream
  13 from streamlink.stream.hls import HLSStream
  14 
  15 
  16 log = logging.getLogger(__name__)
  17 
  18 
  19 @pluginmatcher(re.compile(
  20     r"https?://(?:www\.)?vidio\.com/",
  21 ))
  22 class Vidio(Plugin):
  23     tokens_url = "https://www.vidio.com/live/{id}/tokens"
  24 
  25     def _get_stream_token(self, stream_id, stream_type):
  26         log.debug("Getting stream token")
  27         return self.session.http.post(
  28             self.tokens_url.format(id=stream_id),
  29             params={"type": stream_type},
  30             headers={"Referer": self.url},
  31             schema=validate.Schema(
  32                 validate.parse_json(),
  33                 {"token": str},
  34                 validate.get("token"),
  35             ),
  36         )
  37 
  38     def _get_streams(self):
  39         stream_id, has_token, hls_url, dash_url = self.session.http.get(
  40             self.url,
  41             schema=validate.Schema(
  42                 validate.parse_html(),
  43                 validate.xml_find(".//*[@data-video-id]"),
  44                 validate.union((
  45                     validate.get("data-video-id"),
  46                     validate.all(
  47                         validate.get("data-video-has-token"),
  48                         validate.transform(lambda val: val and val != "false"),
  49                     ),
  50                     validate.get("data-vjs-clip-hls-url"),
  51                     validate.get("data-vjs-clip-dash-url"),
  52                 )),
  53             ),
  54         )
  55 
  56         if dash_url and has_token:
  57             token = self._get_stream_token(stream_id, "dash")
  58             parsed = urlsplit(dash_url)
  59             dash_url = urlunsplit(parsed._replace(path=f"{token}{parsed.path}"))
  60             return DASHStream.parse_manifest(
  61                 self.session,
  62                 dash_url,
  63                 headers={"Referer": "https://www.vidio.com/"},
  64             )
  65 
  66         if not hls_url:
  67             return
  68 
  69         if has_token:
  70             token = self._get_stream_token(stream_id, "hls")
  71             hls_url = f"{hls_url}?{token}"
  72 
  73         return HLSStream.parse_variant_playlist(
  74             self.session,
  75             hls_url,
  76             headers={"Referer": "https://www.vidio.com/"},
  77         )
  78 
  79 
  80 __plugin__ = Vidio
  81
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/streamlink/plugins/vidio.py b/src/streamlink/plugins/vidio.py
  --- a/src/streamlink/plugins/vidio.py
  +++ b/src/streamlink/plugins/vidio.py
  @@ -6,6 +6,7 @@
   import logging
   import re
   from urllib.parse import urlsplit, urlunsplit
  +from uuid import uuid4
   
   from streamlink.plugin import Plugin, pluginmatcher
   from streamlink.plugin.api import validate
  @@ -17,7 +18,7 @@
   
   
   @pluginmatcher(re.compile(
  -    r"https?://(?:www\.)?vidio\.com/",
  +    r"https?://(?:www\.)?vidio\.com/.+",
   ))
   class Vidio(Plugin):
       tokens_url = "https://www.vidio.com/live/{id}/tokens"
  @@ -28,6 +29,10 @@
               self.tokens_url.format(id=stream_id),
               params={"type": stream_type},
               headers={"Referer": self.url},
  +            cookies={
  +                "ahoy_visit": str(uuid4()),
  +                "ahoy_visitor": str(uuid4()),
  +            },
               schema=validate.Schema(
                   validate.parse_json(),
                   {"token": str},
  
verification_info: {"golden_diff": "diff --git a/src/streamlink/plugins/vidio.py b/src/streamlink/plugins/vidio.py\n--- a/src/streamlink/plugins/vidio.py\n+++ b/src/streamlink/plugins/vidio.py\n@@ -6,6 +6,7 @@\n import logging\n import re\n from urllib.parse import urlsplit, urlunsplit\n+from uuid import uuid4\n \n from streamlink.plugin import Plugin, pluginmatcher\n from streamlink.plugin.api import validate\n@@ -17,7 +18,7 @@\n \n \n @pluginmatcher(re.compile(\n-    r\"https?://(?:www\\.)?vidio\\.com/\",\n+    r\"https?://(?:www\\.)?vidio\\.com/.+\",\n ))\n class Vidio(Plugin):\n     tokens_url = \"https://www.vidio.com/live/{id}/tokens\"\n@@ -28,6 +29,10 @@\n             self.tokens_url.format(id=stream_id),\n             params={\"type\": stream_type},\n             headers={\"Referer\": self.url},\n+            cookies={\n+                \"ahoy_visit\": str(uuid4()),\n+                \"ahoy_visitor\": str(uuid4()),\n+            },\n             schema=validate.Schema(\n                 validate.parse_json(),\n                 {\"token\": str},\n", "issue": "plugins.vidio: 403 Client Error on stream token acquirement\n### Checklist\n\n- [X] This is a [plugin issue](https://streamlink.github.io/plugins.html) and not [a different kind of issue](https://github.com/streamlink/streamlink/issues/new/choose)\n- [X] [I have read the contribution guidelines](https://github.com/streamlink/streamlink/blob/master/CONTRIBUTING.md#contributing-to-streamlink)\n- [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)\n- [X] [I have checked the commit log of the master branch](https://github.com/streamlink/streamlink/commits/master)\n\n### Streamlink version\n\nUnable to open URL: https://www.vidio.com/live/204/tokens (403 Client Error: Forbidden for url: https://www.vidio.com/live/204/tokens?type=hls)\n\n### Description\n\nThe live stream:  https://www.vidio.com/live/204-sctv\r\nthe output: https://www.vidio.com/live/204/tokens (403 Client Error: Forbidden for url: https://www.vidio.com/live/204/tokens?type=hls)\r\n\r\nIt is missing sctv\n\n### Debug log\n\n```text\nstreamlink https://www.vidio.com/live/204-sctv best\r\n[cli][info] Found matching plugin vidio for URL https://www.vidio.com/live/204-sctv\r\nerror: Unable to open URL: https://www.vidio.com/live/204/tokens (403 Client Error: Forbidden for url: https://www.vidio.com/live/204/tokens?type=hls)\n```\n\n", "before_files": [{"content": "\"\"\"\n$description Indonesian & international live TV channels and video on-demand service. OTT service from Vidio.\n$url vidio.com\n$type live, vod\n\"\"\"\nimport logging\nimport re\nfrom urllib.parse import urlsplit, urlunsplit\n\nfrom streamlink.plugin import Plugin, pluginmatcher\nfrom streamlink.plugin.api import validate\nfrom streamlink.stream.dash import DASHStream\nfrom streamlink.stream.hls import HLSStream\n\n\nlog = logging.getLogger(__name__)\n\n\n@pluginmatcher(re.compile(\n    r\"https?://(?:www\\.)?vidio\\.com/\",\n))\nclass Vidio(Plugin):\n    tokens_url = \"https://www.vidio.com/live/{id}/tokens\"\n\n    def _get_stream_token(self, stream_id, stream_type):\n        log.debug(\"Getting stream token\")\n        return self.session.http.post(\n            self.tokens_url.format(id=stream_id),\n            params={\"type\": stream_type},\n            headers={\"Referer\": self.url},\n            schema=validate.Schema(\n                validate.parse_json(),\n                {\"token\": str},\n                validate.get(\"token\"),\n            ),\n        )\n\n    def _get_streams(self):\n        stream_id, has_token, hls_url, dash_url = self.session.http.get(\n            self.url,\n            schema=validate.Schema(\n                validate.parse_html(),\n                validate.xml_find(\".//*[@data-video-id]\"),\n                validate.union((\n                    validate.get(\"data-video-id\"),\n                    validate.all(\n                        validate.get(\"data-video-has-token\"),\n                        validate.transform(lambda val: val and val != \"false\"),\n                    ),\n                    validate.get(\"data-vjs-clip-hls-url\"),\n                    validate.get(\"data-vjs-clip-dash-url\"),\n                )),\n            ),\n        )\n\n        if dash_url and has_token:\n            token = self._get_stream_token(stream_id, \"dash\")\n            parsed = urlsplit(dash_url)\n            dash_url = urlunsplit(parsed._replace(path=f\"{token}{parsed.path}\"))\n            return DASHStream.parse_manifest(\n                self.session,\n                dash_url,\n                headers={\"Referer\": \"https://www.vidio.com/\"},\n            )\n\n        if not hls_url:\n            return\n\n        if has_token:\n            token = self._get_stream_token(stream_id, \"hls\")\n            hls_url = f\"{hls_url}?{token}\"\n\n        return HLSStream.parse_variant_playlist(\n            self.session,\n            hls_url,\n            headers={\"Referer\": \"https://www.vidio.com/\"},\n        )\n\n\n__plugin__ = Vidio\n", "path": "src/streamlink/plugins/vidio.py"}], "after_files": [{"content": "\"\"\"\n$description Indonesian & international live TV channels and video on-demand service. OTT service from Vidio.\n$url vidio.com\n$type live, vod\n\"\"\"\nimport logging\nimport re\nfrom urllib.parse import urlsplit, urlunsplit\nfrom uuid import uuid4\n\nfrom streamlink.plugin import Plugin, pluginmatcher\nfrom streamlink.plugin.api import validate\nfrom streamlink.stream.dash import DASHStream\nfrom streamlink.stream.hls import HLSStream\n\n\nlog = logging.getLogger(__name__)\n\n\n@pluginmatcher(re.compile(\n    r\"https?://(?:www\\.)?vidio\\.com/.+\",\n))\nclass Vidio(Plugin):\n    tokens_url = \"https://www.vidio.com/live/{id}/tokens\"\n\n    def _get_stream_token(self, stream_id, stream_type):\n        log.debug(\"Getting stream token\")\n        return self.session.http.post(\n            self.tokens_url.format(id=stream_id),\n            params={\"type\": stream_type},\n            headers={\"Referer\": self.url},\n            cookies={\n                \"ahoy_visit\": str(uuid4()),\n                \"ahoy_visitor\": str(uuid4()),\n            },\n            schema=validate.Schema(\n                validate.parse_json(),\n                {\"token\": str},\n                validate.get(\"token\"),\n            ),\n        )\n\n    def _get_streams(self):\n        stream_id, has_token, hls_url, dash_url = self.session.http.get(\n            self.url,\n            schema=validate.Schema(\n                validate.parse_html(),\n                validate.xml_find(\".//*[@data-video-id]\"),\n                validate.union((\n                    validate.get(\"data-video-id\"),\n                    validate.all(\n                        validate.get(\"data-video-has-token\"),\n                        validate.transform(lambda val: val and val != \"false\"),\n                    ),\n                    validate.get(\"data-vjs-clip-hls-url\"),\n                    validate.get(\"data-vjs-clip-dash-url\"),\n                )),\n            ),\n        )\n\n        if dash_url and has_token:\n            token = self._get_stream_token(stream_id, \"dash\")\n            parsed = urlsplit(dash_url)\n            dash_url = urlunsplit(parsed._replace(path=f\"{token}{parsed.path}\"))\n            return DASHStream.parse_manifest(\n                self.session,\n                dash_url,\n                headers={\"Referer\": \"https://www.vidio.com/\"},\n            )\n\n        if not hls_url:\n            return\n\n        if has_token:\n            token = self._get_stream_token(stream_id, \"hls\")\n            hls_url = f\"{hls_url}?{token}\"\n\n        return HLSStream.parse_variant_playlist(\n            self.session,\n            hls_url,\n            headers={\"Referer\": \"https://www.vidio.com/\"},\n        )\n\n\n__plugin__ = Vidio\n", "path": "src/streamlink/plugins/vidio.py"}]}