Update
This commit is contained in:
@@ -3,6 +3,8 @@ import { fetchFile, toBlobURL } from '@ffmpeg/util';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
|
||||
const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
const [showConsoleLogs] = useState(false);
|
||||
|
||||
const ffmpegRef = useRef(new FFmpeg());
|
||||
|
||||
const [isExporting, setIsExporting] = useState(false);
|
||||
@@ -11,12 +13,12 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
|
||||
const generateFFmpegCommand = useCallback(
|
||||
(is_string = true, useLocalFiles = false) => {
|
||||
console.log('🎬 STARTING FFmpeg generation');
|
||||
showConsoleLogs && console.log('🎬 STARTING FFmpeg generation');
|
||||
|
||||
const videos = timelineElements.filter((el) => el.type === 'video');
|
||||
const texts = timelineElements.filter((el) => el.type === 'text');
|
||||
|
||||
console.log('Videos found:', videos.length);
|
||||
showConsoleLogs && console.log('Videos found:', videos.length);
|
||||
|
||||
if (videos.length === 0) {
|
||||
if (is_string) {
|
||||
@@ -47,12 +49,12 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
videoLayer = `v${i}_out`;
|
||||
});
|
||||
|
||||
console.log('🎵 PROCESSING AUDIO FOR', videos.length, 'VIDEOS');
|
||||
showConsoleLogs && console.log('🎵 PROCESSING AUDIO FOR', videos.length, 'VIDEOS');
|
||||
|
||||
let audioOutputs = [];
|
||||
videos.forEach((v, i) => {
|
||||
const delay = Math.round(v.startTime * 1000);
|
||||
console.log(`🎵 Audio ${i}: delay=${delay}ms, inPoint=${v.inPoint}, duration=${v.duration}`);
|
||||
showConsoleLogs && console.log(`🎵 Audio ${i}: delay=${delay}ms, inPoint=${v.inPoint}, duration=${v.duration}`);
|
||||
filters.push(`[${i}:a]atrim=start=${v.inPoint}:duration=${v.duration},asetpts=PTS-STARTPTS,adelay=${delay}|${delay}[a${i}]`);
|
||||
audioOutputs.push(`[a${i}]`);
|
||||
});
|
||||
@@ -66,7 +68,7 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
audioArgs = ['-map', '[audio_final]', '-c:a', 'aac'];
|
||||
}
|
||||
|
||||
console.log('🎵 Audio args:', audioArgs);
|
||||
showConsoleLogs && console.log('🎵 Audio args:', audioArgs);
|
||||
|
||||
texts.forEach((t, i) => {
|
||||
const escapedText = t.text.replace(/'/g, is_string ? "\\'" : "'").replace(/:/g, '\\:');
|
||||
@@ -82,7 +84,7 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
});
|
||||
|
||||
const filterComplex = filters.join('; ');
|
||||
console.log('🎵 Filter includes atrim:', filterComplex.includes('atrim'));
|
||||
showConsoleLogs && console.log('🎵 Filter includes atrim:', filterComplex.includes('atrim'));
|
||||
|
||||
const finalArgs = [
|
||||
...inputArgs,
|
||||
@@ -107,11 +109,11 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
const audioMap = audioArgs.length > 0 ? ` ${audioArgs.join(' ')}` : '';
|
||||
const command = `ffmpeg ${inputs} -filter_complex "${filterComplex}" -map "[${videoLayer}]"${audioMap} -c:v libx264 -pix_fmt yuv420p -r 30 -t ${totalDuration} output.mp4`;
|
||||
|
||||
console.log('🎵 FINAL COMMAND HAS AUDIO:', command.includes('atrim') && command.includes('audio_final'));
|
||||
showConsoleLogs && console.log('🎵 FINAL COMMAND HAS AUDIO:', command.includes('atrim') && command.includes('audio_final'));
|
||||
|
||||
return command;
|
||||
} else {
|
||||
console.log('🎵 FINAL ARGS HAVE AUDIO:', finalArgs.includes('atrim') && finalArgs.includes('audio_final'));
|
||||
showConsoleLogs && console.log('🎵 FINAL ARGS HAVE AUDIO:', finalArgs.includes('atrim') && finalArgs.includes('audio_final'));
|
||||
|
||||
return finalArgs;
|
||||
}
|
||||
@@ -124,8 +126,8 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
}, [generateFFmpegCommand]);
|
||||
|
||||
const copyFFmpegCommand = useCallback(() => {
|
||||
console.log('🎬 FFMPEG COMMAND GENERATED:');
|
||||
console.log('Command:', ffmpegCommand);
|
||||
showConsoleLogs && console.log('🎬 FFMPEG COMMAND GENERATED:');
|
||||
showConsoleLogs && console.log('Command:', ffmpegCommand);
|
||||
navigator.clipboard.writeText(ffmpegCommand);
|
||||
}, [ffmpegCommand]);
|
||||
|
||||
@@ -144,32 +146,32 @@ const useVideoExport = ({ timelineElements, dimensions, totalDuration }) => {
|
||||
});
|
||||
|
||||
ffmpeg.on('log', ({ message }) => {
|
||||
console.log(message);
|
||||
showConsoleLogs && console.log(message);
|
||||
});
|
||||
|
||||
const baseURL = 'https://unpkg.com/@ffmpeg/core@0.12.6/dist/esm';
|
||||
const coreURL = `${baseURL}/ffmpeg-core.js`;
|
||||
const wasmURL = `${baseURL}/ffmpeg-core.wasm`;
|
||||
|
||||
console.log('Converting JS coreURL...');
|
||||
showConsoleLogs && console.log('Converting JS coreURL...');
|
||||
const coreBlobURL = await toBlobURL(coreURL, 'text/javascript');
|
||||
console.log('JS coreURL ready:', coreBlobURL);
|
||||
showConsoleLogs && console.log('JS coreURL ready:', coreBlobURL);
|
||||
|
||||
console.log('Converting WASM URL...');
|
||||
showConsoleLogs && console.log('Converting WASM URL...');
|
||||
const wasmBlobURL = await toBlobURL(wasmURL, 'application/wasm');
|
||||
console.log('WASM URL ready:', wasmBlobURL);
|
||||
showConsoleLogs && console.log('WASM URL ready:', wasmBlobURL);
|
||||
|
||||
console.log('Calling ffmpeg.load...');
|
||||
showConsoleLogs && console.log('Calling ffmpeg.load...');
|
||||
await ffmpeg.load({
|
||||
coreURL: coreBlobURL,
|
||||
wasmURL: wasmBlobURL,
|
||||
});
|
||||
console.log('FFmpeg loaded!');
|
||||
showConsoleLogs && console.log('FFmpeg loaded!');
|
||||
setExportProgress(20);
|
||||
|
||||
setExportStatus('Loading font...');
|
||||
await ffmpeg.writeFile('arial.ttf', await fetchFile('https://raw.githubusercontent.com/ffmpegwasm/testdata/master/arial.ttf'));
|
||||
console.log('Font loaded!');
|
||||
showConsoleLogs && console.log('Font loaded!');
|
||||
setExportProgress(30);
|
||||
|
||||
setExportStatus('Downloading videos...');
|
||||
|
||||
Reference in New Issue
Block a user