deploy: current vibn theia state
Made-with: Cursor
This commit is contained in:
56
dev-packages/ffmpeg/src/check-ffmpeg.ts
Normal file
56
dev-packages/ffmpeg/src/check-ffmpeg.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2019 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import * as ffmpeg from './ffmpeg';
|
||||
|
||||
export interface CheckFfmpegOptions extends ffmpeg.FfmpegOptions {
|
||||
json?: boolean
|
||||
}
|
||||
|
||||
export interface CheckFfmpegResult {
|
||||
free: ffmpeg.Codec[],
|
||||
proprietary: ffmpeg.Codec[],
|
||||
}
|
||||
|
||||
export const KNOWN_PROPRIETARY_CODECS = new Set(['h264', 'aac']);
|
||||
|
||||
export async function checkFfmpeg(options: CheckFfmpegOptions = {}): Promise<void> {
|
||||
const {
|
||||
ffmpegPath = ffmpeg.ffmpegAbsolutePath(options),
|
||||
json = false,
|
||||
} = options;
|
||||
const codecs = ffmpeg.getFfmpegCodecs(ffmpegPath);
|
||||
const free = [];
|
||||
const proprietary = [];
|
||||
for (const codec of codecs) {
|
||||
if (KNOWN_PROPRIETARY_CODECS.has(codec.name.toLowerCase())) {
|
||||
proprietary.push(codec);
|
||||
} else {
|
||||
free.push(codec);
|
||||
}
|
||||
}
|
||||
if (json) {
|
||||
// Pretty format JSON on stdout.
|
||||
const result: CheckFfmpegResult = { free, proprietary };
|
||||
console.log(JSON.stringify(result, undefined, 2));
|
||||
}
|
||||
if (proprietary.length > 0) {
|
||||
// Should be displayed on stderr to not pollute the JSON on stdout.
|
||||
throw new Error(`${proprietary.length} proprietary codecs found\n${proprietary.map(codec => `> ${codec.name} detected (${codec.longName})`).join('\n')}`);
|
||||
}
|
||||
// Print to stderr to not pollute the JSON on stdout.
|
||||
console.warn(`"${ffmpegPath}" does not contain proprietary codecs (${codecs.length} found).`);
|
||||
}
|
||||
114
dev-packages/ffmpeg/src/ffmpeg.ts
Normal file
114
dev-packages/ffmpeg/src/ffmpeg.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2019 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import path = require('path');
|
||||
|
||||
export interface Codec {
|
||||
id: number
|
||||
name: string
|
||||
longName: string
|
||||
}
|
||||
|
||||
export interface FfmpegNativeAddon {
|
||||
codecs(ffmpegPath: string): Codec[]
|
||||
}
|
||||
|
||||
export interface FfmpegNameAndLocation {
|
||||
/**
|
||||
* Name with extension of the shared library.
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* Relative location of the file from Electron's dist root.
|
||||
*/
|
||||
location: string
|
||||
}
|
||||
|
||||
export interface FfmpegOptions {
|
||||
electronVersion?: string
|
||||
electronDist?: string
|
||||
ffmpegPath?: string
|
||||
platform?: NodeJS.Platform
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function _loadFfmpegNativeAddon(): FfmpegNativeAddon {
|
||||
try {
|
||||
return require('../build/Release/ffmpeg.node');
|
||||
} catch (error) {
|
||||
if (error.code === 'MODULE_NOT_FOUND') {
|
||||
return require('../build/Debug/ffmpeg.node');
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns name and relative path from Electron's root where FFMPEG is located at.
|
||||
*/
|
||||
export function ffmpegNameAndLocation({
|
||||
platform = process.platform
|
||||
}: FfmpegOptions = {}): FfmpegNameAndLocation {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
return {
|
||||
name: 'libffmpeg.dylib',
|
||||
location: 'Electron.app/Contents/Frameworks/Electron Framework.framework/Libraries/',
|
||||
};
|
||||
case 'win32':
|
||||
return {
|
||||
name: 'ffmpeg.dll',
|
||||
location: '',
|
||||
};
|
||||
case 'linux':
|
||||
return {
|
||||
name: 'libffmpeg.so',
|
||||
location: '',
|
||||
};
|
||||
default:
|
||||
throw new Error(`${platform} is not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns relative ffmpeg shared library path from the Electron distribution root.
|
||||
*/
|
||||
export function ffmpegRelativePath(options: FfmpegOptions = {}): string {
|
||||
const { location, name } = ffmpegNameAndLocation(options);
|
||||
return path.join(location, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns absolute ffmpeg shared library path.
|
||||
*/
|
||||
export function ffmpegAbsolutePath(options: FfmpegOptions = {}): string {
|
||||
const {
|
||||
electronDist = path.resolve(require.resolve('electron/package.json'), '..', 'dist')
|
||||
} = options;
|
||||
return path.join(electronDist, ffmpegRelativePath(options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically link to `ffmpegPath` and use FFMPEG APIs to list the included `Codec`s.
|
||||
* @param ffmpegPath absolute path the the FFMPEG shared library.
|
||||
* @returns list of codecs for the given ffmpeg shared library.
|
||||
*/
|
||||
export function getFfmpegCodecs(ffmpegPath: string): Codec[] {
|
||||
return _loadFfmpegNativeAddon().codecs(ffmpegPath);
|
||||
}
|
||||
28
dev-packages/ffmpeg/src/hash.ts
Normal file
28
dev-packages/ffmpeg/src/hash.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import crypto = require('crypto');
|
||||
import fs = require('fs-extra');
|
||||
|
||||
export async function hashFile(filePath: string): Promise<Buffer> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const sha256 = crypto.createHash('sha256');
|
||||
fs.createReadStream(filePath)
|
||||
.on('close', () => resolve(sha256.digest()))
|
||||
.on('data', data => sha256.update(data))
|
||||
.on('error', reject);
|
||||
});
|
||||
}
|
||||
20
dev-packages/ffmpeg/src/index.ts
Normal file
20
dev-packages/ffmpeg/src/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2021 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
export * from './hash';
|
||||
export * from './ffmpeg';
|
||||
export * from './check-ffmpeg';
|
||||
export * from './replace-ffmpeg';
|
||||
80
dev-packages/ffmpeg/src/replace-ffmpeg.ts
Normal file
80
dev-packages/ffmpeg/src/replace-ffmpeg.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
// *****************************************************************************
|
||||
// Copyright (C) 2019 Ericsson and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// http://www.eclipse.org/legal/epl-2.0.
|
||||
//
|
||||
// This Source Code may also be made available under the following Secondary
|
||||
// Licenses when the conditions for such availability set forth in the Eclipse
|
||||
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
||||
// with the GNU Classpath Exception which is available at
|
||||
// https://www.gnu.org/software/classpath/license.html.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
||||
// *****************************************************************************
|
||||
|
||||
import electronGet = require('@electron/get');
|
||||
import fs = require('fs-extra');
|
||||
import os = require('os');
|
||||
import path = require('path');
|
||||
import unzipper = require('unzipper');
|
||||
import * as ffmpeg from './ffmpeg';
|
||||
import { hashFile } from './hash';
|
||||
|
||||
export async function replaceFfmpeg(options: ffmpeg.FfmpegOptions = {}): Promise<void> {
|
||||
let shouldDownload = true;
|
||||
let shouldReplace = true;
|
||||
const {
|
||||
name: ffmpegName,
|
||||
location: ffmpegLocation,
|
||||
} = ffmpeg.ffmpegNameAndLocation(options);
|
||||
const {
|
||||
electronDist = path.resolve(require.resolve('electron/package.json'), '..', 'dist'),
|
||||
electronVersion = await readElectronVersion(electronDist),
|
||||
ffmpegPath = path.resolve(electronDist, ffmpegLocation, ffmpegName),
|
||||
} = options;
|
||||
const ffmpegCachedPath = path.join(os.tmpdir(), `theia-cli/cache/electron-v${electronVersion}`, ffmpegName);
|
||||
if (await fs.pathExists(ffmpegCachedPath)) {
|
||||
shouldDownload = false; // If the file is already cached, do not download.
|
||||
console.warn('Found cached ffmpeg library.');
|
||||
const [cacheHash, distHash] = await Promise.all([
|
||||
hashFile(ffmpegCachedPath),
|
||||
hashFile(ffmpegPath),
|
||||
]);
|
||||
if (cacheHash.equals(distHash)) {
|
||||
shouldReplace = false; // If files are already the same, do not replace.
|
||||
console.warn('Hashes are equal, not replacing the ffmpeg library.');
|
||||
}
|
||||
}
|
||||
if (shouldDownload) {
|
||||
const ffmpegZipPath = await electronGet.downloadArtifact({
|
||||
version: electronVersion,
|
||||
artifactName: 'ffmpeg'
|
||||
});
|
||||
const ffmpegZip = await unzipper.Open.file(ffmpegZipPath);
|
||||
const file = ffmpegZip.files.find(f => f.path.endsWith(ffmpegName));
|
||||
if (!file) {
|
||||
throw new Error(`Archive did not contain "${ffmpegName}".`);
|
||||
}
|
||||
// Extract file to cache.
|
||||
await fs.mkdirp(path.dirname(ffmpegCachedPath));
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
file.stream()
|
||||
.pipe(fs.createWriteStream(ffmpegCachedPath))
|
||||
.on('finish', resolve)
|
||||
.on('error', reject);
|
||||
});
|
||||
console.warn(`Downloaded ffmpeg shared library { version: "${electronVersion}", dist: "${electronDist}" }.`);
|
||||
}
|
||||
if (shouldReplace) {
|
||||
await fs.copy(ffmpegCachedPath, ffmpegPath);
|
||||
console.warn(`Successfully replaced "${ffmpegPath}".`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function readElectronVersion(electronDist: string): Promise<string> {
|
||||
const electronVersionFilePath = path.resolve(electronDist, 'version');
|
||||
const version = await fs.readFile(electronVersionFilePath, 'utf8');
|
||||
return version.trim();
|
||||
}
|
||||
Reference in New Issue
Block a user