Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[extractor,downloader/niconico] support new delivery server called Dowango Media Service(DMS) #8685

Closed
wants to merge 18 commits into from

Conversation

xpadev-net
Copy link

@xpadev-net xpadev-net commented Nov 30, 2023

Closes #9254

Support for downloading videos from the Dowango Media Service(DMS), which has been in use since November.
Dwango has announced that the old server (DMC) will be migrated to the new server (DMS) in stages.
ref: https://blog.nicovideo.jp/niconews/205042.html

For more information about this server, please refer to the following information
tor4kichi/Hohoema#961
Nico Nico Douga's new delivery server "domand" memo for 2023(ニコニコ動画の2023年新配信サーバー「domand」メモ) | scrapbox.io

Template

Before submitting a pull request make sure you have:

In order to be accepted and merged into yt-dlp each piece of code must be in public domain or released under Unlicense. Check all of the following options that apply:

  • I am the original author of this code and I am willing to release it under Unlicense

What is the purpose of your pull request?

  • Fix or improvement to an extractor (Make sure to add/update tests)

@xpadev-net xpadev-net changed the title [extractor,downloader/niconico] support new server called DMS(Dowango Media Service) [extractor,downloader/niconico] support new delivery server called Dowango Media Service(DMS) Nov 30, 2023
@pukkandan pukkandan added enhancement New feature or request site-enhancement Feature request for some website labels Nov 30, 2023
@xpadev-net
Copy link
Author

xpadev-net commented Jan 10, 2024

Copy link
Contributor

@pzhlkj6612 pzhlkj6612 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, @xpadev-net!

yt_dlp/extractor/niconico.py Outdated Show resolved Hide resolved
yt_dlp/extractor/niconico.py Outdated Show resolved Hide resolved
yt_dlp/extractor/niconico.py Outdated Show resolved Hide resolved
bashonly and others added 2 commits February 21, 2024 18:24
Co-authored-by: Mozi <29089388+pzhlkj6612@users.noreply.github.com>
Co-authored-by: Mozi <29089388+pzhlkj6612@users.noreply.github.com>
Reduce confusion and make the usage consistent throughout the file.
Copy link
Contributor

@pzhlkj6612 pzhlkj6612 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that both DMC and DMS code should be modified. In DMC's logic, the "label" field is also "NNNp", not a filesize in the form of | 4.2K .

yt_dlp/extractor/niconico.py Outdated Show resolved Hide resolved
yt_dlp/extractor/niconico.py Outdated Show resolved Hide resolved
xpadev-net and others added 4 commits February 23, 2024 00:50
Co-authored-by: Mozi <29089388+pzhlkj6612@users.noreply.github.com>
[extractor/niconico] refactor: call float_or_none() with kwargs
Co-authored-by: Mozi <29089388+pzhlkj6612@users.noreply.github.com>
@bmg0083dark
Copy link

yt-dlp.exe --ffmpeg-location ffmpeg.exe --batch-file batch-file.txt
--download-archive download-archive.txt --output "F:\data\mov\
%(playlist_title)s %(uploader)s %(title)s [%(id)s] %(resolution)s %(fps)sfps .%(ext)s"
--format "bestvideo+bestaudio/best" --ignore-errors --ignore-config
--no-cache-dir --no-overwrites --no-mtime --add-metadata
--rm-cache-dir --age-limit 50 --cookies-from-browser firefox:xxxx
--cookies cookies.txt

Extracting cookies from firefox
Extracted 1539 cookies from firefox
Cache is disabled (Did you combine --no-cache-dir and --rm-cache-dir?)
[generic] Extracting URL: https://www.nicovideo.jp/user/19266494/mylist?ref=pc_userpage_menu
[generic] mylist?ref=pc_userpage_menu: Downloading webpage
WARNING: [generic] Falling back on generic information extractor
[generic] mylist?ref=pc_userpage_menu: Extracting information
ERROR: Unsupported URL: https://www.nicovideo.jp/user/19266494/mylist?ref=pc_userpage_menu
[generic] Extracting URL: https://www.nicovideo.jp/user/93047623/video?ref=pc_userpage_menu
[generic] video?ref=pc_userpage_menu: Downloading webpage
WARNING: [generic] Falling back on generic information extractor
[generic] video?ref=pc_userpage_menu: Extracting information
ERROR: Unsupported URL: https://www.nicovideo.jp/user/93047623/video?ref=pc_userpage_menu

[niconico:series] Extracting URL: https://www.nicovideo.jp/user/116662252/series/184229?ref=user_series
[niconico:series] 184229: Downloading webpage
[download] Downloading playlist: BBQPitBoys.com
[niconico:series] Playlist BBQPitBoys.com: Downloading 31 items of 31
[download] Downloading item 1 of 31
[download] sm37916071: has already been recorded in the archive

Describe the error and what happened

[niconico] Extracting URL: https://www.nicovideo.jp/watch/sm38092414
[niconico] sm38092414: Downloading webpage
[info] sm38092414: Downloading 1 format(s): dms-h264-1080p-aac-128kbps-hls
[niconico_dms] Downloading from DMS
[niconico] sm38092414: Requesting Manifest Url
[download] Destination: F:\data\isyoku\mad\mpeg\mov\BBQPitBoys.com BBQPitBoysFun アイコニック ピッツ バーガー [sm38092414] 1920x1080 NAfps .mp4
[hls @ 000001b5b006e380] Skip ('#EXT-X-VERSION:6')
[hls @ 000001b5b006e380] Skip ('#EXT-X-INDEPENDENT-SEGMENTS')
[hls @ 000001b5b006e380] Opening 'https://delivery.domand.nicovideo.jp/hlsbid/656ccdce361105a0bdf7663f/playlists/media/audio-aac-128kbps.m3u8?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Expires=1708776766&Signature=jRqXGmr0Vwe1vtLa12ymqLfi53TNiEIZQp39CbZnrRkOPFPVZ3YTotJjYwKv88Hs04XMmXp5yRruJMeVHIcTN4ctosWRdXXnuueKULUPcEsfqiivN66TetCIZvI9vddQnoyQ9Vf82sfADrfvrsXgOgNRjcH4uQkPwFdXeKewmFDHPdUNv8hUuDl3fguVLwH6nzfMJeC78ulGXyAdg6DXR3r~HiN92UoDKf2eCqJHE0qAryqOWOAL4lacikqW0u3nCw3ZjYhed4n2Hv3-3t8X1kuaJwRrn0See3c0EVxjcywb2V4f4H3uHAUnDbhX7jUTNWjMD67nYqdSUlRwRA__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Skip ('#EXT-X-VERSION:6')
[https @ 000001b5b1d6a740] Opening 'https://delivery.domand.nicovideo.jp/hlsbid/656ccdce361105a0bdf7663f/playlists/media/video-h264-1080p.m3u8?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Expires=1708776766&Signature=VtGWZSX6iLaWIZBwdhXWRUit5MIU-S7f1CLCIZ9pPVfcpIKIpSUjBfsqPMsWooED0O-H92VcVQSGxiI0-g6o0dl-B7qdH6mNOhv2IGYOsWKJCFh4mwe52iSQuScuHBBDHWCRGQoMqvX9to6O9fcMuAp7my-At-pSLVwhEs-lizr7Zut4dVvo5xsGlmPZuGiOItZx7tsYQ9O3fYnnkiB7wCf7VHQzQTbARKDl7GIafl6B9vAP53daD2j-IpRNHOwUCl8gZWgltJrQFbkj4XmJlO1V7EA7ozzr53AASrKIYLbWnofQvbJPwwGtY2LFdfFLjqVYzsrCKzQIUlAw__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Skip ('#EXT-X-VERSION:6')
[hls @ 000001b5b006e380] Opening 'https://asset.domand.nicovideo.jp/656ccdce361105a0bdf7663f/audio/1/audio-aac-128kbps/init001.cmfa?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9hc3NldC5kb21hbmQubmljb3ZpZGVvLmpwLzY1NmNjZGNlMzYxMTA1YTBiZGY3NjYzZi9hdWRpby8xL2F1ZGlvLWFhYy0xMjhrYnBzLyoiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE3MDg3NzY3NjZ9fX1dfQ__&Signature=brOmUTeapVrS8Wtm34TMKZgcWxonGEqMxLQi4ALcn4ixajzbZCCAN6MmPIFo0THMTbn3tgGK7IddBH50MsZtVF0yHLqSBxrieqqpfJ6vqgl7KUeSLle-k-O5VNv7PlS0hIJ2vAX67yjktKPGyVUFr7VunhXQsD6Mf22ZBFaCKaB88vgPT823n7iyxyj9kwdiM62aGO1792vF2sbcJv6J9OkZQcEf6rqVUtAWbaPwwgnkRBnhTf5gcYPpLC10TGpSjf9LSu9qHLbWzeML3xuVrFg57J60H66Ioajpm8piRb-lZ5Rr3ba4HjooNxmSZ2hiZXYwgX-Vx1ShZ3thLXDw__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Opening 'https://delivery.domand.nicovideo.jp/hlsbid/656ccdce361105a0bdf7663f/keys/audio-aac-128kbps.key?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Expires=1708776766&Signature=mty2B8BV0JY8if1lFiI0SIGXEKicHHSuwWDtgoNiYyqHU0oM3NFuDtgffPpZZ7msHD3Y8LnnobpMgsWIZeiLQ6StGvasaa3hILIxjBIvMCimv-fiWyqgihw95-aBMprDARdfcXq4g8cTaVu8hKWfKr-YVF554Vu7DXxQQ3nIiHfAdpoy3WKnNoWiNxLSJQYrHG83imaQe5mi4VMRwQ57z4ComuZ0aCMLFp~kuTnHqQ67d2eN65qX2d57b8HeD7A5zwwyThI0ROKBiObLlR5DqYk2lzYHKff-Av0XDRQajj90HqMEHHSOqmJ-1UEltGvyB990co8xK5hyhgnQsu7Q__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Opening 'crypto+https://asset.domand.nicovideo.jp/656ccdce361105a0bdf7663f/audio/1/audio-aac-128kbps/001.cmfa?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9hc3NldC5kb21hbmQubmljb3ZpZGVvLmpwLzY1NmNjZGNlMzYxMTA1YTBiZGY3NjYzZi9hdWRpby8xL2F1ZGlvLWFhYy0xMjhrYnBzLyoiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE3MDg3NzY3NjZ9fX1dfQ__&Signature=brOmUTeapVrS8Wtm34TMKZgcWxonGEqMxLQi4ALcn4ixajzbZCCAN6MmPIFo0THMTbn3tgGK7IddBH50MsZtVF0yHLqSBxrieqqpfJ6vqgl7KUeSLle-k-O5VNv7PlS0hIJ2vAX67yjktKPGyVUFr7VunhXQsD6Mf22ZBFaCKaB88vgPT823n7iyxyj9kwdiM62aGO1792vF2sbcJv6J9OkZQcEf6rqVUtAWbaPwwgnkRBnhTf5gcYPpLC10TGpSjf9LSu9qHLbWzeML3xuVrFg57J60H66Ioajpm8piRb-lZ5Rr3ba4HjooNxmSZ2hiZXYwgX-Vx1ShZ3thLXDw__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Opening 'https://asset.domand.nicovideo.jp/656ccdce361105a0bdf7663f/video/1/video-h264-1080p/init001.cmfv?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9hc3NldC5kb21hbmQubmljb3ZpZGVvLmpwLzY1NmNjZGNlMzYxMTA1YTBiZGY3NjYzZi92aWRlby8xL3ZpZGVvLWgyNjQtMTA4MHAvKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcwODc3Njc2Nn19fV19&Signature=fptn0RwFE2XQQN3pqPuY6iAkOcSYDh0TqUIgXxjt0OeczX1rLQIKMjIcN3XUeUM2bdcn9yJMjKyn-JTjT5hgSPRIMseofZHOTbQ90CHyoH57DntAlUWonim0enKEw0ciFQfuZWYVGixKuNc9syKZr3Gkep7SYVa673mDm2puCK2cUgEkYFmaojk3XjtNK2cBR9GS7UeiHCkUFu-LtzHIAq7zcLyVykafO-NfVmGScVKhmECxTAZfvf2fpRqDQWIMOYgognrH9xeGh8qQ7ynWLUzwxqu-OXAJ4L664MLt~r1PMAGNY5QVfFJ9LY8V8I1NsBdyERkjbSg05A__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Opening 'https://delivery.domand.nicovideo.jp/hlsbid/656ccdce361105a0bdf7663f/keys/video-h264-1080p.key?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Expires=1708776766&Signature=EnkMbyinHgXBUIQM9Gqeu8A4IBPNd1WTVOD9vRs-PwXcYdd2U3yYNNiHHkAgu6ChSxxGBygjXS1yNQGOsz56A0o27zQoiX-bYeLqDDnmpl4Rao9pVZ-f79GUmGLmPOw19KHHLlO1oKlJ-plXnTXTaS00YG~I8bK8YIpgpVClLmvTVoAvYoxziLBuT3UU4kb50u6xNdFvuEW4h0AygYwlGzczFVcQejXJVDDXrfqQwihfsuOEP3q9tb8GPqHMldv8vwaBOHVqWptULk107bTEFmUi76fAvo20XMaLtDQno56VsrVGbxD8TKEMk6OzRgGYHutHcvKRv4m5zsDRihWg__&Key-Pair-Id=K11RB80NFXU134' for reading
[hls @ 000001b5b006e380] Opening 'crypto+https://asset.domand.nicovideo.jp/656ccdce361105a0bdf7663f/video/1/video-h264-1080p/001.cmfv?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9hc3NldC5kb21hbmQubmljb3ZpZGVvLmpwLzY1NmNjZGNlMzYxMTA1YTBiZGY3NjYzZi92aWRlby8xL3ZpZGVvLWgyNjQtMTA4MHAvKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcwODc3Njc2Nn19fV19&Signature=fptn0RwFE2XQQN3pqPuY6iAkOcSYDh0TqUIgXxjt0OeczX1rLQIKMjIcN3XUeUM2bdcn9yJMjKyn-JTjT5hgSPRIMseofZHOTbQ90CHyoH57DntAlUWonim0enKEw0ciFQfuZWYVGixKuNc9syKZr3Gkep7SYVa673mDm2puCK2cUgEkYFmaojk3XjtNK2cBR9GS7UeiHCkUFu-LtzHIAq7zcLyVykafO-NfVmGScVKhmECxTAZfvf2fpRqDQWIMOYgognrH9xeGh8qQ7ynWLUzwxqu-OXAJ4L664MLt~r1PMAGNY5QVfFJ9LY8V8I1NsBdyERkjbSg05A__&Key-Pair-Id=K11RB80NFXU134' for reading
Input #0, hls, from 'https://delivery.domand.nicovideo.jp/hlsbid/656ccdce361105a0bdf7663f/playlists/variants/df79a175c1ba1cdc.m3u8?session=d3afb57204169fb5aa540fbdb336919edf79a175c1ba1cdc0000000065d9dd3ed8e92eef6d7243dd&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kZWxpdmVyeS5kb21hbmQubmljb3ZpZGVvLmpwL2hsc2JpZC82NTZjY2RjZTM2MTEwNWEwYmRmNzY2M2YvcGxheWxpc3RzL3ZhcmlhbnRzL2RmNzlhMTc1YzFiYTFjZGMubTN1OFxcPyoiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE3MDg3NzY3NjZ9fX1dfQ__&Signature=B1KW1hutZmkLo1VmFPFOG0moaPm-s021YwkJpHY-ewoROkbf3QgGFpIgWaT3nZymLtY4wMsJtRA74CCzQ7gGtP3TIx1DPOP8N1s9iYHBFMUMU8Q6GISF~dvlSxom6Ynk6NrCc1lKp1E8yWCBiX30eywKoFT6rEwRC5WXvvlYh15gL0kranSOT64mbQJihgHA3HgIz-6cHoP33P-8aNQnn-vw332l2T-ioNomMkDXXAbTwfeeY6SGQm6lnYEyS0tBAHzAxeUzHc8DF8VgofRI5hOxbveAvD1W9V9bKi4wQZg0DHTQzm8A8G2FqMM9Aqsqv83vBdqbselMgJrPYGDT-w__&Key-Pair-Id=K11RB80NFXU134':
Duration: 00:11:58.95, start: -0.046440, bitrate: 0 kb/s
Program 0
Metadata:
variant_bitrate : 5669864
Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 126 kb/s (default)
Metadata:
variant_bitrate : 5669864
comment : Main Audio
major_brand : iso5
minor_version : 512
compatible_brands: iso5cmfciso6mp41
encoder : Lavf58.76.100
Stream #0:1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 2743 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
Metadata:
variant_bitrate : 5669864
compatible_brands: iso6cmfcmp41
major_brand : iso6
minor_version : 512
encoder : Lavf58.76.100
Output #0, mp4, to 'file:F:\data\isyoku\mad\mpeg\mov\BBQPitBoys.com BBQPitBoysFun アイコニック ピッツ バーガー [sm38092414] 1920x1080 NAfps .mp4.part':
Metadata:
encoder : Lavf59.30.100
Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2743 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
Metadata:
variant_bitrate : 5669864
compatible_brands: iso6cmfcmp41
major_brand : iso6
minor_version : 512
encoder : Lavf58.76.100
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 126 kb/s (default)
Metadata:
variant_bitrate : 5669864
comment : Main Audio
major_brand : iso5
minor_version : 512
compatible_brands: iso5cmfciso6mp41
encoder : Lavf58.76.100
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
[hls @ 000001b5b006e380] Opening 'crypto+https://asset.domand.nicovideo.jp/656ccdce361105a0bdf7663f/audio/1/audio-aac-128

What is this hls? This causes DMS to take longer.

@pzhlkj6612
Copy link
Contributor

A new question: Do we really need the niconico DMS downloader?


For DMS, the current implementation gives us the following formats:

ID                             EXT RESOLUTION │  FILESIZE   TBR PROTO │ VCODEC   VBR ACODEC  ABR ASR MORE INFO
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
dms-h264-144p-aac-64kbps-hls   mp4 256x144    │ ~ 1.51MiB  221k dms   │ h264    153k aac     69k 44k DMS 144p hls
dms-h264-144p-aac-128kbps-hls  mp4 256x144    │ ~ 1.84MiB  269k dms   │ h264    153k aac    117k 44k DMS 144p hls
dms-h264-360p-aac-64kbps-hls   mp4 640x360    │ ~ 4.59MiB  672k dms   │ h264    603k aac     69k 44k DMS 360p hls
dms-h264-360p-aac-128kbps-hls  mp4 640x360    │ ~ 4.92MiB  720k dms   │ h264    603k aac    117k 44k DMS 360p hls
dms-h264-480p-aac-64kbps-hls   mp4 854x480    │ ~11.31MiB 1654k dms   │ h264   1585k aac     69k 44k DMS 480p hls
dms-h264-480p-aac-128kbps-hls  mp4 854x480    │ ~11.63MiB 1702k dms   │ h264   1585k aac    117k 44k DMS 480p hls
dms-h264-720p-aac-64kbps-hls   mp4 1280x720   │ ~14.16MiB 2071k dms   │ h264   2003k aac     69k 44k DMS 720p hls
dms-h264-720p-aac-128kbps-hls  mp4 1280x720   │ ~14.49MiB 2120k dms   │ h264   2003k aac    117k 44k DMS 720p hls
dms-h264-1080p-aac-64kbps-hls  mp4 1920x1080  │ ~27.50MiB 4023k dms   │ h264   3954k aac     69k 44k DMS 1080p hls
dms-h264-1080p-aac-128kbps-hls mp4 1920x1080  │ ~27.83MiB 4071k dms   │ h264   3954k aac    117k 44k DMS 1080p hls

If we directly parse the m3u8 playlist from https://nvapi.nicovideo.jp/v1/watch/{id}/access-rights/hls?actionTrackId={watchTrackId} and do some processing, we will get the following formats:

ID   EXT RESOLUTION FPS │   FILESIZE   TBR PROTO │ VCODEC        VBR ACODEC      ABR ASR MORE INFO
───────────────────────────────────────────────────────────────────────────────────────────────────
64   m4a audio only     │ ~479.86KiB   69k m3u8  │ audio only        aac         69k 44k Main Audio
128  m4a audio only     │ ~816.98KiB  117k m3u8  │ audio only        aac        117k 44k Main Audio
152  mp4 256x144     30 │ ~  1.04MiB  152k m3u8  │ avc1.4d401e  152k video only
603  mp4 640x360     30 │ ~  4.12MiB  603k m3u8  │ avc1.4d401e  603k video only
1585 mp4 854x480     30 │ ~ 10.84MiB 1585k m3u8  │ avc1.4d4020 1585k video only
2003 mp4 1280x720    30 │ ~ 13.69MiB 2003k m3u8  │ avc1.4d4020 2003k video only
3954 mp4 1920x1080   30 │ ~ 27.03MiB 3954k m3u8  │ avc1.64002a 3954k video only

Advantages:

  • Possibly due to the "m3u8" protocol, the concurrent download mechanism does not work with the current code. I tried to fix it but failed. The new implementation will produce "m3u8_native" formats.
  • Format combinations can be chosen by users. Downloading a silent film or an audio track is also supported.
  • The program will become shorter.

Doubtful points:

  • Is the heartbeat useless for DMS?

Test video: sm43273809 (56") - 【完結編】映画『ラブライブ!虹ヶ咲学園スクールアイドル同好会 完結編 第1章』【特報】 - ニコニコ


My implementaion:

from ..utils import (
    parse_bitrate,
    remove_end,
)


class NiconicoIE(InfoExtractor):
    def _real_extract(self, url):
        # api_data obtained

        formats = []

        # DMC stuff

        dms_data = traverse_obj(api_data, ({
            'videos': ('media', 'domand', 'videos', ..., {
                lambda item: item['id'] if item['isAvailable'] else None
            }),
            'audios': ('media', 'domand', 'audios', ..., {
                lambda item: (item['id'], {
                    'format_id': str(parse_bitrate(item['id'])),
                    'abr': float_or_none(item['bitRate'], scale=1000),
                    'asr': item['samplingRate'],
                    'acodec': 'aac',
                    'ext': 'm4a',
                }) if item['isAvailable'] else None
            }),
            'accessRightKey': ('media', 'domand', 'accessRightKey'),
            'track_id': ('client', 'watchTrackId'),
        }, {
            'videos': 'videos',
            'audios': ('audios', {lambda items: dict(items)}),
            'accessRightKey': 'accessRightKey',
            'track_id': 'track_id',
        }))

        dms_m3u8_url = traverse_obj(self._download_json(
            f'https://nvapi.nicovideo.jp/v1/watch/{video_id}/access-rights/hls', video_id,
            data=json.dumps({
                'outputs': list(itertools.product(dms_data['videos'], dms_data['audios']))
            }).encode(), query={'actionTrackId': dms_data['track_id']}, headers={
                'x-access-right-key': dms_data['accessRightKey'],
                'x-frontend-id': 6,
                'x-frontend-version': 0,
                'x-request-with': 'https://www.nicovideo.jp',
            }), ('data', 'contentUrl'))
        dms_fmts = self._extract_m3u8_formats(dms_m3u8_url, video_id)

        # update audio formats
        dms_audio_fmts = [fmt for fmt in dms_fmts if fmt['vcodec'] == 'none']
        for i, fmt in enumerate(dms_audio_fmts):
            format_id = remove_end(fmt['format_id'], '-%s' % fmt['format_note'])
            dms_audio_fmts[i].update(**(traverse_obj(dms_data, ('audios', format_id, {dict})) or {}))

        # remove duplicate video formats
        dms_video_fmts = [
            list(fmts)[0] for _, fmts in itertools.groupby(sorted([
                fmt for fmt in dms_fmts if fmt['vcodec'] != 'none'
            ], key=lambda fmt: fmt['tbr']), lambda fmt: fmt['url'])
        ]

        # correct video bitrate
        min_abr = traverse_obj(min(dms_audio_fmts, key=lambda fmt: fmt['abr']), ('abr'), default=0)
        for i, fmt in enumerate(dms_video_fmts):
            vbr = fmt['tbr'] - min_abr
            dms_video_fmts[i].update({
                'format_id': str(round(vbr)),
                'vbr': vbr,
                'tbr': None,
            })

        formats.extend(dms_video_fmts + dms_audio_fmts)

        # Start extracting information

.

@pukkandan
Copy link
Member

@pzhlkj6612 Could you make a new PR with it? Even if it is inferior to DMS, we can get a extractor-only solution reviewed and merged much easier than the DMS one (which edits downloader). This PR can still be discussed, but that could act as an immediate solution

@pzhlkj6612
Copy link
Contributor

@pukkandan Done, see #9282.

Copy link
Contributor

@pzhlkj6612 pzhlkj6612 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sampling rate things.

yt_dlp/extractor/niconico.py Show resolved Hide resolved
yt_dlp/extractor/niconico.py Outdated Show resolved Hide resolved
xpadev-net and others added 2 commits February 28, 2024 15:26
Co-authored-by: Mozi <29089388+pzhlkj6612@users.noreply.github.com>
Co-authored-by: Mozi <29089388+pzhlkj6612@users.noreply.github.com>
@xpadev-net xpadev-net closed this Mar 1, 2024
@bashonly
Copy link
Member

bashonly commented Mar 1, 2024

@xpadev-net Thank you for your work on this, you have received/will receive credit in the commit and changelog

Copy link
Contributor

@pzhlkj6612 pzhlkj6612 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this PR has been closed, I still found something valuable. 💎

To @xpadev-net : please do not apply any suggestions, go open new PR instead.

Comment on lines +450 to +452
api_data = self._download_json(
'https://www.nicovideo.jp/api/watch/v3_guest/%s?_frontendId=6&_frontendVersion=0&actionTrackId=AAAAAAAAAA_%d' % (video_id, round(time.time() * 1000)), video_id,
note='Downloading API JSON', errnote='Unable to fetch data')['data']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion

Suggested change
api_data = self._download_json(
'https://www.nicovideo.jp/api/watch/v3_guest/%s?_frontendId=6&_frontendVersion=0&actionTrackId=AAAAAAAAAA_%d' % (video_id, round(time.time() * 1000)), video_id,
note='Downloading API JSON', errnote='Unable to fetch data')['data']
api_data = self._download_json(
'https://www.nicovideo.jp/api/watch/v3_guest/%s?_frontendId=6&_frontendVersion=0&actionTrackId=AAAAAAAAAA_%d' % (video_id, round(time.time() * 1000)), video_id,
note='Downloading API JSON', errnote='Unable to fetch data', expected_status=(400))['data']

This API will return HTTP 400 but some info of the video.

Why am I here

In #9338 (comment) , I couldn't get the "api_data" JSON from some videos. No json means no metadata. The "v3_guest" API solved my problem.

As a guest, I tested anime episode so43309069 - 戦国妖狐 世直し姉弟編 #3「永禄七年」 アニメ/動画 - ニコニコ動画 without valid Cookies:

VIDEO_ID='so43309069'

curl --silent --get \
  --data '_frontendId=6' \
  --data '_frontendVersion=0' \
  --data "actionTrackId=$(mktemp -u XXXXXXXXXX)_$(date '+%s')000" \
  "https://www.nicovideo.jp/api/watch/v3_guest/${VIDEO_ID}" | \
jq '
  {
    "meta": .meta,
    "data": {
      "reason": .data.reasonCode,
      "duration": .data.data.video.duration,
      "comment_count": .data.data.video.count.comment
    }
  }
'

With Japan IP:

{
  "meta": {
    "status": 400,
    "errorCode": "FORBIDDEN"
  },
  "data": {
    "reason": "PPV_VIDEO",
    "duration": null,
    "comment_count": null
  }
}

Without Japan IP:

{
  "meta": {
    "status": 400,
    "errorCode": "FORBIDDEN"
  },
  "data": {
    "reason": "DOMESTIC_VIDEO",
    "duration": 1419,
    "comment_count": 3830
  }
}

"DOMESTIC_VIDEO" means geo-restriction. "PPV_VIDEO" means "premium_only".

For members-only videos in fanclubs:

{
  "meta": {
    "status": 400,
    "errorCode": "FORBIDDEN"
  },
  "data": {
    "reason": "PPV_OR_CHANNEL_MEMBER_VIDEO",
    "duration": null,
    "comment_count": null
  }
}
{
  "meta": {
    "status": 400,
    "errorCode": "FORBIDDEN"
  },
  "data": {
    "reason": "CHANNEL_MEMBER_ONLY",
    "duration": null,
    "comment_count": null
  }
}

In #9338 (comment) , I wrote :

The fanclub of so43204345 might have mis-configured its payment method. I didn't see a PPV option, but only the "join" button.

Hence, both "PPV_OR_CHANNEL_MEMBER_VIDEO" and "CHANNEL_MEMBER_ONLY" mean "subscriber_only".

Conclusion

With the "v3_guest" API, we are able to extract more information. I think @xpadev-net should add this to the niconico IE by opening a new PR.

Comment on lines +498 to +499
actual_video_id = traverse_obj(api_data, ('video', 'id'))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Did you encounter some problems with the video id?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request site-enhancement Feature request for some website
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nicovideo.jp "ERROR: 'NoneType' object is not subscriptable"
5 participants