streamlink
streamlink copied to clipboard
plugins.chzzk: new plugin
@bastimeyer I've fixed code lint and some exception handling, and added VOD feature. BTW, the validation schema rule seems to work fine, but what is your RFC saying about it? And I didn't add the Low-Latency feature because there are a lot of things to consider, even though the service is in beta.
Thanks for the update. There are still quite a few issues left though. Instead of reviewing and annotating the code issues, I decided to update the plugin and put it into proper shape myself, so it gets done quicker. I therefore force-pushed the changes onto your PR branch (which is master).
This however doesn't mean that the plugin will get merged into Streamlink's master branch now. The site is still in beta, and a working plugin doesn't change this fact.
Btw, good catch with the MPEG2 transport stream adaptation sets of the VOD DASH streams. The low latency live HLS streams are currently not supported by Streamlink, because the new HLS spec hasn't been finalized yet and partial segments have not been implemented here yet. The LLHLS playlists could be used instead, as it's backwards compatible, but it wouldn't make a difference.
Quick verification with a random stream and VOD:
$ ./script/test-plugin-urls.py chzzk -r CHANNEL_ID 4b2f27574a2e60d15bd53f94cbfc4066 -r VIDEO_ID 1856
:: Finding streams for URL: https://chzzk.naver.com/live/4b2f27574a2e60d15bd53f94cbfc4066
:: Found streams: 144p, 360p, 480p, 720p, 1080p, worst, best
:: Finding streams for URL: https://chzzk.naver.com/video/1856
:: Found streams: 144p, 480p, 720p, 1080p, worst, best
$ streamlink --json https://chzzk.naver.com/live/4b2f27574a2e60d15bd53f94cbfc4066 best | jq .metadata
{
"id": "4144373",
"author": "코렛트1",
"category": "",
"title": "치지직의 코렛트"
}
$ streamlink --json https://chzzk.naver.com/video/1856 best | jq .metadata
{
"id": "1856",
"author": "따효니 DDaHyoNi",
"category": null,
"title": "자낳대 라스트 내전."
}
$ streamlink -l debug https://chzzk.naver.com/live/4b2f27574a2e60d15bd53f94cbfc4066 best
[cli][debug] OS: Linux-6.6.6-1-git-x86_64-with-glibc2.38
[cli][debug] Python: 3.11.6
[cli][debug] OpenSSL: OpenSSL 3.1.4 24 Oct 2023
[cli][debug] Streamlink: 6.5.0+2.ge0008e35
[cli][debug] Dependencies:
[cli][debug] certifi: 2023.11.17
[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.23.1
[cli][debug] trio-websocket: 0.11.1
[cli][debug] typing-extensions: 4.8.0
[cli][debug] urllib3: 2.1.0
[cli][debug] websocket-client: 1.6.4
[cli][debug] Arguments:
[cli][debug] url=https://chzzk.naver.com/live/4b2f27574a2e60d15bd53f94cbfc4066
[cli][debug] stream=['best']
[cli][debug] --loglevel=debug
[cli][debug] --player=mpv
[cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/live/4b2f27574a2e60d15bd53f94cbfc4066
[utils.l10n][debug] Language code: en_US
[stream.ffmpegmux][debug] ffmpeg version n6.1 Copyright (c) 2000-2023 the FFmpeg developers
[stream.ffmpegmux][debug] built with gcc 13.2.1 (GCC) 20230801
[stream.ffmpegmux][debug] configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-frei0r --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libharfbuzz --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librsvg --enable-librubberband --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpl --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-version3 --enable-vulkan
[stream.ffmpegmux][debug] libavutil 58. 29.100 / 58. 29.100
[stream.ffmpegmux][debug] libavcodec 60. 31.102 / 60. 31.102
[stream.ffmpegmux][debug] libavformat 60. 16.100 / 60. 16.100
[stream.ffmpegmux][debug] libavdevice 60. 3.100 / 60. 3.100
[stream.ffmpegmux][debug] libavfilter 9. 12.100 / 9. 12.100
[stream.ffmpegmux][debug] libswscale 7. 5.100 / 7. 5.100
[stream.ffmpegmux][debug] libswresample 4. 12.100 / 4. 12.100
[stream.ffmpegmux][debug] libpostproc 57. 3.100 / 57. 3.100
[stream.hls][debug] Using external audio tracks for stream 1080p (language=None, name=audio.stream)
[stream.hls][debug] Using external audio tracks for stream 720p (language=None, name=audio.stream)
[stream.hls][debug] Using external audio tracks for stream 480p (language=None, name=audio.stream)
[stream.hls][debug] Using external audio tracks for stream 360p (language=None, name=audio.stream)
[stream.hls][debug] Using external audio tracks for stream 144p (language=None, name=audio.stream)
[cli][info] Available streams: 144p (worst), 360p, 480p, 720p, 1080p (best)
[cli][info] Opening stream: 1080p (hls-multi)
[cli][info] Starting player: mpv
[stream.ffmpegmux][debug] Opening hls substream
[stream.hls][debug] Reloading playlist
[stream.ffmpegmux][debug] Opening hls substream
[stream.hls][debug] Reloading playlist
[utils.named_pipe][info] Creating pipe streamlinkpipe-1270134-1-5894
[utils.named_pipe][info] Creating pipe streamlinkpipe-1270134-2-6370
[stream.ffmpegmux][debug] ffmpeg command: /usr/bin/ffmpeg -nostats -y -i /tmp/streamlinkpipe-1270134-1-5894 -i /tmp/streamlinkpipe-1270134-2-6370 -c:v copy -c:a copy -map 0:v? -map 0:a? -map 1:a -copyts -f mpegts pipe:1
[stream.ffmpegmux][debug] Starting copy to pipe: /tmp/streamlinkpipe-1270134-1-5894
[stream.ffmpegmux][debug] Starting copy to pipe: /tmp/streamlinkpipe-1270134-2-6370
[cli][debug] Pre-buffering 8192 bytes
[stream.hls][debug] First Sequence: 17531; Last Sequence: 17533
[stream.hls][debug] Start offset: 0; Duration: None; Start Sequence: 17531; End Sequence: None
[stream.hls][debug] Adding segment 17531 to queue
[stream.hls][debug] Adding segment 17532 to queue
[stream.hls][debug] Adding segment 17533 to queue
[stream.hls][debug] Writing segment 17531 to output
[stream.hls][debug] Segment initialization 17531 complete
[stream.hls][debug] First Sequence: 17673; Last Sequence: 17675
[stream.hls][debug] Start offset: 0; Duration: None; Start Sequence: 17673; End Sequence: None
[stream.hls][debug] Adding segment 17673 to queue
[stream.hls][debug] Adding segment 17674 to queue
[stream.hls][debug] Adding segment 17675 to queue
[stream.hls][debug] Writing segment 17673 to output
[stream.hls][debug] Segment initialization 17673 complete
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Writing segment 17673 to output
[stream.hls][debug] Segment 17673 complete
[stream.hls][debug] Adding segment 17534 to queue
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Writing segment 17531 to output
[stream.hls][debug] Segment 17531 complete
[cli.output][debug] Opening subprocess: ['/home/basti/.local/bin/mpv', '--force-media-title=https://chzzk.naver.com/live/4b2f27574a2e60d15bd53f94cbfc4066', '-']
[stream.hls][debug] Writing segment 17674 to output
[stream.hls][debug] Segment 17674 complete
[cli][debug] Writing stream to output
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 17676 to queue
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Writing segment 17675 to output
[stream.hls][debug] Segment 17675 complete
[stream.hls][debug] Adding segment 17535 to queue
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Writing segment 17532 to output
[stream.hls][debug] Segment 17532 complete
[stream.hls][debug] Adding segment 17677 to queue
[stream.hls][debug] Writing segment 17676 to output
[stream.hls][debug] Segment 17676 complete
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 17536 to queue
[stream.hls][debug] Writing segment 17677 to output
[stream.hls][debug] Segment 17677 complete
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 17678 to queue
[stream.hls][debug] Adding segment 17679 to queue
[stream.hls][debug] Writing segment 17533 to output
[stream.hls][debug] Segment 17533 complete
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 17537 to queue
[stream.hls][debug] Writing segment 17678 to output
[stream.hls][debug] Segment 17678 complete
[cli][info] Player closed
[stream.ffmpegmux][debug] Closing ffmpeg thread
[stream.ffmpegmux][error] Error while writing to pipe /tmp/streamlinkpipe-1270134-2-6370: [Errno 32] Broken pipe
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[stream.ffmpegmux][debug] Pipe copy complete: /tmp/streamlinkpipe-1270134-1-5894
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[stream.ffmpegmux][debug] Closed all the substreams
[cli][info] Stream ended
[cli][info] Closing currently open stream...
$ streamlink -l debug https://chzzk.naver.com/video/1856 best
[cli][debug] OS: Linux-6.6.6-1-git-x86_64-with-glibc2.38
[cli][debug] Python: 3.11.6
[cli][debug] OpenSSL: OpenSSL 3.1.4 24 Oct 2023
[cli][debug] Streamlink: 6.5.0+2.ge0008e35
[cli][debug] Dependencies:
[cli][debug] certifi: 2023.11.17
[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.23.1
[cli][debug] trio-websocket: 0.11.1
[cli][debug] typing-extensions: 4.8.0
[cli][debug] urllib3: 2.1.0
[cli][debug] websocket-client: 1.6.4
[cli][debug] Arguments:
[cli][debug] url=https://chzzk.naver.com/video/1856
[cli][debug] stream=['best']
[cli][debug] --loglevel=debug
[cli][debug] --player=mpv
[cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/video/1856
[utils.l10n][debug] Language code: en_US
[stream.dash][debug] Available languages for DASH audio streams: NONE (using: n/a)
[cli][info] Available streams: 144p (worst), 480p, 720p, 1080p (best)
[cli][info] Opening stream: 1080p (dash)
[cli][info] Starting player: mpv
[stream.dash][debug] Opening DASH reader for: ('69D251C533DDDEB1444A9B09557FB349DE0B', None, '7812b534-9ee7-11ee-b043-a0369ffabad8') - video/mp2t
[stream.dash.manifest][debug] Generating segment timeline for static playlist: ('69D251C533DDDEB1444A9B09557FB349DE0B', None, '7812b534-9ee7-11ee-b043-a0369ffabad8')
[cli][debug] Pre-buffering 8192 bytes
[stream.dash][debug] video/mp2t segment 0: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:08.574861Z)
[stream.dash][debug] video/mp2t segment 1: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:12.939930Z)
[stream.dash][debug] video/mp2t segment 0: completed
[cli.output][debug] Opening subprocess: ['/home/basti/.local/bin/mpv', '--force-media-title=https://chzzk.naver.com/video/1856', '-']
[cli][debug] Writing stream to output
[stream.dash][debug] video/mp2t segment 2: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:13.545367Z)
[stream.dash][debug] video/mp2t segment 1: completed
[stream.dash][debug] video/mp2t segment 3: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:14.139888Z)
[stream.dash][debug] video/mp2t segment 2: completed
[stream.dash][debug] video/mp2t segment 4: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:14.727860Z)
[stream.dash][debug] video/mp2t segment 3: completed
[stream.dash][debug] video/mp2t segment 5: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:15.325981Z)
[stream.dash][debug] video/mp2t segment 4: completed
[stream.dash][debug] video/mp2t segment 6: downloading (1970-01-01T00:00:00.000000Z / 2023-12-20T21:01:15.934503Z)
[stream.dash][debug] video/mp2t segment 5: completed
[cli][info] Player closed
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[stream.dash][warning] video/mp2t segment 6: aborted
[cli][info] Stream ended
[cli][info] Closing currently open stream...
Thank you for fixing the code to be more concise. FYI, Chzzk is expected to be officially released in February. Until then, I leave this PR in draft status for the reason that there might be any follow-ups, such as changes to the API specification.
It seems that chzzk login authentication has been added.
If logged in, information will be retrieved, but otherwise, information will not be retrieved.
No, they simply added a v2
API while the plugin was still based on v1
. This is exactly the reason why we don't merge plugins into master for sites which are still in beta. I've updated the plugin now. Streams and VODs seem to be working fine.
$ ./script/test-plugin-urls.py chzzk -r CHANNEL_ID fc00d47a77ed2d1156cd5997eba30310 -r VIDEO_ID 8642
:: Finding streams for URL: https://chzzk.naver.com/live/fc00d47a77ed2d1156cd5997eba30310
:: Found streams: 144p, 360p, 480p, 720p, 1080p, worst, best
:: Finding streams for URL: https://chzzk.naver.com/video/8642
:: Found streams: 144p, 480p, 720p, 1080p, worst, best
They changed more than just v1 to v2. With v2 they introduced 19+ streams (like AfreecaTV). To watch these streams, authentication is required. The name and birthday of the authenticated account has to be verified by Naver once: https://help.naver.com/service/5640/contents/20897?lang=en
19+ streams won't return the content.livePlaybackJson part in the json when https://api.chzzk.naver.com/service/v2/channels/{channel_id}/live-detail is called. If authentication is required, content.adult is set to true in the response.
It seems GET requests to https://api.chzzk.naver.com/service/v2/channels/{channel_id}/live-detail require a cookie to return content.livePlaybackJson for 19+ streams.
In order to watch such streams, pass the parameter --http-header Cookie='NID_SES=xxx; NID_AUT=xxx'
to streamlink. Without it, an error will be shown:
[cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/live/1ad5aa0f6c6741b072528fad5e5e76b1
[cli][error] Unable to validate response text: ValidationError(AnySchema):
ValidationError(dict):
Unable to validate value of key 'message'
Context(type):
Type of None should be str, but is NoneType
ValidationError(dict):
Unable to validate value of key 'livePlaybackJson'
Context(type):
Type of None should be str, but is NoneType
After exactly 9 hours, the stream breaks. Log is below. It seems some kind of expiration date is kicking in (hdntl=exp=1706567743 in my case). Is there anything that can be done to renew this before it expires?
[14:35:29.238999][cli][debug] Python: 3.11.6
[14:35:29.239139][cli][debug] OpenSSL: OpenSSL 3.2.0 23 Nov 2023
[14:35:29.239285][cli][debug] Streamlink: 6.5.1
[14:35:29.240179][cli][debug] Dependencies:
[14:35:29.251832][cli][debug] certifi: 2023.11.17
[14:35:29.255790][cli][debug] isodate: 0.6.1
[14:35:29.256802][cli][debug] lxml: 4.9.2
[14:35:29.265302][cli][debug] pycountry: 22.3.5
[14:35:29.266242][cli][debug] pycryptodome: 3.20.0
[14:35:29.267633][cli][debug] PySocks: 1.7.1
[14:35:29.271091][cli][debug] requests: 2.31.0
[14:35:29.272293][cli][debug] trio: 0.24.0
[14:35:29.273375][cli][debug] trio-websocket: 0.11.1
[14:35:29.278149][cli][debug] typing-extensions: 4.9.0
[14:35:29.286692][cli][debug] urllib3: 1.26.18
[14:35:29.303105][cli][debug] websocket-client: 1.7.0
[14:35:29.303469][cli][debug] Arguments:
[14:35:29.303611][cli][debug] url=https://chzzk.naver.com/live/f82903be1190262c1155674954a8ce35
[14:35:29.303734][cli][debug] stream=['best']
[14:35:29.303868][cli][debug] --loglevel=all
[14:35:29.304022][cli][debug] --logfile=/data/recorder/in-progress/sl.log
[14:35:29.304163][cli][debug] --output=/data/recorder/in-progress/f82903be1190262c1155674954a8ce35-20240129-20240129-2235-RN4293.ts
[14:35:29.304312][cli][debug] --retry-streams=15.0
[14:35:29.304432][cli][debug] --retry-max=60
[14:35:29.304548][cli][debug] --retry-open=15
[14:35:29.304665][cli][debug] --ringbuffer-size=50331648
[14:35:29.304781][cli][debug] --stream-segment-attempts=30
[14:35:29.304896][cli][debug] --stream-segment-threads=4
[14:35:29.305012][cli][debug] --stream-segment-timeout=10.0
[14:35:29.305128][cli][debug] --stream-timeout=90.0
[14:35:29.305263][cli][debug] --hls-playlist-reload-attempts=15
[14:35:29.305379][cli][debug] --hls-playlist-reload-time=segment
[14:35:29.305496][cli][debug] --hls-segment-queue-threshold=15.0
[14:35:29.305623][cli][debug] --ffmpeg-no-validation=True
[14:35:29.306068][cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/live/f82903be1190262c1155674954a8ce35
[14:35:32.432924][utils.l10n][debug] Language code: en_US
[14:35:33.922777][stream.hls.m3u8][all] #EXT-X-VERSION:7
[14:35:33.923039][stream.hls.m3u8][all] #EXT-X-INDEPENDENT-SEGMENTS
[14:35:33.923167][stream.hls.m3u8][all] #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="afrag1080p",NAME="audio.stream",AUTOSELECT=YES,CHANNELS="2",URI="hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_afrag1080p.m3u8"
[14:35:33.923408][stream.hls.m3u8][all] #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="afragalow.stream",NAME="audio.stream",AUTOSELECT=YES,CHANNELS="2",URI="hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_afragalow.stream.m3u8"
[14:35:33.923597][stream.hls.m3u8][all] #EXT-X-STREAM-INF:BANDWIDTH=8192000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="afrag1080p"
[14:35:33.923742][stream.hls.m3u8][all] hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag1080p.m3u8
[14:35:33.923968][stream.hls.m3u8][all] #EXT-X-STREAM-INF:BANDWIDTH=5192000,CODECS="avc1.64001F,mp4a.40.2",RESOLUTION=1280x720,AUDIO="afrag1080p"
[14:35:33.924320][stream.hls.m3u8][all] hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag720p.m3u8
[14:35:33.924495][stream.hls.m3u8][all] #EXT-X-STREAM-INF:BANDWIDTH=1692000,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=852x480,AUDIO="afrag1080p"
[14:35:33.924626][stream.hls.m3u8][all] hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag480p.m3u8
[14:35:33.924852][stream.hls.m3u8][all] #EXT-X-STREAM-INF:BANDWIDTH=992000,CODECS="avc1.4D401E,mp4a.40.2",RESOLUTION=640x360,AUDIO="afrag1080p"
[14:35:33.924998][stream.hls.m3u8][all] hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag360p.m3u8
[14:35:33.925163][stream.hls.m3u8][all] #EXT-X-STREAM-INF:BANDWIDTH=192000,CODECS="avc1.4D400C,mp4a.40.2",RESOLUTION=256x144,AUDIO="afragalow.stream"
[14:35:33.925306][stream.hls.m3u8][all] hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag144p.m3u8
[14:35:33.925728][stream.hls][debug] Using external audio tracks for stream 1080p (language=None, name=audio.stream)
[14:35:33.925950][stream.hls][debug] Using external audio tracks for stream 720p (language=None, name=audio.stream)
[14:35:33.926125][stream.hls][debug] Using external audio tracks for stream 480p (language=None, name=audio.stream)
[14:35:33.926304][stream.hls][debug] Using external audio tracks for stream 360p (language=None, name=audio.stream)
[14:35:33.926481][stream.hls][debug] Using external audio tracks for stream 144p (language=None, name=audio.stream)
[14:35:33.927289][cli][info] Available streams: 144p (worst), 360p, 480p, 720p, 1080p (best)
[14:35:33.927472][cli][info] Opening stream: 1080p (hls-multi)
[14:35:33.927768][cli][info] Writing output to
/data/recorder/in-progress/f82903be1190262c1155674954a8ce35-20240129-2235-RN4293.ts
[14:35:33.927886][cli][debug] Checking file output
[14:35:33.928047][stream.ffmpegmux][debug] Opening hls substream
[14:35:33.928967][stream.hls][debug] Reloading playlist
[14:35:33.930755][stream.ffmpegmux][debug] Opening hls substream
[14:35:33.931497][stream.hls][debug] Reloading playlist
[14:35:33.931711][utils.named_pipe][info] Creating pipe streamlinkpipe-43041-1-6071
[14:35:33.932272][utils.named_pipe][info] Creating pipe streamlinkpipe-43041-2-8695
[14:35:33.932532][stream.ffmpegmux][debug] ffmpeg command: /usr/bin/ffmpeg -nostats -y -i /tmp/streamlinkpipe-43041-1-6071 -i /tmp/streamlinkpipe-43041-2-8695 -c:v copy -c:a copy -map 0:v? -map 0:a? -map 1:a -copyts -f mpegts pipe:1
[14:35:33.934866][stream.ffmpegmux][debug] Starting copy to pipe: /tmp/streamlinkpipe-43041-1-6071
[14:35:33.935261][stream.ffmpegmux][debug] Starting copy to pipe: /tmp/streamlinkpipe-43041-2-8695
[14:35:33.957963][cli][debug] Pre-buffering 8192 bytes
[14:35:34.224935][stream.hls][debug] First Sequence: 5; Last Sequence: 7
[14:35:34.225058][stream.hls][debug] Start offset: 0; Duration: None; Start Sequence: 5; End Sequence: None
[14:35:34.225173][stream.hls][debug] Adding segment 5 to queue
[14:35:34.227822][stream.hls][debug] Adding segment 6 to queue
[14:35:34.230830][stream.hls][debug] Adding segment 7 to queue
[14:35:34.507620][stream.hls][debug] Writing segment 5 to output
[14:35:34.507926][stream.hls][debug] Segment initialization 5 complete
...
[23:35:45.057110][stream.hls][debug] Adding segment 16343 to queue
[23:35:45.057323][stream.hls][debug] Adding segment 16344 to queue
[23:35:46.235648][stream.hls][debug] Reloading playlist
[23:35:46.747210][stream.hls][debug] Reloading playlist
[23:37:13.396492][stream.ffmpegmux][error] Error while reading from substream: Read timeout
[23:37:40.436997][stream.hls][warning] Failed to reload playlist: Unable to open URL: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_afrag1080p.m3u8 (403 Client Error: Forbidden for url: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_afrag1080p.m3u8)
[23:37:40.437613][stream.hls][warning] No new segments in playlist for more than 30.00s. Stopping...
[23:37:40.437923][stream.segmented][debug] Closing worker thread
[23:37:40.471071][stream.hls][warning] Failed to reload playlist: Unable to open URL: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag1080p.m3u8 (403 Client Error: Forbidden for url: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/hls_chunklist_vfrag1080p.m3u8)
[23:37:40.471362][stream.hls][warning] No new segments in playlist for more than 30.00s. Stopping...
[23:37:40.471547][stream.segmented][debug] Closing worker thread
[23:37:40.474213][stream.segmented][debug] Closing writer thread
[23:37:40.474751][stream.ffmpegmux][debug] Pipe copy complete: /tmp/streamlinkpipe-43041-1-6071
[23:37:45.346803][stream.ffmpegmux][debug] Closing ffmpeg thread
[23:37:45.351042][stream.segmented][debug] Closing writer thread
[23:40:12.357906][stream.hls][error] Failed to fetch segment 16343: Unable to open URL: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/afrag1080p_691305293_1706567740801_32424_0_16343.m4a?type=hls&bitrate=29132&filetype=.m4a (403 Client Error: Forbidden for url: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/afrag1080p_691305293_1706567740801_32424_0_16343.m4a?type=hls&bitrate=29132&filetype=.m4a)
[23:40:12.365906][stream.hls][error] Failed to fetch segment 16344: Unable to open URL: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/afrag1080p_2801223308_1706567742785_32426_0_16344.m4a?type=hls&bitrate=29207&filetype=.m4a (403 Client Error: Forbidden for url: https://livecloud.akamaized.net/chzzk/lip2_kr2/anmss0647/kearacw3nkqwe55myd7kiecbdcfd30c9nv/hdntl=exp=1706567743~acl=*%2fkearacw3nkqwe55myd7kiecbdcfd30c9nv%2f*~data=hdntl~hmac=cd29dd926a9d1f37cb867d6e75639ec0bd1af07b1c573d2f018528e92cacf1b6/afrag1080p_2801223308_1706567742785_32426_0_16344.m4a?type=hls&bitrate=29207&filetype=.m4a)
[23:40:12.367595][stream.ffmpegmux][debug] Closed all the substreams
[23:40:12.373256][cli][info] Stream ended
[23:40:12.375458][cli][info] Closing currently open stream...
@umemoni256, Me too. After 9 hours, the recording stops with a 403. 😢
@umemoni256 @hoonnn @bastimeyer Hey guys. The token value expired 9 hours after it was issued, causing the recording to cut off in the middle. I revamped the code to reissue the token 3 hours before it expired and replace it in the URL fetching on the HLS playlist. I would appreciate some testing and code review.
Sorry, but I'm not going to merge these newly added changes here. Please restore the branch again to the previous commit or I will do it once this plugin is ready to be merged.
The initial plugin implementation should be focused on the basics, which commit 150edc9 achieved just fine (unless something has changed since it was created). An expiration timeout after 9 hours is considered an edge-case. Streamlink was never built for recording streams and it's still not the focus of the project today. This is partly the reason why the stream implementations are still lacking some extensibility capabilities. Just as a quick remark, in order for Streamlink to properly support recording which then can be advertised properly, many things will need to change on the side of both the streams API and CLI implementation.
This however doesn't mean that the plugin can't be improved with refresh logic for the expiration timeout in the future. The way this is done here though is not good. I am aware that you are trying to reload the multivariant playlist, which is of course a bit tricky, but this proposed implementation, ignoring all the other linting, typing and method/function-signature issues, is having lots of issues which makes it impossible to merge. You are overriding a ton of HLSStream logic here, which makes it an unmaintainable mess once the base classes need to get updated, apart from the fact that lots of other stuff from the overridden methods is missing.
A proper implementation should make sure that the base classes are extensible with a clean API, so subclasses can apply their extended logic which modifies the HLS stream behavior.
Also, please keep the coding style of the project in mind when submitting changes. We don't have strict code style linters/formatters configured, but this doesn't mean that we're going to merge anything that the Python interpreter will parse. Annotating all these style issues is way too tedious. Btw, these changes here don't pass ruff
and mypy
.
I understand that the points you've raised. Additionally, I recognize the challenges with linting and formatting due to local environment setup issues. I appreciate your intention to review for a Proof-of-Concept without fully considering code quality.
However, I would like to clarify one thing:
Are you suggesting that handling the expiration timeout as an edge-case and addressing it in an ad-hoc manner is problematic?
If so, I've observed that other plugins within Streamlink that override HLSStream also deal with their expiration logic in ways that might seem tricky [1] [2] [3]. Could you specify what distinguishes my approach from theirs and pinpoint where the issue lies?
@bastimeyer I resolved the issue by referring to this PR
Can it works in streamlink 6.2.0?
@HDSRK No, it is not supported. Only Streamlink version >=6.6.0 are supported. If you want to use it with a lower version, you can manually add the code directly from this commit file into the plugins directory. However, it will not be officially supported though.
Are you suggesting that handling the expiration timeout as an edge-case and addressing it in an ad-hoc manner is problematic?
No, it's not problematic, because playlist expirations are not part of the HLS specification and depend very much on how the streaming platform has implemented them. Plugins therefore always need custom logic in order to solve this type of issue. There can't be a generic solution.
What I was saying was (in the context of your previous changes) that overloading new plugins with tons of extra code is bad for edge cases like this. It's an edge case because it's an expiration timer of 9 hours in contrast to only a couple of minutes for example, which would make the plugin unusable.
I asked you to add playlist expiration logic after the basic plugin implementation has been merged, so extending it, reviewing the code and getting feedback is easier.
Your recent changes however already look much better, but I haven't checked it in detail yet. I can already see a couple of issues though which will require fixing. But as said, I don't want to review this here.
How can I use validate.union_get to extract the values of properties from the array inside media? I'm looking for a way to efficiently retrieve these values in a tuple.
Validation schema docs here: https://streamlink.github.io/api/validate.html#streamlink.plugin.api.validate._schemas.UnionGetSchema
The initial commit already turned the array's objects into tuples, so the result could be destructed/unpacked later on:
I'm getting this error when trying to get the stream url with the plugin and streamlink 6.6.2
is this a result of it being early days of the plugin and is there some kind of workaround to still get the m3u8 url from it?
Muxed stream outputs can't be represented as a single URL, hence this error message when trying to use --stream-url
.
And btw, the current state of the plugin with its refresh-expiration logic on top of the basic plugin implementation won't be merged, as I've said multiple times now.
I misunderstood what you meant at first, Thanks for your understanding @bastimeyer. I'll add the refresh-expiration logic after this PR is got to merge.
They changed more than just v1 to v2. With v2 they introduced 19+ streams (like AfreecaTV). To watch these streams, authentication is required. The name and birthday of the authenticated account has to be verified by Naver once: https://help.naver.com/service/5640/contents/20897?lang=en
19+ streams won't return the content.livePlaybackJson part in the json when https://api.chzzk.naver.com/service/v2/channels/{channel_id}/live-detail is called. If authentication is required, content.adult is set to true in the response.
It seems GET requests to https://api.chzzk.naver.com/service/v2/channels/{channel_id}/live-detail require a cookie to return content.livePlaybackJson for 19+ streams.
In order to watch such streams, pass the parameter
--http-header Cookie='NID_SES=xxx; NID_AUT=xxx'
to streamlink. Without it, an error will be shown:[cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/live/1ad5aa0f6c6741b072528fad5e5e76b1 [cli][error] Unable to validate response text: ValidationError(AnySchema): ValidationError(dict): Unable to validate value of key 'message' Context(type): Type of None should be str, but is NoneType ValidationError(dict): Unable to validate value of key 'livePlaybackJson' Context(type): Type of None should be str, but is NoneType
This seemed to work fine until recently and now the error comes up even with the cookie values. Anyone experiencing same issue?
C:\Users\Administrator>streamlink --loglevel=all https://chzzk.naver.com/live/c40ce04da08cbe2ffa0422210c5480de
[12:51:49.743644][cli][debug] OS: Windows 11
[12:51:49.744690][cli][debug] Python: 3.12.2
[12:51:49.744690][cli][debug] OpenSSL: OpenSSL 3.0.13 30 Jan 2024
[12:51:49.744690][cli][debug] Streamlink: 6.7.0
[12:51:49.745691][cli][debug] Dependencies:
[12:51:49.746745][cli][debug] certifi: 2024.2.2
[12:51:49.747746][cli][debug] isodate: 0.6.1
[12:51:49.747746][cli][debug] lxml: 5.1.0
[12:51:49.748821][cli][debug] pycountry: 23.12.11
[12:51:49.749832][cli][debug] pycryptodome: 3.20.0
[12:51:49.749832][cli][debug] PySocks: 1.7.1
[12:51:49.749832][cli][debug] requests: 2.31.0
[12:51:49.751334][cli][debug] trio: 0.24.0
[12:51:49.752350][cli][debug] trio-websocket: 0.11.1
[12:51:49.753355][cli][debug] typing-extensions: 4.10.0
[12:51:49.754370][cli][debug] urllib3: 2.2.1
[12:51:49.754370][cli][debug] websocket-client: 1.7.0
[12:51:49.754370][cli][debug] Arguments:
[12:51:49.755373][cli][debug] url=https://chzzk.naver.com/live/c40ce04da08cbe2ffa0422210c5480de
[12:51:49.755373][cli][debug] --loglevel=all
[12:51:49.755373][cli][debug] --player=E:\mpv\mpv.exe
[12:51:49.755373][cli][debug] --default-stream=['best']
[12:51:49.755373][cli][debug] --ringbuffer-size=629145600
[12:51:49.756876][cli][debug] --stream-segment-attempts=30
[12:51:49.756876][cli][debug] --stream-segment-threads=10
[12:51:49.756876][cli][debug] --stream-segment-timeout=20.0
[12:51:49.756876][cli][debug] --stream-timeout=50.0
[12:51:49.757901][cli][debug] --hls-live-edge=10
[12:51:49.758087][cli][debug] --ffmpeg-ffmpeg=C:\Program Files\Streamlink\ffmpeg\ffmpeg.exe
[12:51:49.758087][cli][debug] --http-header=[('Cookie', "'NID_SES=CookiePart1Replaced; NID_AUT=CookiePart2Replaced'")]
[12:51:49.758087][cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/live/c40ce04da08cbe2ffa0422210c5480de
error: Unable to validate response text: ValidationError(AnySchema):
ValidationError(dict):
Unable to validate value of key 'message'
Context(type):
Type of None should be str, but is NoneType
ValidationError(dict):
Unable to validate value of key 'livePlaybackJson'
Context(type):
Type of None should be str, but is NoneType
It seems like Chzzk is out of beta now. Is the plugin ready for merging?
This PR will require a few modifications before it can get merged. I will have a look later today when I get back home and then update it myself.
Is there an official statement somewhere that the site went out of its beta phase?
@bastimeyer
https://game.naver.com/lounge/chzzk/board/detail/4033868
@bastimeyer https://game.naver.com/lounge/chzzk/board/detail/4033868
Thanks! Here is also an easier to translate post: https://game.naver.com/lounge/chzzk/board/detail/4033764
I've force-pushed onto your PR-branch, @fml09, which btw is master
, so be aware of that when creating follow-up PRs.
The plugin should be fine now unless I've missed something. If you want to check and validate other streams, please go ahead. Then we can merge. Thanks.
$ ./script/test-plugin-urls.py chzzk -r CHANNEL_ID 3497a9a7221cc3ee5d3f95991d9f95e9 -r VIDEO_ID 1459675
:: Finding streams for URL: https://chzzk.naver.com/live/3497a9a7221cc3ee5d3f95991d9f95e9
:: Found streams: 144p, 360p, 480p, 720p, 1080p, worst, best
:: Finding streams for URL: https://chzzk.naver.com/video/1459675
:: Found streams: 144p, 720p, 1080p, worst, best
$ streamlink -l debug https://chzzk.naver.com/live/3497a9a7221cc3ee5d3f95991d9f95e9 best
[cli][debug] OS: Linux-6.8.6-1-git-x86_64-with-glibc2.39
[cli][debug] Python: 3.12.3
[cli][debug] OpenSSL: OpenSSL 3.3.0 9 Apr 2024
[cli][debug] Streamlink: 6.7.3+20.gda1eb135
[cli][debug] Dependencies:
[cli][debug] certifi: 2024.2.2
[cli][debug] exceptiongroup: 1.2.1
[cli][debug] isodate: 0.6.1
[cli][debug] lxml: 5.2.1
[cli][debug] pycountry: 23.12.11
[cli][debug] pycryptodome: 3.20.0
[cli][debug] PySocks: 1.7.1
[cli][debug] requests: 2.31.0
[cli][debug] trio: 0.25.0
[cli][debug] trio-websocket: 0.11.1
[cli][debug] typing-extensions: 4.11.0
[cli][debug] urllib3: 2.2.1
[cli][debug] websocket-client: 1.8.0
[cli][debug] Arguments:
[cli][debug] url=https://chzzk.naver.com/live/3497a9a7221cc3ee5d3f95991d9f95e9
[cli][debug] stream=['best']
[cli][debug] --loglevel=debug
[cli][debug] --player=/usr/bin/mpv
[cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/live/3497a9a7221cc3ee5d3f95991d9f95e9
[utils.l10n][debug] Language code: en_US
[cli][info] Available streams: 144p (worst), 360p, 480p, 720p, 1080p (best)
[cli][info] Opening stream: 1080p (hls)
[cli][info] Starting player: /usr/bin/mpv
[stream.hls][debug] Reloading playlist
[cli][debug] Pre-buffering 8192 bytes
[stream.hls][debug] First Sequence: 8561; Last Sequence: 8563
[stream.hls][debug] Start offset: 0; Duration: None; Start Sequence: 8561; End Sequence: None
[stream.hls][debug] Adding segment 8561 to queue
[stream.hls][debug] Adding segment 8562 to queue
[stream.hls][debug] Adding segment 8563 to queue
[stream.hls][debug] Writing segment 8561 to output
[stream.hls][debug] Segment initialization 8561 complete
[cli.output][debug] Opening subprocess: ['/usr/bin/mpv', '--force-media-title=https://chzzk.naver.com/live/3497a9a7221cc3ee5d3f95991d9f95e9', '-']
[cli][debug] Writing stream to output
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 8564 to queue
[stream.hls][debug] Writing segment 8561 to output
[stream.hls][debug] Segment 8561 complete
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 8565 to queue
[stream.hls][debug] Writing segment 8562 to output
[stream.hls][debug] Segment 8562 complete
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 8566 to queue
[cli][info] Player closed
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[cli][info] Stream ended
[cli][info] Closing currently open stream...
$ streamlink -l debug https://chzzk.naver.com/video/1459675 best
[cli][debug] OS: Linux-6.8.6-1-git-x86_64-with-glibc2.39
[cli][debug] Python: 3.12.3
[cli][debug] OpenSSL: OpenSSL 3.3.0 9 Apr 2024
[cli][debug] Streamlink: 6.6.1+10.g01c9f2d4.dirty
[cli][debug] Dependencies:
[cli][debug] certifi: 2024.2.2
[cli][debug] exceptiongroup: 1.2.1
[cli][debug] isodate: 0.6.1
[cli][debug] lxml: 5.2.1
[cli][debug] pycountry: 23.12.11
[cli][debug] pycryptodome: 3.20.0
[cli][debug] PySocks: 1.7.1
[cli][debug] requests: 2.31.0
[cli][debug] trio: 0.25.0
[cli][debug] trio-websocket: 0.11.1
[cli][debug] typing-extensions: 4.11.0
[cli][debug] urllib3: 2.2.1
[cli][debug] websocket-client: 1.8.0
[cli][debug] Arguments:
[cli][debug] url=https://chzzk.naver.com/video/1459675
[cli][debug] stream=['best']
[cli][debug] --loglevel=debug
[cli][debug] --player=/usr/bin/mpv
[cli][info] Found matching plugin chzzk for URL https://chzzk.naver.com/video/1459675
[utils.l10n][debug] Language code: en_US
[stream.dash][debug] Available languages for DASH audio streams: NONE (using: n/a)
[cli][info] Available streams: 144p (worst), 720p, 1080p (best)
[cli][info] Opening stream: 1080p (dash)
[cli][info] Starting player: /usr/bin/mpv
[stream.dash][debug] Opening DASH reader for: ('CB11586B7C4E93033D58DED0B06BBC892E14', None, '7535b304-0d9b-11ef-85c1-a0369ffdb798') - video/mp2t
[stream.dash.manifest][debug] Generating segment timeline for static playlist: ('CB11586B7C4E93033D58DED0B06BBC892E14', None, '7535b304-0d9b-11ef-85c1-a0369ffdb798')
[cli][debug] Pre-buffering 8192 bytes
[stream.dash][debug] video/mp2t segment 0: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:23.654517Z)
[stream.dash][debug] video/mp2t segment 1: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:27.441747Z)
[stream.dash][debug] video/mp2t segment 0: completed
[cli.output][debug] Opening subprocess: ['/usr/bin/mpv', '--force-media-title=https://chzzk.naver.com/video/1459675', '-']
[cli][debug] Writing stream to output
[stream.dash][debug] video/mp2t segment 2: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:28.048568Z)
[stream.dash][debug] video/mp2t segment 1: completed
[stream.dash][debug] video/mp2t segment 3: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:28.657800Z)
[stream.dash][debug] video/mp2t segment 2: completed
[stream.dash][debug] video/mp2t segment 4: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:29.264426Z)
[stream.dash][debug] video/mp2t segment 3: completed
[stream.dash][debug] video/mp2t segment 5: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:29.881816Z)
[stream.dash][debug] video/mp2t segment 4: completed
[stream.dash][debug] video/mp2t segment 6: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:30.501731Z)
[stream.dash][debug] video/mp2t segment 5: completed
[stream.dash][debug] video/mp2t segment 7: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:31.122724Z)
[stream.dash][debug] video/mp2t segment 6: completed
[stream.dash][debug] video/mp2t segment 8: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:31.737786Z)
[stream.dash][debug] video/mp2t segment 7: completed
[stream.dash][debug] video/mp2t segment 9: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:32.360098Z)
[stream.dash][debug] video/mp2t segment 8: completed
[stream.dash][debug] video/mp2t segment 10: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:32.973177Z)
[stream.dash][debug] video/mp2t segment 9: completed
[stream.dash][debug] video/mp2t segment 11: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:33.585996Z)
[stream.dash][debug] video/mp2t segment 10: completed
[stream.dash][debug] video/mp2t segment 12: downloading (1970-01-01T00:00:00.000000Z / 2024-05-09T19:12:34.191818Z)
[stream.dash][debug] video/mp2t segment 11: completed
[cli][info] Player closed
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[cli][info] Stream ended
[cli][info] Closing currently open stream...