Packages
AniSkip client for Elixir: opening and ending times for an anime episode by MyAnimeList id, fitted to the length of the file you are playing, plus voting and submitting times. Errors as values, a Req.Test seam.
Current section
Files
Jump to
Current section
Files
README.md
# AniSkip
An Elixir client for [AniSkip](https://api.aniskip.com/api-docs), the
community database of where an anime episode's opening and ending are —
what "Skip intro" is made of.
```elixir
def deps do
[{:aniskip, "~> 0.1"}]
end
```
## Where the opening is
Entries are keyed by **MyAnimeList id** and the episode's number *within
that MAL entry* (a second season's first episode is episode 1 of the
season's own entry).
```elixir
{:ok, times} = AniSkip.times(5114, 1)
#=> [%{kind: :op, from: 58.6, to: 148.6, length: 1469.6, id: "067c…"},
# %{kind: :ed, from: 1349.9, to: 1474.0, length: 1474.7, id: "473e…"}]
```
An episode AniSkip does not know is `{:ok, []}`.
## Fitting them to your file
Each time says how long the file it was measured on was. A different cut of
the same episode (a Blu-ray with a preview, a TV rip without the recap) has
the opening somewhere else, so match the times to the file you are playing:
```elixir
skips = AniSkip.fit(times, video_duration_seconds)
#=> [%{kind: :intro, from: 58.6, to: 148.6, tail: false},
# %{kind: :credits, from: 1349.9, to: 1474.0, tail: true}]
AniSkip.at(skips, current_time) #=> the skip to offer now, or nil
```
`tail` is credits that run to the end of the file — a player can offer
those as "Next episode". A file still being converted (its length short of
the measured one) keeps the times until it is long enough to judge.
## Giving back
```elixir
AniSkip.vote(skip_id, :up)
AniSkip.submit(mal_id, episode, :op, 58.6, 148.6, file_length, submitter_uuid)
```
## Be gentle
Nothing here is cached. AniSkip is a small community service; keep each
episode's answer for a day in your own cache (`{:ok, []}` too), and put a
budget on lookups.
## Errors and testing
Every function returns values and never raises: `{:error, :rate_limited}`,
`{:error, {:http, status}}` or `{:error, {:transport, reason}}`. Every
request merges `req_options`, so point it at `Req.Test`:
```elixir
# config/test.exs
config :aniskip, req_options: [plug: {Req.Test, AniSkip}]
```
## License
MIT © Alexander Don