fix: media playback rate reset on episode change

fix: kodik url parsing for some releases
feat: add more playback rates
This commit is contained in:
Kentai Radiquum 2025-03-19 23:08:29 +05:00
parent b5343f8aac
commit d41e5c6f93
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
4 changed files with 76 additions and 7 deletions

View file

@ -175,7 +175,7 @@ export default function Page(props: { children: any, className?: string }) {
<media-settings-menu hidden anchor="auto">
<media-settings-menu-item>
Playback Speed
<media-playback-rate-menu slot="submenu" hidden>
<media-playback-rate-menu slot="submenu" hidden rates="0.5 0.75 1 1.25 1.5 1.75 2">
<div slot="title">Playback Speed</div>
</media-playback-rate-menu>
</media-settings-menu-item>

View file

@ -11,6 +11,7 @@ import { Spinner } from "../Spinner/Spinner";
import { useUserPlayerPreferencesStore } from "#/store/player";
import HlsVideo from "hls-video-element/react";
import VideoJS from "videojs-video-element/react";
import MediaThemeSutro from "./MediaThemeSutro";
import { getAnonEpisodesWatched } from "./ReleasePlayer";
@ -36,6 +37,7 @@ export const ReleasePlayerCustom = (props: {
type: null,
useCustom: false,
});
const [playbackRate, setPlaybackRate] = useState(1);
const playerPreferenceStore = useUserPlayerPreferencesStore();
const preferredVO = playerPreferenceStore.getPreferredVoiceover(props.id);
@ -78,8 +80,49 @@ export const ReleasePlayerCustom = (props: {
`https://anix-player.wah.su/?url=${url}&player=kodik`
);
const data = await response.json();
let manifest = `https:${data.links["360"][0].src.replace("360.mp4:hls:", "")}`;
let poster = `https:${data.links["360"][0].src.replace("360.mp4:hls:manifest.m3u8", "thumb001.jpg")}`;
let lowQualityLink = data.links["360"][0].src;
if (lowQualityLink.includes("https://")) {
lowQualityLink = lowQualityLink.replace("https://", "//");
}
let manifest = `https:${lowQualityLink.replace("360.mp4:hls:", "")}`;
let poster = `https:${lowQualityLink.replace("360.mp4:hls:manifest.m3u8", "thumb001.jpg")}`;
if (lowQualityLink.includes("animetvseries")) {
let blobTxt = "#EXTM3U\n";
if (data.links.hasOwnProperty("240")) {
blobTxt += "#EXT-X-STREAM-INF:RESOLUTION=427x240,BANDWIDTH=200000\n";
!data.links["240"][0].src.startsWith("https:") ?
(blobTxt += `https:${data.links["240"][0].src}\n`)
: (blobTxt += `${data.links["240"][0].src}\n`);
}
if (data.links.hasOwnProperty("360")) {
blobTxt += "#EXT-X-STREAM-INF:RESOLUTION=578x360,BANDWIDTH=400000\n";
!data.links["360"][0].src.startsWith("https:") ?
(blobTxt += `https:${data.links["360"][0].src}\n`)
: (blobTxt += `${data.links["360"][0].src}\n`);
}
if (data.links.hasOwnProperty("480")) {
blobTxt += "#EXT-X-STREAM-INF:RESOLUTION=854x480,BANDWIDTH=596000\n";
!data.links["480"][0].src.startsWith("https:") ?
(blobTxt += `https:${data.links["480"][0].src}\n`)
: (blobTxt += `${data.links["480"][0].src}\n`);
}
if (data.links.hasOwnProperty("720")) {
blobTxt += "#EXT-X-STREAM-INF:RESOLUTION=1280x720,BANDWIDTH=1280000\n";
!data.links["720"][0].src.startsWith("https:") ?
(blobTxt += `https:${data.links["720"][0].src}\n`)
: (blobTxt += `${data.links["720"][0].src}\n`);
}
let file = new File([blobTxt], "manifest.m3u8", {
type: "application/x-mpegURL",
});
manifest = URL.createObjectURL(file);
}
return { manifest, poster };
};
@ -93,8 +136,6 @@ export const ReleasePlayerCustom = (props: {
const ep = data.player.list[episode.selected.position];
const blobTxt = `#EXTM3U\n${ep.hls.sd && `#EXT-X-STREAM-INF:RESOLUTION=854x480,BANDWIDTH=596000\n${host}${ep.hls.sd}\n`}${ep.hls.hd && `#EXT-X-STREAM-INF:RESOLUTION=1280x720,BANDWIDTH=1280000\n${host}${ep.hls.hd}\n`}${ep.hls.fhd && `#EXT-X-STREAM-INF:RESOLUTION=1920x1080,BANDWIDTH=2560000\n${host}${ep.hls.fhd}\n`}`;
const blob = new Blob([blobTxt], { type: "application/x-mpegURL" });
let file = new File([blobTxt], "manifest.m3u8", {
type: "application/x-mpegURL",
});
@ -274,13 +315,23 @@ export const ReleasePlayerCustom = (props: {
slot="media"
src={playerProps.src}
poster={playerProps.poster}
defaultPlaybackRate={playbackRate}
onRateChange={(e) => {
// @ts-ignore
setPlaybackRate(e.target.playbackRate || 1);
}}
/>
: <video
: <VideoJS
className="object-contain h-full aspect-video"
slot="media"
src={playerProps.src}
poster={playerProps.poster}
></video>
defaultPlaybackRate={playbackRate}
onRateChange={(e) => {
// @ts-ignore
setPlaybackRate(e.target.playbackRate || 1);
}}
></VideoJS>
}
</MediaThemeSutro>
: <iframe src={playerProps.src} className="w-full aspect-video" />}

17
package-lock.json generated
View file

@ -22,6 +22,7 @@
"react-dom": "^18",
"swiper": "^11.1.4",
"swr": "^2.2.5",
"videojs-video-element": "^1.4.1",
"zustand": "^4.5.4"
},
"devDependencies": {
@ -5561,6 +5562,12 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/super-media-element": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/super-media-element/-/super-media-element-1.4.2.tgz",
"integrity": "sha512-9pP/CVNp4NF2MNlRzLwQkjiTgKKe9WYXrLh9+8QokWmMxz+zt2mf1utkWLco26IuA3AfVcTb//qtlTIjY3VHxA==",
"license": "MIT"
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -6100,6 +6107,16 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/videojs-video-element": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/videojs-video-element/-/videojs-video-element-1.4.1.tgz",
"integrity": "sha512-MzwZwmaAHYSXSecRygPP6/oZx/9aEtCe7YlHjjg4njIgkdS+bvv2DrjU3jV0mFwLBWbSr6SEK9s0I2MvuK5kVQ==",
"license": "MIT",
"dependencies": {
"media-tracks": "^0.3.3",
"super-media-element": "~1.4.2"
}
},
"node_modules/watchpack": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",

View file

@ -23,6 +23,7 @@
"react-dom": "^18",
"swiper": "^11.1.4",
"swr": "^2.2.5",
"videojs-video-element": "^1.4.1",
"zustand": "^4.5.4"
},
"devDependencies": {