2020-01-21 21:48:04 +01:00
|
|
|
#!/usr/bin/env node
|
2023-05-09 15:10:24 +05:30
|
|
|
|
|
|
|
import { spawn } from 'child_process';
|
|
|
|
import path from 'path';
|
|
|
|
import process from 'process';
|
|
|
|
import { promisify } from 'util';
|
|
|
|
import stream from 'stream';
|
|
|
|
|
|
|
|
import got from 'got';
|
|
|
|
import { program as cli } from 'commander';
|
|
|
|
import yazl from 'yazl';
|
|
|
|
import fs from 'fs-extra';
|
|
|
|
|
2020-01-29 21:41:33 +01:00
|
|
|
const pipeline = promisify(stream.pipeline);
|
|
|
|
|
2023-05-09 15:10:24 +05:30
|
|
|
cli
|
2023-08-12 13:55:20 +02:00
|
|
|
.option('-a, --arch [arch]', 'Target architecture, ia32, x64, arm, arm64', 'x64')
|
2020-01-29 21:41:33 +01:00
|
|
|
.option('-v, --version [version]', 'Build FFmpeg for the specified NW.js version or Branch', false)
|
|
|
|
.option('-c, --clean', 'Clean the workspace, removes downloaded source code')
|
|
|
|
.option('-d, --download', 'Download Prebuild binaries.')
|
|
|
|
.option('--get-download-url', 'Get Download Url for Prebuild binaries.')
|
|
|
|
.option('-p, --platform [platform]', 'Download platform, darwin, win, linux', process.platform)
|
|
|
|
.option('-o, --out [out]', 'Output Directory', path.join(process.cwd(), 'build', 'out'));
|
2020-01-21 21:48:04 +01:00
|
|
|
|
2023-05-09 15:10:24 +05:30
|
|
|
cli.parse(process.argv);
|
|
|
|
let program = cli.opts();
|
|
|
|
|
2020-01-29 21:41:33 +01:00
|
|
|
const outDir = program.out;
|
2020-01-21 21:48:04 +01:00
|
|
|
|
|
|
|
function execAsync(code, ...a) {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
const proc = spawn(code, a, {
|
|
|
|
stdio: 'inherit',
|
|
|
|
shell: true,
|
|
|
|
env: {
|
2020-01-21 22:00:01 +01:00
|
|
|
...process.env,
|
|
|
|
Path: process.env.PATH
|
2020-01-29 21:41:33 +01:00
|
|
|
}
|
2020-01-21 21:48:04 +01:00
|
|
|
});
|
|
|
|
proc.addListener('exit', resolve);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-01-29 21:41:33 +01:00
|
|
|
async function setupLinux() {
|
|
|
|
await execAsync(`./build/install-build-deps.sh`, `--no-prompt`, `--no-nacl`, `--no-chromeos-fonts`, `--no-syms`);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function setupMac() {
|
|
|
|
}
|
|
|
|
|
|
|
|
async function setupWin() {
|
|
|
|
}
|
|
|
|
|
2020-01-21 21:48:04 +01:00
|
|
|
async function main() {
|
|
|
|
const pkg = await got('https://nwjs.io/versions.json').json();
|
|
|
|
const nwVersion = program.version || pkg['stable'];
|
2020-01-29 21:41:33 +01:00
|
|
|
const version = pkg.versions.find(e => e.version.includes(nwVersion));
|
|
|
|
if (!version) {
|
|
|
|
console.error(`NW.js version ${nwVersion} could not be found.`);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
2023-05-17 16:05:55 +02:00
|
|
|
const chromiumVersion = version['components']['chromium'];
|
2020-01-29 21:41:33 +01:00
|
|
|
let libName = null;
|
|
|
|
let zipName = null;
|
|
|
|
const platform = program.platform || process.platform;
|
|
|
|
if (platform === 'darwin') {
|
|
|
|
libName = 'libffmpeg.dylib';
|
|
|
|
zipName = `${version.version}-osx-${program.arch}.zip`.slice(1);
|
2020-02-09 21:17:37 +01:00
|
|
|
} else if (platform === 'win32' || platform === 'win') {
|
2020-01-29 21:41:33 +01:00
|
|
|
libName = 'ffmpeg.dll';
|
|
|
|
zipName = `${version.version}-win-${program.arch}.zip`.slice(1);
|
|
|
|
} else if (platform === 'linux') {
|
|
|
|
libName = 'libffmpeg.so';
|
|
|
|
zipName = `${version.version}-linux-${program.arch}.zip`.slice(1);
|
|
|
|
} else {
|
|
|
|
console.error('Platform not supported');
|
|
|
|
process.exit(1);
|
2020-01-21 21:48:04 +01:00
|
|
|
}
|
2020-01-29 21:41:33 +01:00
|
|
|
const downloadUrl = `https://github.com/iteufel/nwjs-ffmpeg-prebuilt/releases/download/${version.version.slice(1)}/${zipName}`;
|
|
|
|
if (program.getDownloadUrl) {
|
|
|
|
process.stdout.write(downloadUrl);
|
|
|
|
process.exit(0);
|
|
|
|
}
|
|
|
|
|
2020-01-21 21:48:04 +01:00
|
|
|
await fs.ensureDir(outDir);
|
2020-01-29 21:41:33 +01:00
|
|
|
if (program.download) {
|
|
|
|
console.log(`Downloading NW.js ${version.version} - FFmpeg - (Chromium ${chromiumVersion})`);
|
|
|
|
await pipeline(
|
|
|
|
got.stream(downloadUrl),
|
|
|
|
fs.createWriteStream(path.join(outDir, zipName))
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
console.log(`Building NW.js ${version.version} - FFmpeg - (Chromium ${chromiumVersion})`);
|
2020-01-21 21:48:04 +01:00
|
|
|
await fs.ensureDir('./build');
|
2020-01-29 21:41:33 +01:00
|
|
|
if (program.clean) {
|
|
|
|
console.log('Cleaning build Directory');
|
|
|
|
await fs.emptyDir('./build');
|
|
|
|
}
|
2020-01-21 21:48:04 +01:00
|
|
|
process.chdir('./build');
|
|
|
|
if (!(await fs.pathExists('./depot_tools'))) {
|
|
|
|
await execAsync('git', 'clone', 'https://chromium.googlesource.com/chromium/tools/depot_tools.git');
|
|
|
|
}
|
2020-02-09 21:17:37 +01:00
|
|
|
if (platform === 'win32' || platform === 'win') {
|
2020-01-21 21:48:04 +01:00
|
|
|
process.env.DEPOT_TOOLS_WIN_TOOLCHAIN = '0';
|
|
|
|
process.env.PATH = `${process.env.PATH};${path.resolve('./depot_tools')}`;
|
2020-01-29 21:41:33 +01:00
|
|
|
} else {
|
2020-01-21 21:48:04 +01:00
|
|
|
process.env.PATH = `${process.env.PATH}:${path.resolve('./depot_tools')}`;
|
|
|
|
}
|
|
|
|
await fs.ensureDir('./chromium');
|
|
|
|
process.chdir('./chromium');
|
|
|
|
const hasSrc = await fs.pathExists('./src');
|
|
|
|
console.log(`Clone chromium.src`);
|
|
|
|
if (!hasSrc) {
|
|
|
|
const gclient = `
|
|
|
|
solutions = [
|
|
|
|
{ "name" : 'src',
|
|
|
|
"url" : 'https://chromium.googlesource.com/chromium/src.git',
|
|
|
|
"deps_file" : 'DEPS',
|
|
|
|
"managed" : False,
|
|
|
|
"custom_deps" : {
|
|
|
|
|
|
|
|
},
|
|
|
|
"custom_vars": {},
|
|
|
|
},
|
|
|
|
]
|
2020-01-29 21:56:57 +01:00
|
|
|
${platform === 'arm' ? 'target_cpu=["arm"]' : ''}
|
2020-01-29 21:41:33 +01:00
|
|
|
`.trim();
|
2020-01-21 21:48:04 +01:00
|
|
|
await fs.writeFile('.gclient', gclient);
|
|
|
|
await execAsync('git', 'clone', 'https://chromium.googlesource.com/chromium/src.git', '--branch', chromiumVersion, '--single-branch', '--depth', 1);
|
|
|
|
}
|
|
|
|
process.chdir('./src');
|
2020-01-29 21:41:33 +01:00
|
|
|
if (hasSrc) {
|
2020-01-21 21:48:04 +01:00
|
|
|
await execAsync('git', 'fetch', 'https://chromium.googlesource.com/chromium/src.git', `+refs/tags/${chromiumVersion}`, '--depth', 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
await execAsync('git', 'reset', '--hard', `tags/${chromiumVersion}`);
|
|
|
|
|
|
|
|
if (process.platform === 'linux') {
|
2020-01-29 21:56:57 +01:00
|
|
|
await setupLinux(program.arch === 'arm');
|
2020-01-29 21:41:33 +01:00
|
|
|
} else if (process.platform === 'darwin') {
|
|
|
|
await setupMac();
|
2020-02-09 21:17:37 +01:00
|
|
|
} else if (platform === 'win32' || platform === 'win') {
|
2020-01-29 21:41:33 +01:00
|
|
|
await setupWin();
|
2020-01-21 21:48:04 +01:00
|
|
|
}
|
2020-01-29 21:41:33 +01:00
|
|
|
|
2020-01-21 21:48:04 +01:00
|
|
|
await execAsync('gclient', 'sync', '--with_branch_heads');
|
|
|
|
if (program.arch === 'ia32') {
|
2020-12-15 17:43:48 +01:00
|
|
|
await execAsync('gn', 'gen', 'out/Default', '--args="chrome_pgo_phase=0 is_debug=false enable_nacl=false is_component_ffmpeg=true proprietary_codecs=true is_official_build=true target_cpu=\\"x86\\" ffmpeg_branding=\\"Chrome\\""');
|
2020-01-29 21:56:57 +01:00
|
|
|
} else if (program.arch === 'x64') {
|
2020-12-15 17:43:48 +01:00
|
|
|
await execAsync('gn', 'gen', 'out/Default', '--args="chrome_pgo_phase=0 is_debug=false enable_nacl=false is_component_ffmpeg=true proprietary_codecs=true is_official_build=true target_cpu=\\"x64\\" ffmpeg_branding=\\"Chrome\\""');
|
2020-07-09 22:19:32 +02:00
|
|
|
} else if (program.arch === 'arm') {
|
2020-12-15 17:43:48 +01:00
|
|
|
await execAsync('gn', 'gen', 'out/Default', '--args="chrome_pgo_phase=0 is_debug=false enable_nacl=false is_component_ffmpeg=true proprietary_codecs=true is_official_build=true target_cpu=\\"arm\\" ffmpeg_branding=\\"Chrome\\""');
|
2021-04-27 12:37:48 +02:00
|
|
|
} else if (program.arch === 'arm64') {
|
|
|
|
await execAsync('gn', 'gen', 'out/Default', '--args="chrome_pgo_phase=0 is_debug=false enable_nacl=false is_component_ffmpeg=true proprietary_codecs=true is_official_build=true target_cpu=\\"arm64\\" ffmpeg_branding=\\"Chrome\\""');
|
2020-01-21 21:48:04 +01:00
|
|
|
}
|
2020-01-29 21:41:33 +01:00
|
|
|
await execAsync('autoninja', '-C', 'out/Default', libName);
|
|
|
|
const zipFile = new yazl.ZipFile();
|
|
|
|
zipFile.addFile(`out/Default/${libName}`, libName);
|
|
|
|
|
|
|
|
zipFile.outputStream.pipe(fs.createWriteStream(path.resolve(outDir, zipName))).on("close", () => {
|
2020-01-21 21:48:04 +01:00
|
|
|
console.log(zipName);
|
|
|
|
});
|
2020-01-29 21:41:33 +01:00
|
|
|
zipFile.end();
|
2020-01-21 21:48:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
main().catch((e) => {
|
|
|
|
console.error(e);
|
2020-01-29 21:41:33 +01:00
|
|
|
process.exit(1);
|
|
|
|
});
|