The following code works fine on Firefox whether autoplay
is true or false but not on Chromium. How can I fix it?
EDIT 1: I found out that I can begin with autoplay = true
and then in onloadeddata
pause the video with video.pause()
.
EDIT 2: Another interesting thing was found. You can set video.currentTime
to, for example 5, to capture the 5th second and if the duration of your video is less than, again for example 5s, the last frame will be drawn on the canvas. And then you can set it back to zero inonloadeddata
event. It is good because in most cases the first seconds are black.
let inputFile = document.getElementById("files"); let container = document.getElementById("container"); inputFile.addEventListener("change", inputFileEventHandler); function inputFileEventHandler() { for (const file of inputFile.files) { let canvas = document.createElement("canvas"); canvas.style.border = "1px solid gray"; canvas.style.padding = "16px"; let video = document.createElement("video"); video.style.width = "250px"; video.style.height = "auto"; video.style.border = "1px solid gray"; video.style.padding = "16px"; video.autoplay = false; video.src = URL.createObjectURL(file); container.append(video); container.append(canvas); video.onloadeddata = () => { canvas.getContext("2d").drawImage(video, 0, 0, video.videoWidth, video.videoHeight); } } }
<!DOCTYPE html> <html> <body> <input type="file" id="files" name="files" multiple> <div id="container"></div> </body> </html>
Advertisement
Answer
I have no idea what is the problem
Seems like preload: auto
helps, but I’m not sure
Handling multiple events at once makes it work, but not always
let inputFile = document.getElementById("files"); let container = document.getElementById("container"); inputFile.addEventListener("change", inputFileEventHandler); const events = `abort canplay canplaythrough durationchange loadeddata suspend`.split('n') function inputFileEventHandler() { for (const file of inputFile.files) { const video = document.createElement("video"); video.style.width = "250px"; video.style.height = "auto"; video.style.border = "1px solid gray"; video.style.padding = "16px"; video.autoplay = false; video.preload = 'auto'; video.src = URL.createObjectURL(file); container.append(video); for (const event of events) { const canvas = document.createElement("canvas"); canvas.style.border = "1px solid gray"; canvas.style.padding = "16px"; container.append(canvas); video.addEventListener(event, () => { console.log(event) const ctx = canvas.getContext("2d") ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); ctx.font = "24px serif"; ctx.fillText(event, 10, 50); }) } } }
<!DOCTYPE html> <html> <body> <input type="file" id="files" name="files" multiple> <div id="container"></div> </body> </html>