Add image2video example
@ -3,7 +3,8 @@
|
|||||||
"rules": {
|
"rules": {
|
||||||
"no-underscore-dangle": 0,
|
"no-underscore-dangle": 0,
|
||||||
"linebreak-style": 0,
|
"linebreak-style": 0,
|
||||||
"global-require": 0
|
"global-require": 0,
|
||||||
|
"no-await-in-loop": 0,
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
|
51
examples/browser/image2video.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="/dist/ffmpeg.dev.js"></script>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>Click start to transcode images to mp4 (x264) and play!</h3>
|
||||||
|
<video id="output-video" controls></video><br/>
|
||||||
|
<button id="start-btn">Start</button>
|
||||||
|
<p id="message"></p>
|
||||||
|
<a href="https://github.com/ffmpegjs/ffmpeg.js/tree/master/tests/assets/triangle">Data Set</a>
|
||||||
|
<script>
|
||||||
|
const { createWorker } = FFmpeg;
|
||||||
|
const worker = createWorker({
|
||||||
|
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
|
||||||
|
progress: (p) => console.log(p),
|
||||||
|
});
|
||||||
|
|
||||||
|
const image2video = async () => {
|
||||||
|
const message = document.getElementById('message');
|
||||||
|
message.innerHTML = 'Loading ffmpeg-core.js';
|
||||||
|
await worker.load();
|
||||||
|
message.innerHTML = 'Loading data';
|
||||||
|
await worker.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
|
||||||
|
for (let i = 0; i < 60; i += 1) {
|
||||||
|
const num = `00${i}`.slice(-3);
|
||||||
|
await worker.write(`tmp.${num}.png`, `../../tests/assets/triangle/tmp.${num}.png`);
|
||||||
|
}
|
||||||
|
message.innerHTML = 'Start transcoding';
|
||||||
|
await worker.run('-framerate 30 -pattern_type glob -i *.png -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4');
|
||||||
|
const { data } = await worker.read('out.mp4');
|
||||||
|
|
||||||
|
const video = document.getElementById('output-video');
|
||||||
|
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||||
|
}
|
||||||
|
const elm = document.getElementById('start-btn');
|
||||||
|
elm.addEventListener('click', image2video);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
23
examples/node/image2video.js
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { createWorker } = require('../../src');
|
||||||
|
|
||||||
|
const worker = createWorker({
|
||||||
|
progress: (p) => console.log(p),
|
||||||
|
});
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
console.log('Loading ffmpeg-core.js');
|
||||||
|
await worker.load();
|
||||||
|
console.log('Loading data');
|
||||||
|
await worker.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
|
||||||
|
for (let i = 0; i < 60; i += 1) {
|
||||||
|
const num = `00${i}`.slice(-3);
|
||||||
|
await worker.write(`tmp.${num}.png`, `../../tests/assets/triangle/tmp.${num}.png`);
|
||||||
|
}
|
||||||
|
console.log('Start transcoding');
|
||||||
|
await worker.run('-framerate 30 -pattern_type glob -i *.png -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4');
|
||||||
|
const { data } = await worker.read('out.mp4');
|
||||||
|
console.log('Complete transcoding');
|
||||||
|
fs.writeFileSync('out.mp4', Buffer.from(data));
|
||||||
|
process.exit(0);
|
||||||
|
})();
|
@ -8,7 +8,10 @@ const ts2sec = (ts) => {
|
|||||||
module.exports = ({ message }, progress) => {
|
module.exports = ({ message }, progress) => {
|
||||||
if (message.startsWith(' Duration')) {
|
if (message.startsWith(' Duration')) {
|
||||||
const ts = message.split(', ')[0].split(': ')[1];
|
const ts = message.split(', ')[0].split(': ')[1];
|
||||||
duration = ts2sec(ts);
|
const d = ts2sec(ts);
|
||||||
|
if (duration === 0 || duration > d) {
|
||||||
|
duration = d;
|
||||||
|
}
|
||||||
} else if (message.startsWith('frame')) {
|
} else if (message.startsWith('frame')) {
|
||||||
const ts = message.split('time=')[1].split(' ')[0];
|
const ts = message.split('time=')[1].split(' ')[0];
|
||||||
const t = ts2sec(ts);
|
const t = ts2sec(ts);
|
||||||
|
BIN
tests/assets/triangle/audio.ogg
Normal file
BIN
tests/assets/triangle/tmp.000.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
tests/assets/triangle/tmp.001.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
tests/assets/triangle/tmp.002.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
tests/assets/triangle/tmp.003.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
tests/assets/triangle/tmp.004.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.005.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
tests/assets/triangle/tmp.006.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
tests/assets/triangle/tmp.007.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.008.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.009.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.010.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.011.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.012.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
tests/assets/triangle/tmp.013.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
tests/assets/triangle/tmp.014.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.015.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.016.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.017.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.018.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.019.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
tests/assets/triangle/tmp.020.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
tests/assets/triangle/tmp.021.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.022.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
tests/assets/triangle/tmp.023.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.024.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
tests/assets/triangle/tmp.025.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
tests/assets/triangle/tmp.026.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
tests/assets/triangle/tmp.027.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
tests/assets/triangle/tmp.028.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
tests/assets/triangle/tmp.029.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.030.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
tests/assets/triangle/tmp.031.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.032.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
tests/assets/triangle/tmp.033.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
tests/assets/triangle/tmp.034.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.035.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
tests/assets/triangle/tmp.036.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
tests/assets/triangle/tmp.037.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
tests/assets/triangle/tmp.038.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
tests/assets/triangle/tmp.039.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
tests/assets/triangle/tmp.040.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
tests/assets/triangle/tmp.041.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
tests/assets/triangle/tmp.042.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
tests/assets/triangle/tmp.043.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
tests/assets/triangle/tmp.044.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
tests/assets/triangle/tmp.045.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
tests/assets/triangle/tmp.046.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
tests/assets/triangle/tmp.047.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
tests/assets/triangle/tmp.048.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.049.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
tests/assets/triangle/tmp.050.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
tests/assets/triangle/tmp.051.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.052.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/assets/triangle/tmp.053.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
tests/assets/triangle/tmp.054.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
tests/assets/triangle/tmp.055.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
tests/assets/triangle/tmp.056.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
tests/assets/triangle/tmp.057.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
tests/assets/triangle/tmp.058.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
tests/assets/triangle/tmp.059.png
Normal file
After Width: | Height: | Size: 33 KiB |