jackyzy823 / rajiko

A tool for unblocking geolocation restriction of radiko.jp!
The Unlicense
211 stars 24 forks source link

Rajiko

Warning:

This addon will not work on Manifest V3 with only declarativeNetRequest API.

So if Chromium based browsers totally abandon MV2 in the future, I'll stop maintaining for these browsers.

How to use:

  1. Install it from Chrome webstore or Firefox addons. For Firefox Android users, before Addons General Availability, you need to use Beta/Nightly with Addons Collections to use Radiko.
  2. Do nothing or change default area by clicking icon which only affects live area.
  3. Recording live or download timeshift by clicking icon.
  4. Click icon or click pause button to stop recording.

Permission Details:

  1. activeTab : to get tab's url to decide whether auto refresh or alert or which radio to record.
  2. cookies : for force setting radiko.jp's current location.
  3. storage : for storing your location configuration.
  4. webRequest : modify request to pass the authentication.
  5. webRequestBlocking : modify request to pass the authentication.
  6. *://*.radiko.jp/* : the only site we aimed at.
  7. declartiveContent : [TODO] for showing icon only on radiko pages.But firefox does not support this api.When firefox supports this api,tab permission will not be required.
  8. downloads : for downloading recored audio.
  9. *://*.smartstream.ne.jp/* : the site where audio stored.
  10. unlimitedStorage : for recording radio.

What's new:

Suppport List:

Known Issue:

Why I do this:

An overseas fan of Kalafina wanted to listen to the radio program 'Kalafina倶楽部 ' which was ended a few days after this extension have been developed.

Technical Details:

  1. How it works?

    The authentication of pc(html5) version radkio validates user's location via ip address.

    However the android version of radkio validates user via geolocation provided by GPS(if possible),not via user's ip.

    So why don't we use the authentication method of android version in pc to bypass ip check?

    The authentication includes two step:

    1. auth1

      request : platform_info , user_id

      response : a token to be valid, full_key_offset ,partial_key_length

    2. auth2

      request: token ,platform_info ,user_id, a parital key generated by full key and offset , connection type (in android), gps location(in android)

      response: Your location (and your token is valid for only this location) / OUT

    In the pc version,the full key is simplely placed in the javascript code in apps/js/playerCommon.js :

    player = new RadikoJSPlayer($audio[0], 'pc_html5', 'bcd151073c03b352e1ef2fd66c32209da9ca0afa' /*full key*/ ...

    However the android version's full key is protected by native dynamic librarys.Obviously the key is much longer than that in pc version.

  2. But how do you generate the partialkey/how do you get fullkey?

    By reversing android dynamic library,You can get the fullkey from .data segment after bypassing the root check ,emulator check and lots of anti-debugging tricks and waiting for itself to repair the .data segment.

ABOUT AAC

  1. HLS(HTTP Live Streaming) using Packed Audio see : https://tools.ietf.org/html/draft-pantos-http-live-streaming-23 which is ID3 tag + audio sample(AAC_ADTS,MP3,AC3)
  2. About com.apple.streaming.transportStreamTimestamp ? Could i use this to sort?(yes) PTS -> (stamp2 - stamp1) / (90*1000.0) https://blog.csdn.net/qq_32430349/article/details/50218317
  3. Drop all ID3 tag? see id3 in hls :https://helpx.adobe.com/adobe-media-server/dev/timed-metadata-hls-hds-streams.html
  4. ID3 header -> size PRIV Frame header (PRIV size flag) -> identi end with \x00 64bit data (31bit 0 and 33bit data bigendian) frame header see http://id3.org/id3v2.4.0-structure priv see http://id3.org/id3v2.4.0-frames

TODO

  1. Using ffmpeg.js (based on Emscripten:an LLVM-to-JavaScript compiler) concating ts segments to avoid 5s problem in mediaplayer.Note:size is about 13MB. (depercated : just drop id3 tags and simplely concat adts strem)

  2. Fake request headers more similarly (such as remove cookies and set accept,user agent,and etc) to avoid detection (partially done) due to the limitation of extension , cannot captialize some header's key

  3. Automatic switch location , no need for manually choice. (consider not supporting)

  4. Add recording function? (find solution on firefox -> webRequest.filterResponseData() and localstorge/chrome.storage -> downloads.download URL.createObjectURL(BlobObject), chrome may use xhr to save data , double trafic?) the right way to download data uri https://stackoverflow.com/questions/40269862/save-data-uri-as-file-using-downloads-download-api/40279050

    how to merge? (src site use hls.js to play m3u8 and aac) seems that directly concat is enough

  5. Force Firefox android load web page,not app download page.(done)

  6. consider generate different extension in different browser

    https://stackoverflow.com/questions/45911251/what-is-the-best-way-to-create-a-cross-browser-gmail-extension https://www.smashingmagazine.com/2017/04/browser-extension-edge-chrome-firefox-opera-brave-vivaldi/

  7. modify firefox android page to responsive page. (partially done)

  8. break the time limitation of timeshift and be able to download timeshift content (done)