I have this component. But after I upload the video to the server, the <DisplayVideo> component running but inside the video is not loading, and poster not showing. I even tried setting key with Date.now() to force rerender but no luck. I don’t understand the behaviour.
const VideoInput = ({ videos, onChange }: Props) => {
const ref = useRef<any>(null);
const { dispatch } = useContext(DispatchContext);
const { seqPartner } = useSelector((state: RootState) => state.partner);
const [duration, setDuration] = useState('');
const selectVideoFile = (e: any) => {
if (e.target?.files[0]?.size === 0) return null;
const newInput = e.target?.files[0];
const maxSize = 100 * 1024 * 1024;
if (newInput.size > maxSize) {
alert('only 100mb');
return null;
}
const formData: any = new FormData();
formData.append('videoFile', newInput);
uploadVideoToServer(formData);
};
const uploadVideoToServer = async (formData: FormData) => {
try {
dispatch({ type: 'LOADING_START' });
await api
.post('/videos/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then((data) => {
if (data.status !== 200) {
alert('server error');
} else {
const { data: videoData } = data;
onChange('videos', [
{
id: videoData?.id,
fileName: videoData?.fileName,
fileUrl: videoData?.fileUrl,
videoImgUrl: videoData?.videoImgUrl,
fileData: formData.get('videoFile'),
},
]);
}
});
dispatch({ type: 'LOADING_END' });
} catch (error) {
dispatch({ type: 'LOADING_END' });
console.error(error);
}
};
const handleDelete = (e: any) => {
e.stopPropagation();
alert('deleted');
};
const clickVideo = (e: any) => {
e.stopPropagation();
if (ref?.current) {
const video = ref?.current;
var isPlaying =
video.currentTime > 0 && !video.paused && !video.ended && video.readyState > video.HAVE_CURRENT_DATA;
if (isPlaying) {
ref?.current?.pause();
} else {
ref?.current?.play();
}
}
};
const handleLoadedMetadata = (e: any) => {
console.log(e);
const video: any = ref.current;
console.log('metadata', video);
if (video) {
const duration = video.duration;
const minutes = Math.floor(duration / 60)
.toString()
.padStart(2, '0');
const seconds = Math.floor(duration % 60)
.toString()
.padStart(2, '0');
setDuration(`${minutes}:${seconds}`);
}
};
return (
<Wrapper>
<div style={{ paddingLeft: 64, paddingRight: 24, marginTop: 12 }}>
{videos?.length > 0 && (
<DisplayVideo key={videos.length}>
<div className="video">
<video
ref={ref}
poster={videos[0]?.videoImgUrl}
preload="metadata"
onLoadedMetadata={handleLoadedMetadata}
controls={false}
autoPlay={false}
>
<source src={videos[0]?.fileUrl} type="video/mp4" />
</video>
<div className="deleteButtonContainer">
<img src={DeleteIcon} alt="" onClick={handleDelete} />
</div>
<div className="darkOverlay">
<div className="playButton" onClick={clickVideo}>
<img src={VideoPlayButton} alt="" />
</div>
</div>
{!!duration.length && <div className="duration">{duration}</div>}
</div>
</DisplayVideo>
)}
<Label disabled={videos?.length > 0}>
<input
type="file"
accept="video/mp4,video/mkv, video/x-m4v,video/*"
disabled={videos.length > 0}
onInput={selectVideoFile}
/>
<img src={VideoUploadIcon} alt="" />
upload video
<span style={{ minWidth: '6px' }}></span>
</Label>
</div>
</Wrapper>
);
};
Tried everything with useEffect and other things