i was able to open m3u8 format using hls.js, but i have problem, i need to show preview images from m3u8 when user hover the timeline, how to do this, thanks in advance for your answers)
<div
className="timeline-container"
onMouseMove={handleTimeLineUpdate}
onMouseDown={toggleScrubbing}
ref={timelineContainer}
>
<div className="timeline">
<img className="preview-img" ref={previewImgRef} alt="previewImg" />
<div className="thumb-indicator"></div>
</div>
</div>
there is my functions for getting iframe from m3u8:
const getIframePlaylistUrlsFromM3U8 = async () => {
try {
const response = await fetch(movie.transcode_file);
const m3u8Content = await response.text();
const iframePlaylistUrls = extractIframePlaylistUrls(m3u8Content);
return iframePlaylistUrls;
} catch (error) {
console.error("Error fetching or parsing M3U8 file", error);
return [];
}
};
there i have problem, when i log iframePlaylistUrls it has values, but when another function receives it it shows empty
const extractIframePlaylistUrls = (m3u8Content) => {
const iframePlaylistUrls = parseM3U8(m3u8Content);
return iframePlaylistUrls;
};
const parseM3U8 = (m3u8Content) => {
const regex = /EXT-X-I-FRAME-STREAM-INF:.*URI="(.+)"/g;
const matches = m3u8Content.matchAll(regex);
return Array.from(matches, (match) => match[1]);
};
const updatePreviewImageOnHover = async (e) => {
const rect = timelineContainer.current.getBoundingClientRect();
const percent =
Math.min(Math.max(0, e.clientX - rect.x), rect.width) / rect.width;
const iframePlaylistUrls = await getIframePlaylistUrlsFromM3U8();
const iframeIndex = Math.max(
0,
Math.floor(percent * iframePlaylistUrls.length)
);
const thumbnailImageUrl = await extractThumbnailImageUrl(
iframePlaylistUrls[iframeIndex]
);
previewImgRef.current.src = thumbnailImageUrl;
};
const extractThumbnailImageUrl = async (iframePlaylistUrl) => {
try {
const response = await fetch(iframePlaylistUrl);
const iframePlaylistContent = await response.text();
const thumbnailImageUrl = parseIframePlaylist(iframePlaylistContent);
return thumbnailImageUrl;
} catch (error) {
console.error("Error fetching or parsing iframe playlist", error);
return "";
}
};
const parseIframePlaylist = (iframePlaylistContent) => {
const thumbnailImageUrl = parseIframePlaylistUrl(iframePlaylistContent);
return thumbnailImageUrl;
};
const parseIframePlaylistUrl = (iframePlaylistContent) => {
const regex = /#EXT-X-IMAGE:(.+)/;
const match = iframePlaylistContent.match(regex);
return match ? match[1] : "";
};
when i hover timeline this function runs
const handleTimeLineUpdate = (e) => {
const rect = timelineContainer.current.getBoundingClientRect();
const percent =
Math.min(Math.max(0, e.clientX - rect.x), rect.width) / rect.width;
updatePreviewImageOnHover(e);
timelineContainer.current.style.setProperty("--preview-position", percent);
if (isScrubbing.current) {
e.preventDefault();
// thumbnailImgRef.current.src = previewImgSrc;
timelineContainer.current.style.setProperty(
"--progress-position",
percent
);
}
};