Skip to content

Instantly share code, notes, and snippets.

@rogie
Last active August 31, 2023 04:22
Show Gist options
  • Save rogie/1bb66b6a80ab1711a1e3ce1863df0316 to your computer and use it in GitHub Desktop.
Save rogie/1bb66b6a80ab1711a1e3ce1863df0316 to your computer and use it in GitHub Desktop.
Embedding video on Figma Canvas
let errorCreatingVideo = false
let video, paint
// Figma's pro (and higher plans) allow for embedding videos. There is no native code for a Figma plugin to be able
// to test what plan a user is on. So, this code attempts to create the video. If it can't, then it will notify the user
// of the error (I would imagine this error also will fire if the video is too large).
try {
video = await figma.createVideoAsync(args.webm)
paint = {
videoHash: video.hash,
type: "VIDEO",
scaleMode: "FILL"
}
} catch (error) {
errorCreatingVideo = true
figma.notify(error.toString(), { error: true })
}
// If a video object was created successfully, then we will create a shape on the screen and then fill it with the video paint
if (!errorCreatingVideo) {
let layer = figma.createRectangle()
layer.resize(2048, 2048)
layer.fills = [paint]
figma.currentPage.appendChild(layer)
figma.currentPage.selection = [layer]
figma.viewport.scrollAndZoomIntoView(figma.currentPage.selection)
}
async function exportVideo(canvas, duration = 5000, loop = false) {
return new Promise((resolve, reject) => {
const timeSlice = 1000
const chunks = []; // here we will store our recorded media chunks (Blobs)
const stream = canvas.captureStream(30); // grab our canvas MediaStream
const options = {
mimeType: 'video/webm;codecs=vp9,opus'
};
const rec = new MediaRecorder(stream, options); // init the recorder
// every time the recorder has new data, we will store it in our array
rec.ondataavailable = (e) => {
if (e.data.size > 0) {
chunks.push(e.data);
if (chunks.length - 1 > duration / timeSlice) {
if (rec.state !== "inactive") {
rec.stop()
} else {
resolve(new Blob(chunks, { type: 'video/webm' }))
}
}
}
}
rec.start(timeSlice);
})
}
// export the video from the canvas (returns a blob of the webm
let canvas = canvasContainer.querySelector('canvas')
let webm = await exportVideo(canvas, duration * 1000)
let buffer = new Uint8Array(await webm.arrayBuffer())
// send the buffer to code.ts (the Figma scene)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment