"""
$description Global live-streaming platform owned by BitTorrent, Inc.
$url dlive.tv
$type live, vod
$metadata author
$metadata title
"""

import logging
import re
from urllib.parse import unquote_plus

from streamlink.plugin import Plugin, pluginmatcher
from streamlink.plugin.api import validate
from streamlink.stream.hls import HLSStream


log = logging.getLogger(__name__)


@pluginmatcher(re.compile(r"""
    https?://(?:www\.)?dlive\.tv/
    (?:
        p/(?P<video>[^/]+)
        |
        (?P<channel>[^/]+)
    )
""", re.VERBOSE))
class DLive(Plugin):
    URL_LIVE = "https://live.prd.dlive.tv/hls/live/{username}.m3u8"

    QUALITY_WEIGHTS = {
        "src": 1080,
    }

    @classmethod
    def stream_weight(cls, key):
        weight = cls.QUALITY_WEIGHTS.get(key)
        if weight:
            return weight, "dlive"

        return super().stream_weight(key)

    def _get_streams_video(self, video):
        log.debug(f"Getting video HLS streams for {video}")
        hls_url = self.session.http.get(self.url, schema=validate.Schema(
            validate.regex(re.compile(r'"playbackUrl"\s*:\s*"([^"]+\.m3u8)"')),
            validate.get(1),
            validate.transform(unquote_plus),
            validate.transform(lambda url: bytes(url, "utf-8").decode("unicode_escape")),
            validate.url(),
        ))

        return HLSStream.parse_variant_playlist(self.session, hls_url)

    def _get_streams_live(self, channel):
        log.debug(f"Getting live HLS streams for {channel}")
        query = f"""query {{
            userByDisplayName(displayname:"{channel}") {{
                livestream {{
                    title
                }}
                username
            }}
        }}"""
        livestream, username = self.session.http.post(
            "https://graphigo.prd.dlive.tv/",
            json={"query": query},
            schema=validate.Schema(
                validate.parse_json(),
                {
                    "data": {
                        "userByDisplayName": {
                            "livestream": {
                                "title": str,
                            },
                            "username": str,
                        },
                    },
                },
                validate.get(("data", "userByDisplayName")),
                validate.union_get("livestream", "username"),
            ),
        )

        self.author = channel
        self.title = livestream["title"]

        return HLSStream.parse_variant_playlist(self.session, self.URL_LIVE.format(username=username))

    def _get_streams(self):
        video = self.match.group("video")
        channel = self.match.group("channel")

        if video:
            return self._get_streams_video(video)
        elif channel:
            return self._get_streams_live(channel)


__plugin__ = DLive

src/streamlink/plugins/dlive.py
"""
$description Global live-streaming platform owned by BitTorrent, Inc.
$url dlive.tv
$type live, vod
$metadata author
$metadata title
"""

import logging
import re
from urllib.parse import unquote_plus

from streamlink.plugin import Plugin, pluginmatcher
from streamlink.plugin.api import validate
from streamlink.stream.hls import HLSStream


log = logging.getLogger(__name__)


@pluginmatcher(re.compile(r"""
    https?://(?:www\.)?dlive\.tv/
    (?:
        p/(?P<video>[^/]+)
        |
        (?P<channel>[^/]+)
    )
""", re.VERBOSE))
class DLive(Plugin):
    URL_LIVE = "https://live.prd.dlive.tv/hls/live/{username}.m3u8"

    QUALITY_WEIGHTS = {
        "src": 1080,
    }

    @classmethod
    def stream_weight(cls, key):
        weight = cls.QUALITY_WEIGHTS.get(key)
        if weight:
            return weight, "dlive"

        return super().stream_weight(key)

    def _get_streams_video(self, video):
        log.debug(f"Getting video HLS streams for {video}")
        hls_url = self.session.http.get(self.url, schema=validate.Schema(
            validate.regex(re.compile(r'"playbackUrl"\s*:\s*"([^"]+\.m3u8)"')),
            validate.get(1),
            validate.transform(unquote_plus),
            validate.transform(lambda url: bytes(url, "utf-8").decode("unicode_escape")),
            validate.url(),
        ))

        return HLSStream.parse_variant_playlist(self.session, hls_url)

    def _get_streams_live(self, channel):
        log.debug(f"Getting live HLS streams for {channel}")
        query = f"""query {{
            userByDisplayName(displayname:"{channel}") {{
                livestream {{
                    title
                }}
                username
            }}
        }}"""
        livestream, username = self.session.http.post(
            "https://graphigo.prd.dlive.tv/",
            json={"query": query},
            schema=validate.Schema(
                validate.parse_json(),
                {
                    "data": {
                        "userByDisplayName": {
                            "livestream": {
                                "title": str,
                            },
                            "username": str,
                        },
                    },
                },
                validate.get(("data", "userByDisplayName")),
                validate.union_get("livestream", "username"),
            ),
        )

        self.author = channel
        self.title = livestream["title"]

        return HLSStream.parse_variant_playlist(self.session, self.URL_LIVE.format(username=username), headers={"Referer": "https://dlive.tv/"})

    def _get_streams(self):
        video = self.match.group("video")
        channel = self.match.group("channel")

        if video:
            return self._get_streams_video(video)
        elif channel:
            return self._get_streams_live(channel)


__plugin__ = DLive

src/streamlink/plugins/dlive.py
diff --git a/src/streamlink/plugins/dlive.py b/src/streamlink/plugins/dlive.py
index 1dc5bf510e8..d337dc683c3 100644
--- a/src/streamlink/plugins/dlive.py
+++ b/src/streamlink/plugins/dlive.py
@@ -86,7 +86,7 @@ def _get_streams_live(self, channel):
         self.author = channel
         self.title = livestream["title"]
 
-        return HLSStream.parse_variant_playlist(self.session, self.URL_LIVE.format(username=username))
+        return HLSStream.parse_variant_playlist(self.session, self.URL_LIVE.format(username=username), headers={"Referer": "https://dlive.tv/"})
 
     def _get_streams(self):
         video = self.match.group("video")

plugins.dlive: Failed to fetch segment | 403 Client Error
### 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

[cli][info] Your Streamlink version (6.2.1) is up to date!

### Description

I navigate to the folder where streamlink.exe is located and enter the command "streamlink.exe https://dlive.tv/cryptokaprika best". It doesn't matter which channel is specified, the same error comes up for all of them as of late.


Here is the complete output that is shown to me in the command line:


C:\Program Files\Streamlink\bin>streamlink.exe https://dlive.tv/cryptokaprika best

[cli][info] Found matching plugin dlive for URL https://dlive.tv/cryptokaprika

[cli][info] Available streams: src (worst, best)

[cli][info] Opening stream: src (hls)

[cli][info] Starting player: C:\Program Files\VideoLAN\VLC\vlc.exe

[stream.hls][error] Failed to fetch segment 79790: Unable to open URL: https://videos.prd.dlivecdn.com/dlive/0000079790.ts (403 Client Error: Forbidden for url: https://videos.prd.dlivecdn.com/dlive/0000079790.ts)

[stream.hls][error] Failed to fetch segment 79791: Unable to open URL: https://videos.prd.dlivecdn.com/dlive/0000079791.ts (403 Client Error: Forbidden for url: https://videos.prd.dlivecdn.com/dlive/0000079791.ts)

[cli][info] Stream ended

[cli][info] Closing currently open stream...


The VLC Media Player also starts, but I only get the following picture and am referred to the homepage: [https://imgur.com/a/NpuAHQ3](https://imgur.com/a/NpuAHQ3)

### Debug log

```text
C:\Program Files\Streamlink\bin>streamlink.exe --loglevel=debug https://dlive.tv/cryptokaprika best
[cli][debug] OS:         Windows 10
[cli][debug] Python:     3.11.5
[cli][debug] OpenSSL:    OpenSSL 3.0.9 30 May 2023
[cli][debug] Streamlink: 6.2.1
[cli][debug] Dependencies:
[cli][debug]  certifi: 2023.7.22
[cli][debug]  isodate: 0.6.1
[cli][debug]  lxml: 4.9.3
[cli][debug]  pycountry: 22.3.5
[cli][debug]  pycryptodome: 3.19.0
[cli][debug]  PySocks: 1.7.1
[cli][debug]  requests: 2.31.0
[cli][debug]  trio: 0.22.2
[cli][debug]  trio-websocket: 0.11.1
[cli][debug]  typing-extensions: 4.8.0
[cli][debug]  urllib3: 2.0.6
[cli][debug]  websocket-client: 1.6.3
[cli][debug] Arguments:
[cli][debug]  url=https://dlive.tv/cryptokaprika
[cli][debug]  stream=['best']
[cli][debug]  --loglevel=debug
[cli][debug]  --ffmpeg-ffmpeg=C:\Program Files\Streamlink\ffmpeg\ffmpeg.exe
[cli][info] Found matching plugin dlive for URL https://dlive.tv/cryptokaprika
[plugins.dlive][debug] Getting live HLS streams for cryptokaprika
[utils.l10n][debug] Language code: en_US
[cli][info] Available streams: src (worst, best)
[cli][info] Opening stream: src (hls)
[cli][info] Starting player: C:\Program Files\VideoLAN\VLC\vlc.exe
[stream.hls][debug] Reloading playlist
[cli][debug] Pre-buffering 8192 bytes
[stream.hls][debug] First Sequence: 79786; Last Sequence: 79791
[stream.hls][debug] Start offset: 0; Duration: None; Start Sequence: 79786; End Sequence: 79791
[stream.hls][debug] Adding segment 79786 to queue
[stream.hls][debug] Adding segment 79787 to queue
[stream.hls][debug] Adding segment 79788 to queue
[stream.hls][debug] Adding segment 79789 to queue
[stream.hls][debug] Adding segment 79790 to queue
[stream.hls][debug] Adding segment 79791 to queue
[stream.segmented][debug] Closing worker thread
[stream.hls][debug] Writing segment 79786 to output
[stream.hls][debug] Segment 79786 complete
[cli.output][debug] Opening subprocess: ['C:\\Program Files\\VideoLAN\\VLC\\vlc.exe', '--input-title-format', 'https://dlive.tv/cryptokaprika', '-']
[stream.hls][debug] Writing segment 79787 to output
[stream.hls][debug] Segment 79787 complete
[stream.hls][debug] Writing segment 79788 to output
[stream.hls][debug] Segment 79788 complete
[stream.hls][debug] Writing segment 79789 to output
[stream.hls][debug] Segment 79789 complete
[cli][debug] Writing stream to output
[stream.hls][error] Failed to fetch segment 79790: Unable to open URL: https://videos.prd.dlivecdn.com/dlive/0000079790.ts (403 Client Error: Forbidden for url: https://videos.prd.dlivecdn.com/dlive/0000079790.ts)
[stream.hls][error] Failed to fetch segment 79791: Unable to open URL: https://videos.prd.dlivecdn.com/dlive/0000079791.ts (403 Client Error: Forbidden for url: https://videos.prd.dlivecdn.com/dlive/0000079791.ts)
[stream.segmented][debug] Closing writer thread
[cli][info] Stream ended
[cli][info] Closing currently open stream...
```

