Init commit
This commit is contained in:
commit
a1334c60f3
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
. !text !filter !merge !diff
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
25
README.md
Normal file
25
README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
FFmpeg.js
|
||||||
|
=========
|
||||||
|
|
||||||
|
A FFmpeg WebAssembly version built from scratch, you can learn how to do it from this series of stories: [Build FFmpeg WebAssembly version (=ffmpeg.js)](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-1-preparation-ed12bf4c8fac).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm install @ffmpeg/ffmpeg
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const fs = require('fs');
|
||||||
|
const ffmpeg = require('@ffmpeg/ffmpeg');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await ffmpeg.load();
|
||||||
|
const data = ffmpeg.transcode('./test.avi', 'mp4');
|
||||||
|
fs.wrieFileSync('./test.mp4', data);
|
||||||
|
})();
|
||||||
|
```
|
10
examples/transcode.js
Executable file
10
examples/transcode.js
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const ffmpeg = require('../src');
|
||||||
|
const { argv } = process;
|
||||||
|
const [,, inputPath, outputPath] = argv;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await ffmpeg.load();
|
||||||
|
const data = ffmpeg.transcode(inputPath, outputPath.split('.').pop());
|
||||||
|
fs.writeFileSync(outputPath, data);
|
||||||
|
})();
|
13
package-lock.json
generated
Normal file
13
package-lock.json
generated
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "@ffmpeg/ffmpeg",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@ffmpeg/core": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-a4/HokRytKFJDW+RVvuf22rUzjNgXZKhlF6FIVBcLACIDcCEQZ0uCUC+5DZb+xprCvdMyXm0wy90uoYLRTq+LA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
package.json
Normal file
30
package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "@ffmpeg/ffmpeg",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "FFmpeg WebAssembly version",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"directories": {
|
||||||
|
"example": "examples"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/jeromewu/ffmpeg.js.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"ffmpeg",
|
||||||
|
"WebAssembly",
|
||||||
|
"video"
|
||||||
|
],
|
||||||
|
"author": "Jerome Wu <jeromewus@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/jeromewu/ffmpeg.js/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/jeromewu/ffmpeg.js#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"@ffmpeg/core": "^0.1.0"
|
||||||
|
}
|
||||||
|
}
|
6
src/constants/defaultArgs.js
Executable file
6
src/constants/defaultArgs.js
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = [
|
||||||
|
'./ffmpeg', // args[0] is always binary path
|
||||||
|
'-nostdin', // Disable interaction mode
|
||||||
|
'-loglevel',
|
||||||
|
'quiet',
|
||||||
|
];
|
7
src/index.js
Executable file
7
src/index.js
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
const load = require('./load');
|
||||||
|
const transcode = require('./transcode');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load,
|
||||||
|
transcode,
|
||||||
|
};
|
12
src/load.js
Executable file
12
src/load.js
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
const { setModule } = require('./util/module');
|
||||||
|
const FFmpegCore = require('@ffmpeg/core');
|
||||||
|
|
||||||
|
module.exports = () => (
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
FFmpegCore()
|
||||||
|
.then((Module) => {
|
||||||
|
setModule(Module);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
17
src/transcode.js
Executable file
17
src/transcode.js
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { getModule } = require('./util/module');
|
||||||
|
const getFFmpeg = require('./util/getFFmpeg');
|
||||||
|
const strList2ptr = require('./util/strList2ptr');
|
||||||
|
const defaultArgs = require('./constants/defaultArgs');
|
||||||
|
|
||||||
|
module.exports = (inputPath, outputExt, options='') => {
|
||||||
|
const Module = getModule();
|
||||||
|
const data = new Uint8Array(fs.readFileSync(inputPath));
|
||||||
|
const iPath = `file.${inputPath.split('.').pop()}`;
|
||||||
|
const oPath = `file.${outputExt}`;
|
||||||
|
const ffmpeg = getFFmpeg();
|
||||||
|
const args = [...defaultArgs, ...`${options} -i ${iPath} ${oPath}`.trim().split(' ')];
|
||||||
|
Module.FS.writeFile(iPath, data);
|
||||||
|
ffmpeg(args.length, strList2ptr(args));
|
||||||
|
return Buffer.from(Module.FS.readFile(oPath));
|
||||||
|
};
|
6
src/util/getFFmpeg.js
Executable file
6
src/util/getFFmpeg.js
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
const { getModule } = require('./module');
|
||||||
|
|
||||||
|
module.exports = () => {
|
||||||
|
const Module = getModule();
|
||||||
|
return Module.cwrap('ffmpeg', 'number', ['number', 'number']);
|
||||||
|
};
|
7
src/util/module.js
Executable file
7
src/util/module.js
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
let Module = null;
|
||||||
|
|
||||||
|
exports.setModule = m => {
|
||||||
|
Module = m;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.getModule = () => Module;
|
11
src/util/str2ptr.js
Executable file
11
src/util/str2ptr.js
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
const { getModule } = require('./module');
|
||||||
|
|
||||||
|
module.exports = (s) => {
|
||||||
|
const Module = getModule();
|
||||||
|
const ptr = Module._malloc((s.length+1)*Uint8Array.BYTES_PER_ELEMENT);
|
||||||
|
for (let i = 0; i < s.length; i++) {
|
||||||
|
Module.setValue(ptr+i, s.charCodeAt(i), 'i8');
|
||||||
|
}
|
||||||
|
Module.setValue(ptr+s.length, 0, 'i8');
|
||||||
|
return ptr;
|
||||||
|
};
|
14
src/util/strList2ptr.js
Executable file
14
src/util/strList2ptr.js
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
const { getModule } = require('./module');
|
||||||
|
const str2ptr = require('./str2ptr');
|
||||||
|
|
||||||
|
module.exports = (strList) => {
|
||||||
|
const Module = getModule();
|
||||||
|
const listPtr = Module._malloc(strList.length*Uint32Array.BYTES_PER_ELEMENT);
|
||||||
|
|
||||||
|
strList.forEach((s, idx) => {
|
||||||
|
const strPtr = str2ptr(s);
|
||||||
|
Module.setValue(listPtr + (4*idx), strPtr, 'i32');
|
||||||
|
});
|
||||||
|
|
||||||
|
return listPtr;
|
||||||
|
};
|
BIN
tests/assets/test.avi
Executable file
BIN
tests/assets/test.avi
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user