HOW RADIKO'S STREAMS WORK THESE DAYS

The process of getting the m3u8 works the same as normal (with the X-Radiko-Authtoken header) so I won't go into it here

If you are using ffmpeg, you should add the arguments -http_seekable 0 -seekable 0 , otherwise ffmpeg will send Range headers which the stream rejects.

If you just want to record it in real-time then that's all there is to it, you just wait

BUT that's a ballache
fortunately there is a solution if you don't mind getting a bit fiddly (more complicated than just feeding the url to some downloader)


first let me explain a bit about the stream URL/ the url parameters it takes
these two^ are the ones we're interested in.

Setting l is useful even if you do nothing else, because you can get a 5-minute "head start" on the download. (because it gives you 5 mins worth of fragments from the start, instead of the default 15s)

this is where the fiddly bit comes in

You can't seek in the "as-live" stream.
but, you seem to be able to do it on the website. how do they manage that?
well, they don't really. When you seek on the website, it requests a whole new playlist that starts from the place you want, using the seek parameter.

NOW, we can do this too!
we can download the programme into 5-minute chunks, download those, and combine them into the full programme.
quite similar to how HLS itself works in fact

IMPLEMENTATION

NB
, all "times" are in YYYYMMDDhhmmss, eg 20260127160000

First, set our start/end times according to the programme,  set our l to 300, and the seek to the start time

get the first playlist.
make sure to find the *real* duration of all the fragments, because sometimes it doesnt add up to 300. (i think so that they can have a clean split for ad insertion)
you can do this by summing up the #EXTINF tags in the m3u8, or by calculating from the actual audio segments, whichever is easier for your implementation.
If you don't do this, then your download could have duplicated fragments, ie the programme will repeat itself the programme will repeat itself
round the real duration, and increment your seek parameter by that amount of seconds

NB, the playlist is still "live"! but you shouldn't treat it as live. just take the segments it gives you and leave, like normal on-demand hls.

Now that you've updated the seek parameter, do the same again with that url.
continue until you reach the end.

merge all the chunks together, and lo and behold, you have the full programme.

You could change the ft/start_at parameters instead of seek, and get the same result. But the site uses seek and i feel it's better to follow what the site does so you don't stand out too much.

EXAMPLE

You would download these "chunk" urls for a 1 hour programme with no funny business
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125230000
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125230500
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125231000
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125231500
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125232000
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125232500
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125233000
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125233500
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125234000
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125234500
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125235000
https://dr-wowza.radiko-cf.com/tf/playlist.m3u8?station_id=CCL&l=300&lsid=[removed]&type=b&start_at=20260125230000&ft=20260125230000&end_at=20260126000000&to=20260126000000&seek=20260125235500


you can see some implementations in the rajiko browser extension, my plugin yt-dlp-rajiko, and uru2's rec_radiko_ts.sh

hopefully this is helpful