this is more of a documentation than a how-to, a bit of technical knowledge is required
UPDATE: the session id endpoint now returns 403 if you are not authenticated
“fanclub” sites are https://portal.nicochannel.jp and sites dedicated to one person, using the same website layout and infrastructure
here are a few of those sites as example
the api base url is https://nfc-api.<domain>/fc
where <domain>
is the domain of the site, so for example nicochannel.jp
or canan8181.com
fanclub sites use hls to play streams and videos, the m3u8 playlist is obtained through the api
the url to the m3u8 is constructed like this
https://hls-auth.cloud.stream.co.jp/auth/index.m3u8?session_id={session_id}
this format can be found at the /video_pages/<id>
endpoint under data -> video_page -> video_stream -> authenticated_url
to get the session_id, make a POST
request with an empty json object {}
as body to the /video_pages/<id>/session_ids
endpoint
as of right now (30th August 23) this endpoint requires the following header, this will likely change in the future
Content-Type: application/json
Fc_use_device: null
Origin: https://<domain>
no authentication is required for this endpoint, it works regardless of if you should have access to the content or not
this has been the case for over a year now and it seems to be either intentionally ignored by dwango or something is stopping them from implementing an authorization system
the returned json looks like this
{"data":{"session_id":"d463c750-3385-4708-a7ef-76ec6ece61a3"}}
now using the full url, you can access the m3u8 which is a master playlist containing all available quality options
the playlist for each quality contains the urls to the segments and an decryption key
unlike everything else, the decryption key is only accessible if you send a valid user agent
otherwise it will return the text Forbidden
instead of the key, which downloaders like yt-dlp usually show as some kind of “key is not 16 bytes long” error
also note that a few months ago dwango has decided to completely block firefox, that means you can not use its user agent to access the key
finally, here are a couple examples of how you can get the session_id
curl -X POST --data {} -H "Content-Type: application/json" -H "Fc_use_device: null" -H "Origin: https://<domain>" https://nfc-api.<domain>/fc/video_pages/<id>/session_ids
import httpx
resp = httpx.post(f"https://nfc-api.<domain>/fc/video_pages/<id>/session_ids", json={},
headers={
"Fc_use_device": "null",
"Origin": <domain>
}
)
print("https://hls-auth.cloud.stream.co.jp/auth/index.m3u8?session_id=" + resp.json()["data"]["session_id"])