zhengpengju 3 years ago
commit b9a52b50da

@ -1,61 +1,40 @@
import React, {forwardRef, useEffect,useImperativeHandle,useState} from "react"; import React, { useEffect } from "react";
import videojs from "video.js"; import videojs from "video.js";
import "video.js/dist/video-js.css"; import "video.js/dist/video-js.css";
import "videojs-contrib-hls"; import "videojs-contrib-hls";
export const VideoJS = ( props: any ) => {
// React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。
const VideoJS = ( props: any, ref: any) => {
const videoRef = React.useRef(null); const videoRef = React.useRef(null);
const playerRef = React.useRef<any>(null); const playerRef = React.useRef<any>(null);
const { options, onReady, width, height } = props; const { options, onReady, width, height } = props;
console.log('props', props)
useEffect(() => { useEffect(() => {
// make sure Video.js player is only initialized once
if (!playerRef.current) { if (!playerRef.current) {
const videoElement = videoRef.current; const videoElement = videoRef.current;
if (!videoElement) return; if (!videoElement) return;
const player = playerRef.current = videojs(videoElement, options, () => { const player = playerRef.current = videojs(videoElement, options, () => {
// console.log("player is ready"); console.log("player is ready");
onReady && onReady(player); onReady && onReady(player);
}); });
} else { } else {
// you can update player here [update player through props] // you can update player here [update player through props]
const player = playerRef.current; const player = playerRef.current;
console.log('playerplayerplayer===',player);
player.src(options.sources[0].src); player.src(options.sources[0].src);
// player.autoplay(true); player.autoplay(true);
videoRef.current.addEventListener('play',()=>{
console.log('播放');
//setCount(player.currentTime());
//playerRef.current.currentTime(count)
// player.currentTime(count)
// getTime(player.currentTime());
// saveLearning();
});
videoRef.current.addEventListener('pause',()=>{
console.log('停止了')
})
}
}, [options]);
// 暴露组件的方法 接受外部获取的ref
useImperativeHandle(ref, () => ({
// 构造ref的获取数据方法
currentTime: (time: number) => {
if(time){
playerRef?.current?.currentTime(time)
} }
return playerRef?.current?.currentTime() || 0 }, [options, videoRef]);
},
}));
return ( return (
<div data-vjs-player> <div data-vjs-player>
<video style={{ <video style={{
width: width ||'100%', width: width || '100%',
height:'auto' height: height || 'auto'
}} ref={videoRef} className="video-js vjs-big-play-centered" /> }} ref={videoRef} className="video-js vjs-big-play-centered" />
</div> </div>
); );
} }
// forwardRef这个组件能够将其接受的 ref 属性转发到其组件树下
export default forwardRef( VideoJS );

@ -10,21 +10,24 @@ import { Content } from 'antd/lib/layout/layout';
import Sider from 'antd/lib/layout/Sider'; import Sider from 'antd/lib/layout/Sider';
import SubMenu from 'antd/lib/menu/SubMenu'; import SubMenu from 'antd/lib/menu/SubMenu';
import { useRef } from 'react'; import React,{ useRef } from 'react';
import {listMyLearningChapterCourse1, viewCourseGetMyLearning,saveMyLearning} from './service'; import {listMyLearningChapterCourse1, viewCourseGetMyLearning,saveMyLearning} from './service';
import cookie from 'react-cookies'; import cookie from 'react-cookies';
import VideoJS from '../components/VideoJS'; import { VideoJS } from '../components/VideoJS';
const { Paragraph } = Typography; const { Paragraph } = Typography;
let num=0;
const CardList = () => { const CardList = () => {
const params = useParams(); const params = useParams();
const ids = params.msg.split(',');//chapter_id,course_id,subject_id const ids = params.msg.split(',');//chapter_id,course_id,subject_id
const [currentLearning, SetCurrentLearning] = useState(); const [currentLearning, SetCurrentLearning] = useState();
const [courseId, SetCourseId] = useState(ids[1]); const [courseId, SetCourseId] = useState(ids[1]);
let time=0; const [video, setVideo] = useState({});
const videoRef = useRef<HTMLVideoElement>(null); const [nums,setNums]=useState(0);
let timer=useRef();
let video_second=0;
// const videoRef = useRef<HTMLVideoElement>(null);
const playerRef = React.useRef<any>(null); // 播放器引用
console.log('courseIdcourseIdcourseIdcourseId',courseId) console.log('courseIdcourseIdcourseIdcourseId',courseId)
/** 获取课节 */ /** 获取课节 */
const { data } = useRequest(() => { const { data } = useRequest(() => {
@ -46,23 +49,51 @@ const CardList = () => {
chapter_id: ids[0],//chapter_list[0].chapter_id chapter_id: ids[0],//chapter_list[0].chapter_id
course_id:params?.course_id, course_id:params?.course_id,
}); });
},{
onSuccess:(result)=>{
console.log('result9999',result);
let info={img:'',url:''};
if(JSON.stringify(result.course.attachment_json.url)!=='{}'){
info.url= '/dsideal_yy/html/'+result.course.attachment_json.url;
info.img=result.course.attachment_json.img;
}
setVideo(info);
}
}); });
console.log('learning',learning) console.log('video',video)
//保存进度 //保存进度
const {data: progress, run:saveProgress, } = useRequest((params:{time:number}) => { // const saveProcess = async((params:{time:number,num:number}) => {
return saveMyLearning({ // console.log('num保存是',num)
// // return saveMyLearning({
// // chapter_id:learning?.learning.chapter_id,//章节id
// // course_id:courseId?courseId:ids[1],//课程id
// // identity_id:cookie.load('identity_id'),
// // learning_id:learning?.learning.learning_id,//学习记录id
// // learning_second:num,//距离上次提交持续学习秒数(非必填)
// // person_id:cookie.load('person_id'),
// // play_second:params?.time,//当前播放时间点(秒数)
// // subject_id:learning?.learning.subject_id,//主题id
// // video_second:video_second,//视频总长度
// // });
// });
const saveProcess = async (info)=>{
console.log('num保存是',info)
await saveMyLearning({
chapter_id:learning?.learning.chapter_id,//章节id chapter_id:learning?.learning.chapter_id,//章节id
course_id:courseId?courseId:ids[1],//课程id course_id:courseId?courseId:ids[1],//课程id
identity_id:cookie.load('identity_id'), identity_id:cookie.load('identity_id'),
learning_id:learning?.learning.learning_id,//学习记录id learning_id:learning?.learning.learning_id,//学习记录id
learning_second:0,//距离上次提交持续学习秒数(非必填) learning_second:info.num,//距离上次提交持续学习秒数(非必填)
person_id:cookie.load('person_id'), person_id:cookie.load('person_id'),
play_second:params?.time,//当前播放时间点(秒数) play_second:info.time,//当前播放时间点(秒数)
subject_id:learning?.learning.subject_id,//主题id subject_id:learning?.learning.subject_id,//主题id
video_second:learning?.course.course_minutes*60,//视频总长度 video_second:video_second,//视频总长度
}); })
}); }
/** 首次页面 当data 变化 执行run chapterCourse 变化 进行currentCourse赋值 */ /** 首次页面 当data 变化 执行run chapterCourse 变化 进行currentCourse赋值 */
useEffect(() => { useEffect(() => {
@ -119,17 +150,12 @@ const CardList = () => {
const videoInfo = {url:'http://10.10.14.199/dsideal_yy/html/down/M3u8/2D/2D99BF1D-2F37-47FB-8A24-45112A236B8F.m3u8', img:''}//有视频 const videoInfo = {url:'http://10.10.14.199/dsideal_yy/html/down/M3u8/2D/2D99BF1D-2F37-47FB-8A24-45112A236B8F.m3u8', img:''}//有视频
// const videoInfo=learning?.course.attachment_json;isg // const videoInfo=learning?.course.attachment_json;isg
const nullData: Partial<CardListItemDataType> = {}; const nullData: Partial<CardListItemDataType> = {};
const saveLearning=()=>{
console.log('保存进队');
saveProgress({time:time})
};
// const saveLearning=useEffect(() => { // const saveLearning=useEffect(() => {
// console.log('保存进队'); // console.log('保存进队');
// saveProgress({time:time}) // saveProgress({time:time})
// },[time]); // },[time]);
console.log('time',time)
return ( return (
<PageContainer <PageContainer
// content={content} // content={content}
@ -162,25 +188,29 @@ const CardList = () => {
</Col> </Col>
<Col span={18} style={{background:'#ffffff', padding:24}}> <Col span={18} style={{background:'#ffffff', padding:24}}>
{ {
videoInfo.url && <VideoJS video?.url&&(
<VideoJS
style={{width:640,height:480}}
width='100%'
height='480px'
options={{ options={{
controls: true, controls: true,
playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度 playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
autoplay: false, // 如果true,浏览器准备好时开始回放。 autoplay: false, // 如果true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。 muted: false, // 默认情况下将会消除任何音频。
loop: true, // 导致视频一结束就重新开始。 loop: false, // 导致视频一结束就重新开始。
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: 'zh-CN', language: 'zh-CN',
aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3" aspectRatio: '4:3', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3"
fluid: true, // 当true时Video.js player将拥有流体大小。换句话说它将按比例缩放以适应其容器。 fluid: true, // 当true时Video.js player将拥有流体大小。换句话说它将按比例缩放以适应其容器。
sources: [ sources: [
{ {
// src: 'http://10.10.24.121:8000/dsideal_yy/html/'+videoInfo.url, src: JSON.stringify(video)!=='{}'?video.url:'', // 测试地址后续请删除
src: videoInfo.url, // src: '/dsideal_yy/html/down/Syzx/6e/6e4e88a3-0c71-4298-ba5b-ac1c3f52d587.mp4' , // 测试地址后续请删除
type: 'application/x-mpegURL' //type: 'application/x-mpegURL'
} }
], ],
poster: videoInfo.img, // 你的封面地址 poster: JSON.stringify(video)!=='{}'?video.img:'', // 你的封面地址
width: document.documentElement.clientWidth, width: document.documentElement.clientWidth,
notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。 notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: { controlBar: {
@ -190,9 +220,47 @@ const CardList = () => {
fullscreenToggle: true // 全屏按钮 fullscreenToggle: true // 全屏按钮
} }
}} }}
ref={videoRef} onReady={(play: any) => {
//console.log('play====', play);
playerRef.current = play
// play.play();
play.on('play',function (event) {
console.log('播放-------------------------------')
num=0;
timer.current=setInterval(()=>{;
// console.log('timer-----------',timer)
num++
},1000)
})
play.on("timeupdate", function (event) {
//const _timeCurrent = Date.parse(new Date().toString()) / 1000; // 当前时间
//setTimeUpdateState(_timeCurrent); //timeUpdateState
if(play.currentTime()===this.duration()){
console.log('播放完了',num)
clearInterval(timer.current)
saveProcess({time:play.currentTime(),num:num})
}
// console.log('playcurrentTime--', play.currentTime())
// console.log('play-%-', parseInt(play.currentTime()) % 30)
if (parseInt(play.currentTime())>0&&parseInt(play.currentTime()) % 30 === 0) { // 每15秒更新进度
console.log(1)
saveProcess({time:play.currentTime(),num:30})
}
//var currentTime = parseInt(this.currentTime()); //当前时间
video_second = this.duration(); //视频时常
// console.log('duration',duration)
//var percent = (currentTime / duration * 100).toFixed(0) + "%";
//console.log('event',event);
//$("#current").text(this.currentTime());
//$("#duration").text(duration);
})
}}
/> />
)
} }
</Col> </Col>
</Row> </Row>

@ -47,6 +47,7 @@ const Login: React.FC = () => {
// 登录产生cookie // 登录产生cookie
const msg = await login({ ...values, type }); const msg = await login({ ...values, type });
if (msg.success === true) { if (msg.success === true) {
console.log('dengdgdgdgdgd---------------------------------')
const defaultLoginSuccessMessage = '登录成功!'; const defaultLoginSuccessMessage = '登录成功!';
message.success(defaultLoginSuccessMessage); message.success(defaultLoginSuccessMessage);
await fetchUserInfo(); await fetchUserInfo();
@ -68,6 +69,7 @@ const Login: React.FC = () => {
}; };
const { status, type: loginType } = userLoginState; const { status, type: loginType } = userLoginState;
return ( return (
<div className={styles.container}> <div className={styles.container}>
<div className={styles.lang} data-lang> <div className={styles.lang} data-lang>
@ -216,6 +218,11 @@ const Login: React.FC = () => {
/> />
</> </>
)} )}
<div style={{textAlign:'right',cursor:'pointer',color:'#1890FF',marginBottom:'1rem'}}
onClick={()=>{
window.open("http://10.10.14.199/dsideal_yy/html/pwdfind/pwdfind_fir.html?register_flag=11","_blaknk");
}}
></div>
</LoginForm> </LoginForm>
</div> </div>
<Footer /> <Footer />

Loading…
Cancel
Save