frontend_adaptive_learning/src/roles/user/review/views/components/MediaViewer.jsx
2024-12-05 15:30:22 +07:00

123 lines
4.6 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import Skeleton from 'react-loading-skeleton';
const MediaViewer = ({ mediaUrls }) => {
const [loadedMedia, setLoadedMedia] = useState([]);
const [loading, setLoading] = useState(true);
function isMediaUrl(url) {
const urls = url[0];
const audioExtensions = ['.mp3', '.wav', '.ogg', '.m4a', '.aac', '.flac'];
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'];
const lowercasedUrl = urls.toLowerCase();
const isAudio = audioExtensions.some(extension => lowercasedUrl.endsWith(extension));
const isImage = imageExtensions.some(extension => lowercasedUrl.endsWith(extension));
return isAudio || isImage;
}
const preloadMedia = (urls) => {
return Promise.all(
urls.map((url) => {
return new Promise((resolve, reject) => {
const mediaType = url.split('.').pop();
if (['jpg', 'jpeg', 'png', 'gif'].includes(mediaType)) {
const img = new Image();
img.src = url;
img.onload = () => resolve({ type: 'image', url });
img.onerror = () => reject(`Failed to load image: ${url}`);
} else if (['mp3', 'wav'].includes(mediaType)) {
const audio = new Audio();
audio.src = url;
audio.onloadedmetadata = () => resolve({ type: 'audio', url });
audio.onerror = () => reject(`Failed to load audio: ${url}`);
} else {
resolve({ type: 'unknown', url });
}
});
})
);
};
const renderVideo = (url) => {
// Cek apakah ini link YouTube
if (url.includes('youtube.com') || url.includes('youtu.be')) {
const youtubeId = url.includes('youtube.com')
? new URLSearchParams(new URL(url).search).get('v') // Ambil ID dari link YouTube
: url.split('/').pop(); // Ambil ID dari youtu.be link
return (
<iframe
src={`https://www.youtube.com/embed/${youtubeId}`}
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
title="YouTube Video"
className='video-box'
></iframe>
);
} else if (url.includes('drive.google.com')) {
const driveId = url.includes('file/d/') ? url.split('file/d/')[1].split('/')[0] : '';
return (
<iframe
src={`https://drive.google.com/file/d/${driveId}/preview`}
allow="autoplay"
title="Google Drive Video"
className='video-box'
></iframe>
);
} else {
return (
<video controls className='video-box'>
<source src={url} type="video/mp4" />
Your browser does not support the video tag.
</video>
);
}
};
useEffect(() => {
if (mediaUrls && mediaUrls.length > 0 && isMediaUrl(mediaUrls)) {
preloadMedia(mediaUrls)
.then((loaded) => {
setLoadedMedia(loaded);
setLoading(false);
})
.catch((error) => {
console.error(error);
setLoading(false);
});
} else {
setLoading(false);
}
}, [mediaUrls]);
if (loading) {
return (
<Skeleton containerClassName='w-50 d-block' className='w-100 mb-1 rounded-3' style={{height:"20vh"}} />
);
}
return (
<div className='my-1'>
{isMediaUrl(mediaUrls) ? (
loadedMedia.map((media, index) => {
if (media.type === 'image') {
return <img key={index} src={media.url} alt={`Media ${index}`} />;
} else if (media.type === 'audio') {
return <audio key={index} controls src={media.url}></audio>;
} else {
return <div key={index}>Unknown media type</div>;
}
})
) : (
renderVideo(mediaUrls[0]) // Panggil fungsi renderVideo dengan URL yang benar
)}
</div>
);
};
export default MediaViewer;