import { useEffect, useRef, useState } from "react"; import styles from "./video.module.scss"; import { useParams, useNavigate } from "react-router-dom"; import { useSelector } from "react-redux"; import { course as Course } from "../../api/index"; import { ArrowLeftOutlined } from "@ant-design/icons"; import { message } from "antd"; declare const window: any; type HourModel = { chapter_id: number; course_id: number; duration: number; id: number; rid: number; sort: number; title: string; type: string; }; type CourseModel = { charge: number; class_hour: number; created_at: string; id: number; is_required: number; is_show: number; short_desc: string; thumb: string; title: string; }; type UserHourRecordModel = { course_id: number; created_at: string; finished_at?: string; finished_duration: number; hour_id: number; id: number; is_finished: number; real_duration: number; total_duration: number; updated_at: string; user_id: number; }; const CoursePalyPage = () => { const navigate = useNavigate(); const params = useParams(); const systemConfig = useSelector((state: any) => state.systemConfig.value); const user = useSelector((state: any) => state.loginUser.value.user); const [playUrl, setPlayUrl] = useState(""); const [playDuration, setPlayDuration] = useState(0); const [playendedStatus, setPlayendedStatus] = useState(false); const [lastSeeValue, setLastSeeValue] = useState({}); const [course, setCourse] = useState(null); const [hour, setHour] = useState(null); const [loading, setLoading] = useState(false); const [isLastpage, setIsLastpage] = useState(false); const [totalHours, setTotalHours] = useState([]); const [playingTime, setPlayingTime] = useState(0); const [watchedSeconds, setWatchedSeconds] = useState(0); const myRef = useRef(0); const playRef = useRef(0); const watchRef = useRef(0); const totalRef = useRef(0); useEffect(() => { getCourse(); getDetail(); document.oncontextmenu = function (e) { /*屏蔽浏览器默认右键事件*/ e = e || window.event; return false; }; return () => { document.oncontextmenu = function (e) { /*恢复浏览器默认右键事件*/ e = e || window.event; return true; }; }; }, [params.courseId, params.hourId]); useEffect(() => { myRef.current = playDuration; }, [playDuration]); useEffect(() => { playRef.current = playingTime; }, [playingTime]); useEffect(() => { watchRef.current = watchedSeconds; }, [watchedSeconds]); useEffect(() => { totalRef.current = hour?.duration || 0; }, [hour]); const getCourse = () => { Course.detail(Number(params.courseId)).then((res: any) => { let totalHours: HourModel[] = []; if (res.data.chapters.length === 0) { setTotalHours(res.data.hours[0]); totalHours = res.data.hours[0]; } else if (res.data.chapters.length > 0) { const arr: HourModel[] = []; for (let key in res.data.hours) { res.data.hours[key].map((item: any) => { arr.push(item); }); } setTotalHours(arr); totalHours = arr; } const index = totalHours.findIndex( (i: any) => i.id === Number(params.hourId) ); if (index === totalHours.length - 1) { setIsLastpage(true); } }); }; const getDetail = () => { if (loading) { return true; } setLoading(true); Course.play(Number(params.courseId), Number(params.hourId)) .then((res: any) => { setCourse(res.data.course); setHour(res.data.hour); document.title = res.data.hour.title; let record: UserHourRecordModel = res.data.user_hour_record; let params = null; if (record && record.finished_duration && record.is_finished === 0) { params = { time: 5, pos: record.finished_duration, }; setLastSeeValue(params); setLastSeeValue(params); setWatchedSeconds(record.finished_duration); } else if (record && record.is_finished === 1) { setWatchedSeconds(res.data.hour.duration); } getVideoUrl(params); setLoading(false); }) .catch((e) => { setLoading(false); }); }; const getVideoUrl = (data: any) => { Course.playUrl(Number(params.courseId), Number(params.hourId)).then( (res: any) => { setPlayUrl(res.data.url); initDPlayer(res.data.url, 0, data); } ); }; const initDPlayer = (playUrl: string, isTrySee: number, params: any) => { let banDrag = systemConfig.playerIsDisabledDrag && watchRef.current < totalRef.current && watchRef.current === 0; window.player = new window.DPlayer({ container: document.getElementById("meedu-player-container"), autoplay: false, video: { url: playUrl, pic: systemConfig.playerPoster, }, try: isTrySee === 1, bulletSecret: { enabled: systemConfig.playerIsEnabledBulletSecret, text: systemConfig.playerBulletSecretText .replace("{name}", user.name) .replace("{email}", user.email) .replace("{idCard}", user.id_card), size: "14px", color: systemConfig.playerBulletSecretColor || "red", opacity: Number(systemConfig.playerBulletSecretOpacity), }, ban_drag: banDrag, last_see_pos: params, }); // 监听播放进度更新evt window.player.on("timeupdate", () => { let currentTime = parseInt(window.player.video.currentTime); if ( systemConfig.playerIsDisabledDrag && watchRef.current < totalRef.current && currentTime - playRef.current >= 2 && currentTime > watchRef.current ) { message.warning("首次学习禁止快进"); window.player.seek(watchRef.current); } else { setPlayingTime(currentTime); playTimeUpdate(parseInt(window.player.video.currentTime), false); } }); window.player.on("ended", () => { if ( systemConfig.playerIsDisabledDrag && watchRef.current < totalRef.current && window.player.video.duration - playRef.current >= 2 ) { window.player.seek(playRef.current); return; } setPlayingTime(0); setPlayendedStatus(true); playTimeUpdate(parseInt(window.player.video.currentTime), true); exitFullscreen(); window.player && window.player.destroy(); }); setLoading(false); }; const playTimeUpdate = (duration: number, isEnd: boolean) => { if (duration - myRef.current >= 10 || isEnd === true) { setPlayDuration(duration); Course.record( Number(params.courseId), Number(params.hourId), duration ).then((res: any) => {}); Course.playPing(Number(params.courseId), Number(params.hourId)).then( (res: any) => {} ); } }; const goNextVideo = () => { const index = totalHours.findIndex( (i: any) => i.id === Number(params.hourId) ); if (index === totalHours.length - 1) { setIsLastpage(true); message.error("已经是最后一节了!"); } else if (index < totalHours.length - 1) { navigate(`/course/${params.courseId}/hour/${totalHours[index + 1].id}`, { replace: true, }); } }; const exitFullscreen = () => { let de: any; de = document; if (de.fullscreenElement !== null) { de.exitFullscreen(); } else if (de.mozCancelFullScreen) { de.mozCancelFullScreen(); } else if (de.webkitCancelFullScreen) { de.webkitCancelFullScreen(); } }; return (
{ window.player && window.player.destroy(); document.oncontextmenu = function (e) { /*恢复浏览器默认右键事件*/ e = e || window.event; return true; }; navigate(-1); }} > 返回
{hour?.title}
{playendedStatus && (
{isLastpage && (
navigate(`/course/${params.courseId}`)} > 恭喜你学完最后一节
)} {!isLastpage && (
{ window.player && window.player.destroy(); setLastSeeValue({}); setPlayendedStatus(false); goNextVideo(); }} > 播放下一节
)}
)}
); }; export default CoursePalyPage;