import React, { Suspense, useCallback, useEffect, useState } from "react"; import { Button, Paper } from "@material-ui/core"; import { makeStyles, useTheme } from "@material-ui/core/styles"; import { useLocation, useParams, useRouteMatch } from "react-router"; import { useDispatch, useSelector } from "react-redux"; import pathHelper from "../../utils/page"; import UseFileSubTitle from "../../hooks/fileSubtitle"; import { getPreviewURL } from "../../middleware/Api"; import { useHistory } from "react-router-dom"; import { basename, fileNameNoExt, isMobileSafari } from "../../utils"; import { list } from "../../services/navigate"; import { getViewerURL } from "../../redux/explorer/action"; import { subtitleSuffix, videoPreviewSuffix } from "../../config"; import { toggleSnackbar } from "../../redux/explorer"; import { pathJoin } from "../Uploader/core/utils"; import { Launch, PlaylistPlay, Subtitles } from "@material-ui/icons"; import TextLoading from "../Placeholder/TextLoading"; import SelectMenu from "./SelectMenu"; import { getDownloadURL } from "../../services/file"; import { sortMethodFuncs } from "../FileManager/Sort"; import { useTranslation } from "react-i18next"; const Artplayer = React.lazy(() => import( /* webpackChunkName: "artplayer" */ "artplayer/examples/react/Artplayer" ) ); const domain = document.location.protocol + "//" + window.location.host; const externalPlayers = [ { name: "PotPlayer", url: (source, title) => { if (source.startsWith('/')) { return `potplayer://${domain}${source}` } else { return `potplayer://${source}` } }, }, { name: "VLC", url: (source, title) => { if (source.startsWith('/')) { return `vlc://${domain}${source}` } else { return `vlc://${source}` } }, }, { name: "IINA", url: (source, title) => { if (source.startsWith('/')) { return `iina://weblink?url=${domain}${source}` } else { return `iina://weblink?url=${source}` } }, }, { name: "nPlayer", url: (source, title) => { if (source.startsWith('/')) { return `nplayer-${domain}${source}` } else { return `nplayer-${source}` } }, }, { name: "MXPlayer (Free)", url: (source, title) => { if (source.startsWith('/')) { return `intent:${domain}${source}#Intent;package=com.mxtech.videoplayer.ad;S.title=${title};end` } else { return `intent:${source}#Intent;package=com.mxtech.videoplayer.ad;S.title=${title};end` } }, }, { name: "MXPlayer (Pro)", url: (source, title) => { if (source.startsWith('/')) { return `intent:${domain}${source}#Intent;package=com.mxtech.videoplayer.pro;S.title=${title};end` } else { return `intent:${source}#Intent;package=com.mxtech.videoplayer.pro;S.title=${title};end` } }, }, ]; const useStyles = makeStyles((theme) => ({ layout: { width: "auto", marginTop: 30, marginBottom: 20, marginLeft: theme.spacing(3), marginRight: theme.spacing(3), [theme.breakpoints.up(1100 + theme.spacing(3) * 2)]: { width: 1100, marginLeft: "auto", marginRight: "auto", }, }, player: { height: "100vh", maxHeight: "calc(100vh - 180px)", }, actions: { marginTop: theme.spacing(2), }, actionButton: { marginRight: theme.spacing(1), marginTop: theme.spacing(1), }, "@global": { "video,.art-video-player,.art-bottom": { borderRadius: theme.shape.borderRadius, } } })); function useQuery() { return new URLSearchParams(useLocation().search); } export default function VideoViewer() { const { t } = useTranslation(); const math = useRouteMatch(); const location = useLocation(); const query = useQuery(); const { id } = useParams(); const dispatch = useDispatch(); const ToggleSnackbar = useCallback( (vertical, horizontal, msg, color) => dispatch(toggleSnackbar(vertical, horizontal, msg, color)), [dispatch] ); const { title, path } = UseFileSubTitle(query, math, location); const theme = useTheme(); const [art, setArt] = useState(null); const history = useHistory(); const [files, setFiles] = useState([]); const [subtitles, setSubtitles] = useState([]); const [playlist, setPlaylist] = useState([]); const [subtitleOpen, setSubtitleOpen] = useState(null); const [subtitleSelected, setSubtitleSelected] = useState(""); const [playlistOpen, setPlaylistOpen] = useState(null); const [externalPlayerOpen, setExternalPlayerOpen] = useState(null); const isShare = pathHelper.isSharePage(location.pathname); const sortMethod = useSelector((state) => state.viewUpdate.sortMethod); const sortFunc = sortMethodFuncs[sortMethod]; useEffect(() => { art && art.on("ready", () => { art.autoHeight = true; }); return () => { if ( art !== null && !isMobileSafari() && document.pictureInPictureEnabled && art.playing ) { art.pip = true; art.query(".art-video").addEventListener( "leavepictureinpicture", () => { art.pause(); }, false ); } }; }, [art]); const classes = useStyles(); useEffect(() => { if (art !== null) { const newURL = getPreviewURL( isShare, id, query.get("id"), query.get("share_path") ); if (newURL !== art.url) { if (art.subtitle) { art.subtitle.show = false; } art.switchUrl(newURL); if (path && path !== "") { list( basename(path), isShare ? { key: id } : null, "", "" ).then((res) => { setFiles( res.data.objects.sort(sortFunc).filter((o) => o.type === "file") ); setPlaylist( res.data.objects.filter( (o) => o.type === "file" && videoPreviewSuffix.indexOf( o.name.split(".").pop().toLowerCase() ) !== -1 ) ); }); } } } }, [art, id, location, path]); const switchSubtitle = (f) => { if (art !== null) { const fileType = f.name.split(".").pop().toLowerCase(); art.subtitle.switch( getPreviewURL( isShare, id, f.id, pathJoin([basename(query.get("share_path")), f.name]) ), { type: fileType, } ); art.subtitle.show = true; setSubtitleSelected(f.name); ToggleSnackbar( "top", "center", t("fileManager.subtitleSwitchTo", { subtitle: f.name, }), "info" ); } }; useEffect(() => { if (files.length > 0) { const fileNameMatch = fileNameNoExt(title) + "."; const options = files.filter((f) => { const fileType = f.name.split(".").pop().toLowerCase(); return subtitleSuffix.indexOf(fileType) !== -1; }).sort((a, b) => { return (a.name.startsWith(fileNameMatch) && !b.name.startsWith(fileNameMatch)) ? -1 : 0; }); if (options.length > 0 && options[0].name.startsWith(fileNameMatch)) { switchSubtitle(options[0]); } setSubtitles(options); } }, [files]); const switchVideo = (file) => { setSubtitleSelected(null); if (isShare) { file.key = id; } if (isMobileSafari()) { window.location.href = getViewerURL("video", file, isShare); } else { history.push(getViewerURL("video", file, isShare)); } }; const setSubtitle = (sub) => { setSubtitleOpen(null); switchSubtitle(sub); }; const startSelectSubTitle = (e) => { if (subtitles.length === 0) { ToggleSnackbar( "top", "right", t("fileManager.noSubtitleAvailable"), "warning" ); return; } setSubtitleOpen(e.currentTarget); }; const openInExternalPlayer = (player) => { const current = { name: title }; current.id = query.get("id"); current.path = basename(path); if (isShare) { current.key = id; } setExternalPlayerOpen(null); getDownloadURL(current) .then((response) => { window.location.assign(player.url(response.data, title)); }) .catch((error) => { ToggleSnackbar("top", "right", error.message, "error"); }); }; return (
}> setArt(a)} />
{playlist.length >= 2 && ( )}
setSubtitleOpen(null)} /> setPlaylistOpen(null)} /> setExternalPlayerOpen(null)} />
); }