Ever bored with nothing interesting at work? Well, that’s when I decided to scratch my itch to tinker around with the current state of browser APIs. Could we compress videos directly through web APIs? In this blog, I’ll show you how to use modern browser features to compress MP4 videos to WebM format—all within a React app.
Before we dive in, make sure you've got:
Quick setup:
<p>npm install antd</p>
Let's set up our React component with all the React imports:
<p>import { useState, useRef, useEffect, ChangeEvent } from "react";<br> import { Button, Progress, message, Flex } from "antd";</p> <p>const VideoCompression = () => {<br> const [sourceVideo, setSourceVideo] = useState<File | null>(null);<br> const [compressedVideo, setCompressedVideo] = useState<Blob | null>(null);<br> const [isCompressing, setIsCompressing] = useState(false);<br> const [progress, setProgress] = useState(0);<br> const [width, setWidth] = useState<string>("");<br> const [height, setHeight] = useState<string>("");<br> const videoRef = useRef<HTMLVideoElement>(null);<br> const inputRef = useRef<HTMLInputElement>(null);</p>
We need a way to choose our MP4 file:
<p>const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {<br> if (!event.target.files) return;<br> const file = event.target.files[0];<br> if (file && file.type.startsWith("video/")) {<br> setSourceVideo(file);<br> setCompressedVideo(null);<br> } else {<br> message.error("Please select a valid video file.");<br> }<br> };</p>
Let's get the video metadata:
<p>useEffect(() => {<br> if (sourceVideo) {<br> const video = document.createElement("video");<br> video.onloadedmetadata = () => {<br> setWidth(video.videoWidth.toString());<br> setHeight(video.videoHeight.toString());<br> };<br> video.src = URL.createObjectURL(sourceVideo);<br> }<br> }, [sourceVideo]);</p>
Here's where the magic happens:
<p>const compressVideo = async () => {<br> if (!sourceVideo) {<br> message.error("Please upload a video first.");<br> return;<br> }<br> setIsCompressing(true);<br> setProgress(0);<br> try {<br> const stream = videoRef.current?.captureStream();<br> const mediaRecorder = new MediaRecorder(stream, {<br> mimeType: "video/webm",<br> videoBitsPerSecond: 1000000,<br> });<br> const chunks: BlobPart[] = [];<br> mediaRecorder.ondataavailable = (event) => {<br> if (event.data.size > 0) {<br> chunks.push(event.data);<br> }<br> };<br> mediaRecorder.onstop = () => {<br> const blob = new Blob(chunks, { type: "video/webm" });<br> setCompressedVideo(blob);<br> setIsCompressing(false);<br> setProgress(100);<br> };<br> if (!videoRef.current) return;<br> videoRef.current.onloadedmetadata = () => {<br> videoRef.current!.muted = true;<br> videoRef.current?.play();<br> mediaRecorder.start();<br> };<br> videoRef.current.onended = () => {<br> mediaRecorder.stop();<br> videoRef.current?.pause();<br> };<br> videoRef.current.ontimeupdate = () => {<br> if (!videoRef.current) return;<br> const progress =<br> (videoRef.current.currentTime / videoRef.current.duration) * 100;<br> setProgress(progress);<br> };<br> if (!videoRef.current) return;<br> videoRef.current.width = Number.parseFloat(width);<br> videoRef.current.height = Number.parseFloat(height);<br> videoRef.current.src = URL.createObjectURL(sourceVideo);<br> } catch (err) {<br> message.error("Error compressing video: " + (err as Error).message);<br> setIsCompressing(false);<br> }<br> };</p>
<p>const downloadCompressedVideo = () => {<br> if (compressedVideo) {<br> const url = URL.createObjectURL(compressedVideo);<br> const a = document.createElement("a");<br> a.href = url;<br> a.download = "compressed_video.webm";<br> document.body.appendChild(a);<br> a.click();<br> document.body.removeChild(a);<br> URL.revokeObjectURL(url);<br> }<br> };</p>
Here's a sneak peek of our complete work:
Deployment Link:
https://abhirup-99.github.io/browser-compression-webm/
Code Link:
https://github.com/Abhirup-99/browser-compression-webm
Congratulations! You've just built a powerful MP4 to WebM video compressor using React. Your web videos will now load faster than ever, delighting users and boosting your site's performance.
The above is the detailed content of Compressing videos to webm in the browser. For more information, please follow other related articles on the PHP Chinese website!