background

Cliche: JS to get the first frame of video, has always known about how to do, but it is also the first practice, often this kind of thing is the existence of the general pit.

Open to

The first thing is canvas. It has a getContext method above it, which gets a drawing context and can start drawing. Canvas also has a method called drawImage, which accepts an image or video object and can obtain the image of the object.

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
Copy the code

Ok, now that we have the tools, all we need to do is create a video object, put the URL of our video in it, set the length and width, listen for the video event, and then use the drawImage method described above to get a Base64 image. Video How to choose several events:

Play: triggered when play and autoplay start pause: triggered when data is being played waiting, not playing playing usually when getting the current duration and total duration loadeddata: This event is triggered when the current frame has been loaded, but there is not enough data to load the next frameCopy the code

I’m using the loadedData event here

let video = document.createElement('video') video.setAttribute('crossOrigin', Video.setattribute (' SRC ', url) video.setAttribute('width', 400) video.setattribute ('height', 240) video.addEventListener('loadeddata', Function () {let canvas = document.createElement('canvas') let width = video.width // Let height = video.height canvas.width = width canvas.height = height console.log(this, video) canvas.getContext('2d').drawImage(this, 0, 0, width, // Draw Canvas dataURL = canvas. ToDataURL ('image/jpeg') // Convert to base64})Copy the code

Now let’s try this code in actionWow, black screen. What a joke. What’s going on here? Emmm probably feels that the current time is wrong, so I will manually set the time of the current video.

Video. CurrentTime = 0.1Copy the code

Ok and that’s done getting the first frame of the video.

You think this is the end? Too young

It was all in Chrome, now it’s real. IPhone doesn’t autoload, so autoplay and fraternal attributes,

        video.setAttribute('autoplay', true)
        video.setAttribute('muted', true)
Copy the code

But by default, the iPhone will play the video in full screen, even if you don’t write it in HTML. So, plus inline play.

        video.setAttribute('playsinline', true)
        video.setAttribute('webkit-playsinline', true)
Copy the code

Add a little delay, wrap it with a promise, and you’re ready to go. Complete code:

GetVideoBase64 (url) {return new Promise(function (resolve, resolve)) reject) { let dataURL = '' let video = document.createElement('video') video.setAttribute('crossOrigin', 'anonymous')// Processing cross-domain video.setattribute (' SRC ', URL) video.setattribute ('autoplay', true) video.setattribute (' conservation ', true) video.setAttribute('playsinline', true) video.setAttribute('webkit-playsinline', true) video.setAttribute('width', 400) video.setAttribute('height', 101) video.currentTime = 0.1 video.addeventListener (' loadedData ', Function () {setTimeout(() => {let canvas = document.createElement('canvas') let width = video.width // The canvas size is the same as the image  let height = video.height canvas.width = width canvas.height = height canvas.getContext('2d').drawImage(this, 0, 0, Width, height) // Draw Canvas dataURL = canvas.todataURL ('image/jpeg') // Convert to base64 resolve(dataURL)}, 100)})},Copy the code

Pit point

There’s a lot of stuff online, but it doesn’t work. But this is my own practice out, and can be used. Ios and Android are really different, this shows that doesn’t show, adaptation is a disgusting thing