Skip to content

fix: replace anidb with hianime provider - #1897

Open
U-L-M-S wants to merge 1 commit into
pystardust:masterfrom
U-L-M-S:hianime-improvements
Open

fix: replace anidb with hianime provider#1897
U-L-M-S wants to merge 1 commit into
pystardust:masterfrom
U-L-M-S:hianime-improvements

Conversation

@U-L-M-S

@U-L-M-S U-L-M-S commented Sep 6, 2026

Copy link
Copy Markdown

Replaces the offline anidb.app with hianime.at.

Credit

This is built on @Dhairya3391's work in #1894. The reverse engineering is theirs: the hianime endpoints, the HD-1 embed, and the base64(json XOR "otaku-embed-v1") deobfuscation all come from that PR, and they are credited as co-author on the commit. The external .vtt handling in that thread came from @Tsagar3.

What I did was rework it on top of master as a smaller diff, since @port19x said the original was too fat to review by hand, and fix the bugs I hit while testing it.

insertions deletions
#1894 +191 −58
this PR +82 −62

Bugs fixed relative to #1894

Search returned the "Top 10" sidebar. Those widgets use the same film-detail markup as the results grid, so ~30 unrelated titles were appended to every search, and a nonsense query returned 29 rows, meaning No results found! could never fire.

The subtitle regex picked the last track. "subtitles":\[[^]]*"src":"..." is greedy. Attack on Titan ep 1 has five tracks, all tagged "lang":"en", and the last is labelled Spanish. One Piece has one track, which is why it tests clean.

--skip got an empty MAL id. ani-skip ran before get_video_link, and mal_id was only assigned inside a command substitution, so it never reached the parent shell. hianime pages carry no MyAnimeList link, so the description scraper could not supply it either.

History from 5.0.x resolved to a different anime. anidb and hianime ids share the name-<n> shape, so old entries survived migration and the trailing number was sent to hianime as one of theirs. A history line of attack-on-titan-1 offered "Attack on Titan - episode 6" and played One Piece ep 6, then wrote that back. Every user upgrading from 5.0.x hits this on their first -c.

IINA and VLC could not take a subtitle URL. They only worked because #1894 downloads the .vtt locally first. --sub-files is a path list mpv splits on :, truncating the URL at its scheme; VLC's sub-file goes through vlc_path2uri(), which rewrites an https URL into a file:// path. Fixed by escaping the colons for IINA and using :input-slave= for VLC.

CI was red. shellcheck SC2312/SC2086/SC2249 and two shfmt complaints.

Structural changes

  • hianime_m3u8 runs in the parent shell and sets links, sub_link, mal_id and refr instead of printing. That removes both temp files, the six rm -f sites, replay_sub/replay_sub_file and the local .vtt download.
  • refr is derived from the embed URL instead of hardcoding zokoanime.video in ten places.
  • hianime_desc is dropped. hianime has no seasons block, so its regex was returning nav links, genres and studios. change_season re-searches the current title instead, which returns the real related entries.
  • Dropped the HD-2 fallback, since megaplay.buzz serves a different player deobfuscate_blob cannot read, and the X-Requested-With header, which neither endpoint needs.

Tested

shellcheck and shfmt clean, no awk/wget, exec bit set. Sub, dub, -r ranges, -c and --skip resolve under bash, busybox ash and bash --posix. Headless mpv loads video, audio and the external subtitle track, and gives 403 without the referer. yt-dlp --referer and ffmpeg -referer both download, and both 403 without it.

Known limitations

  • Android intents, catt and the iSH vlc:// handler cannot send a Referer header, so they cannot play from this provider. Same as fix: temp-fix #1894, not fixable in the script.
  • The IINA and VLC flags are derived from their source, not tested on a Mac. Confirmation from a macOS user would be welcome.
  • hianime serves a single 1080p variant right now, so -q mostly falls back to best. README and man page adjusted to say so.
  • Pre-existing, not introduced here: _http_code=${_response##* } in hianime_curl is quadratic in zsh, and the 1.1 MB episode list makes it take over a minute there. Harmless on any real /bin/sh.

Closes #1894 if the maintainers prefer this shape, otherwise happy for it to be cherry-picked there instead.

anidb.app is offline, so scrape hianime.at instead: the search page, the
episode and server list endpoints, the HD-1 embed whose config is
base64(json XOR "otaku-embed-v1"), and finally the master playlist.

Builds on the scraping work in pystardust#1894.

- hianime_m3u8 runs in the parent shell and sets links, sub_link, mal_id
  and refr, so ani-skip now runs after get_video_link with a real mal id
- the stream host rejects playlists without a referer, pass it to mpv,
  iina, vlc, syncplay, yt-dlp and ffmpeg
- subtitles come as a separate vtt, hand it to the players and save it
  next to downloads
- hianime has no season list, so change_season searches the current title
- scope the episode list to the selected slug, otherwise ids left over
  from the previous provider resolve to an unrelated show
- cut the top 10 sidebar out of the search results
- create the temp history file before backup_old_hist appends to it
- bump to 5.1.0 and update readme, man page, disclaimer and hacking notes

Co-authored-by: Dhairya3391 <dhairyaadroja3391@gmail.com>
@madeline-celeste

Copy link
Copy Markdown

gpt pr description

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants