[这是我的代码:videoDetails组件->
import React, { useEffect, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { markLectureAsComplete } from "../../../services/operations/courseDetailsAPI";
import { updateCompletedLectures } from "../../../slices/viewCourseSlice";
import { Player } from "video-react";
import { BigPlayButton } from "video-react";
import "video-react/dist/video-react.css";
import IconBtn from "../../common/IconBtn";
import { AiFillPlayCircle } from "react-icons/ai";
const VideoDetails = () => {
const { courseId, sectionId, subSectionId } = useParams();
const navigate = useNavigate();
const dispatch = useDispatch();
const location = useLocation();
const playerRef = useRef();
const { token } = useSelector((state) => state.auth);
const { courseSectionData, courseEntireData, completedLectures } =
useSelector((state) => state.viewCourse);
const [previewSource, setPreviewSource] = useState("");
const [videoData, setVideoData] = useState([]);
const [videoEnded, setVideoEnded] = useState(false);
const [loading, setLoading] = useState(false);
useEffect(() => {
const setVideoSpecificDetails = async () => {
if (!courseSectionData.length) return;
if (!courseId && !sectionId && !subSectionId) {
navigate("/dashboard/enrolled-courses");
} else {
//let's assume k all 3 fields are present
const filteredData = courseSectionData.filter(
(course) => course._id === sectionId
);
const filteredVideoData = filteredData?.[0].subSection.filter(
(data) => data._id === subSectionId
);
setVideoData(filteredVideoData[0]);
setPreviewSource(courseEntireData.thumbnail);
setVideoEnded(false);
}
};
setVideoSpecificDetails();
}, [courseSectionData, courseEntireData, location.pathname]);
console.log("COURSE SECTION DATA", courseSectionData, courseEntireData);
const isFirstVideo = () => {
const currentSectionIndex = courseSectionData.findIndex(
(data) => data._id === sectionId
);
const currentSubSectionIndex = courseSectionData[
currentSectionIndex
].subSectionId.findIndex((data) => data._id === subSectionId);
if (currentSectionIndex === 0 && currentSubSectionIndex === 0) {
return true;
} else {
return false;
}
};
const isLastVideo = () => {
const currentSectionIndex = courseSectionData.findIndex(
(data) => data._id === sectionId
);
const noOfSubSections =
courseSectionData[currentSectionIndex].subSection.length;
const currentSubSectionIndex = courseSectionData[
currentSectionIndex
].subSectionId.findIndex((data) => data._id === subSectionId);
if (
currentSectionIndex === courseSectionData.length - 1 &&
currentSubSectionIndex === noOfSubSections - 1
) {
return true;
} else {
return false;
}
};
const goToNextVideo = () => {
const currentSectionIndex = courseSectionData.findIndex(
(data) => data._id === sectionId
);
const noOfSubSections =
courseSectionData[currentSectionIndex].subSection.length;
const currentSubSectionIndex = courseSectionData[
currentSectionIndex
].subSectionId.findIndex((data) => data._id === subSectionId);
if (currentSubSectionIndex !== noOfSubSections - 1) {
//same section ki next video me jao
const nextSubSectionId =
courseSectionData[currentSectionIndex].subSection[
currentSectionIndex + 1
]._id;
//next video pr jao
navigate(
`/view-course/${courseId}/section/${sectionId}/sub-section/${nextSubSectionId}`
);
} else {
//different section ki first video
const nextSectionId = courseSectionData[currentSectionIndex + 1]._id;
const nextSubSectionId =
courseSectionData[currentSectionIndex + 1].subSection[0]._id;
///iss voide par jao
navigate(
`/view-course/${courseId}/section/${nextSectionId}/sub-section/${nextSubSectionId}`
);
}
};
const goToPrevVideo = () => {
const currentSectionIndex = courseSectionData.findIndex(
(data) => data._id === sectionId
);
const noOfSubSections =
courseSectionData[currentSectionIndex].subSection.length;
const currentSubSectionIndex = courseSectionData[
currentSectionIndex
].subSectionId.findIndex((data) => data._id === subSectionId);
if (currentSubSectionIndex !== 0) {
//same section , prev video
const prevSubSectionId =
courseSectionData[currentSectionIndex].subSection[
currentSubSectionIndex - 1
];
//iss video par chalge jao
navigate(
`/view-course/${courseId}/section/${sectionId}/sub-section/${prevSubSectionId}`
);
} else {
//different section , last video
const prevSectionId = courseSectionData[currentSectionIndex - 1]._id;
const prevSubSectionLength =
courseSectionData[currentSectionIndex - 1].subSection.length;
const prevSubSectionId =
courseSectionData[currentSectionIndex - 1].subSection[
prevSubSectionLength - 1
]._id;
//iss video par chalge jao
navigate(
`/view-course/${courseId}/section/${prevSectionId}/sub-section/${prevSubSectionId}`
);
}
};
const handleLectureCompletion = async () => {
///dummy code, baad me we will replace it witht the actual call
setLoading(true);
//PENDING - > Course Progress PENDING
const res = await markLectureAsComplete(
{ courseId: courseId, subSectionId: subSectionId },
token
);
//state update
if (res) {
dispatch(updateCompletedLectures(subSectionId));
}
setLoading(false);
};
return (
<div className="flex flex-col gap-5 text-white">
{!videoData ? (
<img
src={previewSource}
alt="Preview"
className="h-full w-full rounded-md object-cover"
/>
) : (
<Player
ref={playerRef}
aspectRatio="16:9"
playsInline
onEnded={() => setVideoEnded(true)}
src={videoData?.videoUrl}
>
<AiFillPlayCircle
fontSize={25}
position="center"
className="text-white"
/>
{/* Render When Video Ends */}
{videoEnded && (
<div
style={{
backgroundImage:
"linear-gradient(to top, rgb(0, 0, 0), rgba(0,0,0,0.7), rgba(0,0,0,0.5), rgba(0,0,0,0.1)",
}}
className="full absolute inset-0 z-[100] grid h-full place-content-center font-inter"
>
{!completedLectures.includes(subSectionId) && (
<IconBtn
disabled={loading}
onclick={() => handleLectureCompletion()}
text={!loading ? "Mark As Completed" : "Loading..."}
customClasses="text-xl max-w-max px-4 mx-auto"
/>
)}
<IconBtn
disabled={loading}
onclick={() => {
if (playerRef?.current) {
// set the current time of the video to 0
playerRef?.current?.seek(0);
setVideoEnded(false);
}
}}
text="Rewatch"
customClasses="text-xl max-w-max px-4 mx-auto mt-2"
/>
<div className="mt-10 flex min-w-[250px] justify-center gap-x-4 text-xl">
{!isFirstVideo() && (
<button
disabled={loading}
onClick={goToPrevVideo}
className="blackButton"
>
Prev
</button>
)}
{!isLastVideo() && (
<button
disabled={loading}
onClick={goToNextVideo}
className="blackButton"
>
Next
</button>
)}
</div>
</div>
)}
</Player>
)}
<h1 className="mt-4 text-3xl font-semibold">{videoData?.title}</h1>
<p className="pt-2 pb-6">{videoData?.description}</p>
</div>
);
};
export default VideoDetails;
字符串
](https://i.stack.imgur.com/XMFJd.png)
我创建自定义视频播放器与React
库-video-react.在此视频组件Player
我想播放不同的部分和小节视频就像每当点击下一个转到下一个视频以及prevoius按钮。
视频播放器不工作,它显示错误,我附上截图。
ERROR image的
1条答案
按热度按时间lf3rwulv1#
根据提供的代码和错误消息,问题似乎与video-react库中的Player组件有关。该错误可能是由于Player组件中的AiFillPlayCircle组件使用不正确。
要解决此问题,您应该从Player组件中删除AiFillPlayCircle组件,因为它似乎会导致冲突或渲染问题。相反,您可以使用video-react库提供的BigPlayButton组件在视频播放器上显示播放按钮。
下面是修改后的代码:
字符串
通过使用BigPlayButton而不是AiFillPlayCircle,您应该能够解决此问题。