我在我的Next.JS应用程序中使用ffmpeg.wasm。
这里是我的规格:
"@ffmpeg/ffmpeg": "^0.12.5",
"@ffmpeg/util": "^0.12.0",
"next": "^13.0.6",
"react": "^18.2.0",
我想简单地从画布上录制一个5s的视频,所以我尝试了:
'use client'
import React, { useEffect, useRef, useState } from 'react';
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util';
const CanvasVideoRecorder = () => {
const canvasRef = useRef(null);
const videoChunksRef = useRef([]);
const ffmpegRef = useRef(new FFmpeg({ log: true }));
const [loaded, setLoaded] = useState(false);
const [videoUrl, setVideoUrl] = useState(null);
const load = async () => {
await ffmpegRef.current.load({
coreURL: '/js/ffmpeg-core.js',
wasmURL: '/js/ffmpeg-core.wasm',
});
setLoaded(true);
};
useEffect(() => {
const ctx = canvasRef.current.getContext('2d');
function drawFrame(timestamp) {
ctx.fillStyle = `rgb(${(Math.sin(timestamp / 500) * 128) + 128}, 0, 0)`;
ctx.fillRect(0, 0, canvasRef.current.width, canvasRef.current.height);
requestAnimationFrame(drawFrame);
}
requestAnimationFrame(drawFrame);
}, []);
const startRecording = async () => {
const videoStream = canvasRef.current.captureStream(30);
const videoRecorder = new MediaRecorder(videoStream, { mimeType: 'video/webm' });
videoRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
videoChunksRef.current.push(event.data);
}
};
videoRecorder.start();
setTimeout(() => videoRecorder.stop(), 5000);
videoRecorder.onstop = async () => {
try {
await ffmpegRef.current.writeFile('recorded.webm', await fetchFile(new Blob(videoChunksRef.current, { type: 'video/webm' })));
await ffmpegRef.current.exec('-y', '-i', 'recorded.webm', '-an', '-c:v', 'copy', 'output_copy.webm');
const data = await ffmpegRef.current.readFile('output_copy.webm');
const url = URL.createObjectURL(new Blob([data.buffer], { type: 'video/webm' }));
setVideoUrl(url);
} catch (error) {
console.error("Error during processing:", error);
}
};
};
return (
<div>
<canvas ref={canvasRef} width="640" height="480"></canvas>
{loaded ? (
<>
<button onClick={startRecording}>Start Recording</button>
{videoUrl && <video controls src={videoUrl}></video>}
</>
) : (
<button onClick={load}>Load FFmpeg</button>
)}
</div>
);
};
export default CanvasVideoRecorder;
我不知道为什么,但它捕捉到一个错误:
ErrnoError: FS error
当我这样做时会发生这个错误:
await ffmpegRef.current.exec('-y', '-i', 'recorded.webm', '-an', '-c:v', 'copy', 'output_copy.webm');
const data = await ffmpegRef.current.readFile('output_copy.webm');
recorded.webm
文件写得正确,我可以读取它,ffmpegRef.current
定义得很好,那么我的逻辑有什么问题,为什么exec命令不起作用?
1条答案
按热度按时间lfapxunr1#
首先,我忘记了
exec
中的方括号。其次,我不知道WebM转换到底有什么问题,但我最终使用了
mp4
:现在它工作得很好!