// ==UserScript== // @name Anime Songs - AniList Player // @namespace Openings and Endings Player // @version 2.2 // @description This Script allows You to play Openings and Endings directly on AniList // @author NurarihyonMaou // @match https://anilist.co/* // @icon https://www.google.com/s2/favicons?sz=64&domain=anilist.co // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @require http://code.jquery.com/jquery-3.5.1.min.js // @downloadURL none // ==/UserScript== const $ = window.jQuery; let result; let openings, endings; let audioUrls = ['https://animethemes.moe/audio/', 'https://a.animethemes.moe/', 'https://beta.animethemes.moe/audio/']; let videoUrls = ['https://animethemes.moe/video/', 'https://v.animethemes.moe/', 'https://beta.animethemes.moe/video/']; let urlsIndex = GM_getValue("urlsIndex") ?? 1; //let audioURLAddon = "-NCBD1080"; let url = "https://graphql.anilist.co"; let AnimeID; let AniID = { id: parseInt(window.location.pathname.split("/")[2]) }; const VideoIcon = ``; const MusicIcon = ``; const ToggleStyle = `.AudioMode { width:45px; height:15px; background-color: grey; position: relative; transition: ease-in-out 0.5s; display: flex; justify-content: center; align-items: center; } .circle { border-radius:50%; width: 30px; max-height: 30px; color:red; z-index: 9999; position: absolute; left:0; transition: ease-in-out 0.5s; } .circle svg { transition: ease-in-out 0.5s; color:red; } .active{ left:50%; } `; GM_addStyle(ToggleStyle); let AudioMode = GM_getValue("AudioMode") ?? false; async function getAID() { AniID = { id: parseInt(window.location.pathname.split("/")[2]) }; let query = ` query ($id: Int) { Media (id: $id, type: ANIME) { idMal } } `; let options = { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify({ query: query, variables: AniID, }), }; await fetch(url, options) .then(handleResponse) .then(handleData) .catch(handleError); function handleResponse(response) { return response.json().then(function (json) { return response.ok ? json : Promise.reject(json); }); } function handleData(data) { AnimeID = data.data.Media.idMal; } function handleError(error) { alert("Error, check console"); console.error(error); } } async function returnThemes() { await getAID(); let response = $.ajax({ url: `https://api.jikan.moe/v4/anime/${AnimeID}/themes`, method: "GET", success: function (data) { return data; }, error: function (error) { alert("Something went wrong.\n" + error.errorMessage); }, }); return response; } function appendThemes() { if ($("body").find("div.openings").length == 0) $("body div.characters").after( "

Openings

" ); else { $("body div.characters").after($("body").find("div.openings")); $("body").find("div.openings").html("

Openings

"); } if ($("body").find("div.endings").length == 0) $("body div.openings").after("

Endings

"); else { $("body div.openings").after($("body").find("div.endings")); $("body").find("div.endings").html("

Endings

"); } themes.data.openings.forEach((opening) => { $("body").find("div.openings").append(``); }); themes.data.endings.forEach((ending) => { $("body").find("div.endings").append(``); }); if (parseInt(AniID.id) != 112323) { if ($("body").find("div.AudioMode").length == 0) $("body div.openings").before( ` URL Slider - use this when the Player(s) don't work

` ); else $("body div.openings").before($("body").find("div.AudioMode")); } } $("body").on("click", "div.AudioMode", function () { AudioMode = !AudioMode; if (AudioMode) { $(this).children().addClass("active"); $(this).children().html(MusicIcon); } else { $(this).children().removeClass("active"); $(this).children().html(VideoIcon); } GM_setValue("AudioMode", AudioMode); $("body").find(".AnimeThemesPlayer").remove(); loadVideos(); }); $("body").on("change", "input#urlsIndex", function () { urlsIndex = document.getElementById('urlsIndex').value; GM_setValue("urlsIndex", urlsIndex); $("body").find(".AnimeThemesPlayer").remove(); loadVideos(); }); function loadVideos() { let Song = 0; (function init() { openings = document.getElementsByClassName("openings"); endings = document.getElementsByClassName("endings"); if (openings.length > 0 || endings.length > 0) { GM_xmlhttpRequest({ method: "GET", url: "https://api.animethemes.moe/anime?filter[has]=resources&filter[site]=MyAnimeList&filter[external_id]=" + AnimeID + "&include=animethemes.animethemeentries.videos,animethemes.song.artists", data: AnimeID, headers: { "Content-Type": "application/json" }, onload: function (response) { result = JSON.parse(response.responseText); openings = openings.length > 0 ? openings : endings; if ($("body .AnimeThemesPlayer").length == 0) { $(openings).append( AudioMode ? "