Skip to content

Instantly share code, notes, and snippets.

@ammoradi
Last active July 23, 2022 21:22
Show Gist options
  • Save ammoradi/54795d3f14b93b88c91d863708e994be to your computer and use it in GitHub Desktop.
Save ammoradi/54795d3f14b93b88c91d863708e994be to your computer and use it in GitHub Desktop.
usage of @ffmpeg/ffmpeg to transcode and trim videos in react project

VIDEO CONVERTER

SEE CONSOLE DURING COMPILE

import React, { useState, useCallback } from 'react';
import './App.css';
import transformer from './transformer'
function App() {
const [videoSrc, setVideoSrc] = useState('');
const handleTranscode = useCallback(async ({ target: { files } }) => {
// you can use range slider
const url = await transformer(files[0], '00:01:30', 30, 'test.mp4')
setVideoSrc(url);
}, [])
return (
<div className="App">
<p/>
<video src={videoSrc} controls></video><br/>
<input type="file" onChange={handleTranscode} />
</div>
);
}
export default App;
// yarn add @ffmpeg/ffmpeg
import { createFFmpeg } from '@ffmpeg/ffmpeg';
const ffmpeg = createFFmpeg({
log: true,
});
const defaultOutputFileName = 'output.webm'
/**
@param input {string} - inputFileName.format
@param end {string} - end timestamp - hh:mm:ss
@param duration {string|number} - trim duration in seconds
@param output {string} - outputtFileName.format
*/
const getMp4Command = (input, end, duration, output) => `-t ${end} -i ${input} -ss ${duration} ${output}`
//@todo should fork @ffmpeg/ffmpeg and update its ffmpeg to fix getWebmCommand.
const getWebmCommand = (input, end, duration, output) =>
`-t ${end} -i ${input} -ss ${duration} -c:v libvpx -crf 10 -b:v 300K -c:a libvorbis ${output}`
/**
@param inputFile {object} - event target file - eg: event.target.files[0] from <input type="video" />
@param end {string} - end timestamp - hh:mm:ss
@param duration {string|number} - trim duration in seconds
@param outputFileName {string} - outputtFileName.format
*/
const transformer = async (inputFile, end, duration, outputFileName = defaultOutputFileName) => {
const { name } = inputFile;
// it will download ~25Mb
await ffmpeg.load();
await ffmpeg.write(name, inputFile);
await ffmpeg.run(getMp4Command(name, end, duration, outputFileName));
// get output
const output = ffmpeg.read(outputFileName);
// it will returns a proper url for <video /> tag's src attribute. you can change it to anything you want
return URL.createObjectURL(new Blob([output.buffer], { type: 'video/mp4' }))
}
export default transformer
@thecherrie
Copy link

@ammoradi thanks for sharing this. I was getting a similar error:

getCreateFFmpegCore.js?5d16:43 Uncaught ReferenceError: createFFmpegCore is not defined
    at HTMLScriptElement.eventHandler (getCreateFFmpegCore.js?5d16:43:1)

Fixed it via this thread -> ffmpegwasm/ffmpeg.wasm#262

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment