next.js FFmpeg Wasm,从画布创建视频时出错

blpfk2vs  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(117)

我在我的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命令不起作用?

lfapxunr

lfapxunr1#

首先,我忘记了exec中的方括号。
其次,我不知道WebM转换到底有什么问题,但我最终使用了mp4

await ffmpeg.exec(['-i', 'recorded.webm', '-i', 'audio.mp3', '-c:v', 'libx264', '-c:a', 'aac', 'output.mp4']);
const data = await ffmpeg.readFile('output.mp4');

现在它工作得很好!

相关问题