feat(video player): support flv cloudreve/Cloudreve#2300 (#254)

* feat(video player): support flv cloudreve/Cloudreve#2300

* fix(video player): ignore case in file extension

* fix(video player): specify the video type

Since the link may not include the file extension.
This commit is contained in:
小白-白 2025-04-27 09:41:17 +08:00 committed by GitHub
parent 8ebc46686d
commit 0680171f46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 13 deletions

View File

@ -43,6 +43,7 @@
"lodash": "^4.17.21",
"material-ui-popup-state": "^5.0.10",
"monaco-editor": "^0.49.0",
"mpegts.js": "^1.8.0",
"mui-one-time-password-input": "^2.0.1",
"notistack": "^3.0.1",
"nuqs": "^2.3.1",

View File

@ -1,8 +1,10 @@
import { Box, BoxProps } from "@mui/material";
import { fileExtension } from "../../../util";
import Artplayer from "artplayer";
import artplayerPluginChapter from "artplayer-plugin-chapter";
import artplayerPluginHlsControl from "artplayer-plugin-hls-control";
import Hls, { HlsConfig } from "hls.js";
import mpegts from 'mpegts.js';
import i18next from "i18next";
import { useEffect, useRef } from "react";
import "./artplayer.css";
@ -96,6 +98,26 @@ const playM3u8 =
}
};
const playFlv =
(video: HTMLVideoElement, url: string, art: Artplayer) => {
if (mpegts.isSupported()) {
if (art.flv) art.flv.destroy();
const flv = mpegts.createPlayer({
type: 'flv',
url: url,
}, {
lazyLoadMaxDuration: 5 * 60,
accurateSeek: true,
});
flv.attachMediaElement(video);
flv.load();
art.flv = flv;
art.on('destroy', () => flv.destroy());
} else {
art.notice.show = 'Unsupported playback format: flv';
}
};
export default function Player({
option,
chapters,
@ -105,12 +127,27 @@ export default function Player({
...rest
}: PlayerProps) {
const artRef = useRef<Artplayer>();
const ext = fileExtension(option.title);
useEffect(() => {
const opts = {
...option,
plugins: [
...option.plugins,
plugins: [...option.plugins],
container: artRef.current,
customType: {
...option.customType,
m3u8: playM3u8(m3u8UrlTransform, getEntityUrl),
flv: playFlv,
},
type: ext,
};
if (chapters) {
opts.plugins.push(artplayerPluginChapter({ chapters }));
}
if (ext === "m3u8") {
opts.plugins.push(
artplayerPluginHlsControl({
quality: {
// Show qualitys in control
@ -135,17 +172,9 @@ export default function Player({
auto: i18next.t("application:fileManager.auto"),
},
}),
],
container: artRef.current,
customType: {
...option.customType,
m3u8: playM3u8(m3u8UrlTransform, getEntityUrl),
},
};
if (chapters) {
opts.plugins.push(artplayerPluginChapter({ chapters }));
);
}
const art = new Artplayer(opts);
if (getInstance && typeof getInstance === "function") {

View File

@ -100,7 +100,7 @@ const VideoViewer = () => {
}
const firstLoad = !currentExpire.current;
const isM3u8 = viewerState.file.name.endsWith(".m3u8");
const isM3u8 = fileExtension(viewerState.file.name) === "m3u8";
if (isM3u8) {
// For m3u8, use masked url
const crFileUrl = new CrUri(getFileLinkedUri(viewerState.file));

View File

@ -4690,6 +4690,11 @@ es6-iterator@^2.0.3:
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
es6-promise@^4.2.5:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@^3.1.3:
version "3.1.4"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c"
@ -6574,6 +6579,14 @@ monaco-editor@^0.49.0:
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.49.0.tgz#4e80e9859feb2c421def3cef194d12d822606472"
integrity sha512-2I8/T3X/hLxB2oPHgqcNYUVdA/ZEFShT7IAujifIPMfKkNbLOqY8XCoyHCXrsdjb36dW9MwoTwBCFpXKMwNwaQ==
mpegts.js@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/mpegts.js/-/mpegts.js-1.8.0.tgz#b944751df0e811be880c0d1e32dcd721f5ff9550"
integrity sha512-ZtujqtmTjWgcDDkoOnLvrOKUTO/MKgLHM432zGDI8oPaJ0S+ebPxg1nEpDpLw6I7KmV/GZgUIrfbWi3qqEircg==
dependencies:
es6-promise "^4.2.5"
webworkify-webpack xqq/webworkify-webpack
ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
@ -8229,6 +8242,10 @@ webidl-conversions@^4.0.2:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
"webworkify-webpack@github:xqq/webworkify-webpack":
version "2.1.5"
resolved "https://codeload.github.com/xqq/webworkify-webpack/tar.gz/24d1e719b4a6cac37a518b2bb10fe124527ef4ef"
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"