Web browser extension to skip anime openings and endings
We are now on Discord! Want to contribute, need help or just want to ask questions?
Join the Aniskip Discord.
You will need to have installed:
-
Clone the repo
git clone https://github.com/lexesjan/typescript-aniskip-extension -
Navigate into the cloned GitHub repository
cd typescript-aniskip-extension -
Run the install and start script
yarn install yarn start:dev:chrome
This will start a chromium browser with the built extension loaded. This script will reload the extension on file change. You can replace chrome with firefox to build for firefox.
-
Clone the repo
git clone https://github.com/lexesjan/typescript-aniskip-extension -
Navigate into the cloned GitHub repository
cd typescript-aniskip-extension -
Run the install and start script
yarn install yarn build:prod:chrome
This will build a zipped extension in the web-ext-artifacts folder. You can replace chrome with firefox to build for firefox.
There are two parts to a webpage,
-
The webpage itself (i.e. Crunchy Rolls https://github.com/aniskip/aniskip-extension/tree/main/src/pages/crunchyroll)

-
The video player (i.e. the stuff that actually runs the video https://github.com/aniskip/aniskip-extension/tree/main/src/players/crunchyroll)

There are a two core function to implement, as seen in the example
To inherit from base-page.ts
...
// Implement a function to get the Anime Title (to map to MalID that we use as primary key (identifier) for skip times)
getIdentifier(): string {
...
}
// Implement a function to get Episode Number
getRawEpisodeNumber(): number {
...
}Note: The rest of the stuff are not required by default, they could very well inherited from legacy but not required for current/future players.
Example
This determines when the correspondent player script is used
Note: pattern here, tl;dr: *://x.y.z/*
{
"pageUrls": ["*://www.crunchyroll.com/*"]
}Example This simply exports the functions, create the same for your player
export * from './crunchyroll'; // whatever you named your playerThis configures how we interact with the video player
Example Generally, you could very well copy and paste the whole thing here. As you can see from the examples, we read from metadata.json for the details.
Note: The example should provide a good starting point, if you need something custom, add it yourself! For example, some might have different selector for desktop and mobile, example
// Fetches the video container (the whole thing)
getVideoContainer(): HTMLVideoElement | null {
...
}
// Fetches the video controls (the one with play/pause/adjust playback speed)
getVideoControlsContainer(): HTMLElement | null {
...
}
// The button for fullscreen
getSettingsButtonElement(): HTMLElement | null {
...
}Example This is where we have our core logic to interacting with the video player
{
"variant": "videojs", -- name of player
"playerUrls": [ -- lists of urls (do note that more webpages will i-frame into video players' url, not the url of the webpage itself
"*://dood.to/*", -- see pics below, for a different player
],
"selectorStrings": { -- some players are used across different webpages, but with slightly different name
"default": {
"videoContainerSelectorString": "Video Player", -- CSS selector that points to the video player (generally div)
"videoControlsContainerSelectorString": "vjs-control-bar", -- CSS selector that points to video player's control bar
"injectMenusButtonsReferenceNodeSelectorString": "vjs-fullscreen-control", -- CSS selector to fullscreen button
"seekBarContainerSelectorString": "vjs-progress-holder vjs-slider" -- CSS selector to seekbar (the stuff that moves when you watch the video)
},
"dood": { -- other subvariants
...
},
}
}Example of the player container

Example Exports all defined function, no change required.
export * from './videojs'; // player script that you definedExample CSS to make stuff prettier Note: CSS 101, or learn by modifying existing ones
Short answer: We don't need to Long answer: In pages we defined where is the video player container, this essentially gives us the player url, and we defined which player script to run for which urls in the metadata.





