@theia/ffmpeg 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +642 -0
- package/README.md +3 -0
- package/lib/check-ffmpeg.d.ts +26 -0
- package/lib/check-ffmpeg.d.ts.map +1 -0
- package/lib/check-ffmpeg.js +47 -0
- package/lib/check-ffmpeg.js.map +1 -0
- package/lib/ffmpeg.d.ts +61 -0
- package/lib/ffmpeg.d.ts.map +1 -0
- package/lib/ffmpeg.js +83 -0
- package/lib/ffmpeg.js.map +1 -0
- package/lib/hash.d.ts +18 -0
- package/lib/hash.d.ts.map +1 -0
- package/lib/hash.js +31 -0
- package/lib/hash.js.map +1 -0
- package/lib/index.d.ts +20 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +32 -0
- package/lib/index.js.map +1 -0
- package/lib/replace-ffmpeg.d.ts +19 -0
- package/lib/replace-ffmpeg.d.ts.map +1 -0
- package/lib/replace-ffmpeg.js +76 -0
- package/lib/replace-ffmpeg.js.map +1 -0
- package/native/ffmpeg.c +146 -0
- package/native/ffmpeg.h +80 -0
- package/native/linux-ffmpeg.c +68 -0
- package/native/mac-ffmpeg.c +26 -0
- package/native/win-ffmpeg.c +77 -0
- package/package.json +37 -0
- package/src/check-ffmpeg.ts +56 -0
- package/src/ffmpeg.ts +111 -0
- package/src/hash.ts +28 -0
- package/src/index.ts +20 -0
- package/src/replace-ffmpeg.ts +80 -0
package/native/ffmpeg.h
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#ifndef FFMPEG_H
|
|
2
|
+
#define FFMPEG_H
|
|
3
|
+
/**
|
|
4
|
+
* THIS FILE REDEFINES DATA AS RETURNED BY THE FFMPEG LIBRARY.
|
|
5
|
+
* HEADER FILES ARE NOT DISTRIBUTED IN OUR SETUP, HENCE THIS.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* https://github.com/FFmpeg/FFmpeg/blob/release/3.2/libavutil/avutil.h#L193-L201
|
|
10
|
+
*/
|
|
11
|
+
enum AVMediaType
|
|
12
|
+
{
|
|
13
|
+
_UNKNOWN_DATA_AVMediaType = -1,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* https://github.com/FFmpeg/FFmpeg/blob/release/3.2/libavcodec/avcodec.h#L191-L653
|
|
18
|
+
*/
|
|
19
|
+
enum AVCodecID
|
|
20
|
+
{
|
|
21
|
+
__UNKNOWN_DATA_AVCodecID = 0,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* https://github.com/FFmpeg/FFmpeg/blob/release/3.2/libavcodec/avcodec.h#L3611-L3721
|
|
26
|
+
*/
|
|
27
|
+
struct AVCodec
|
|
28
|
+
{
|
|
29
|
+
const char *name, *long_name;
|
|
30
|
+
enum AVMediaType type;
|
|
31
|
+
enum AVCodecID id;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* https://github.com/FFmpeg/FFmpeg/blob/release/3.2/libavcodec/avcodec.h#L660-L688
|
|
36
|
+
*/
|
|
37
|
+
struct AVCodecDescriptor
|
|
38
|
+
{
|
|
39
|
+
enum AVCodecID id;
|
|
40
|
+
enum AVMediaType type;
|
|
41
|
+
const char *name, *long_name;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Wrapper around the ffmpeg library that must be loaded at runtime.
|
|
46
|
+
*/
|
|
47
|
+
struct FFMPEG_Library
|
|
48
|
+
{
|
|
49
|
+
void *handle;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* https://github.com/FFmpeg/FFmpeg/blob/release/3.2/libavcodec/avcodec.h#L6228
|
|
53
|
+
*
|
|
54
|
+
* We use AVCodecDescriptor because it is the only structure that we can
|
|
55
|
+
* query on all platforms. Windows' ffmpeg.dll does not export a
|
|
56
|
+
* `av_codec_next` function, only `avcodec_descriptor_next`.
|
|
57
|
+
* Also it seems that this "descriptor" concept is the recommended API.
|
|
58
|
+
*/
|
|
59
|
+
struct AVCodecDescriptor *(*avcodec_descriptor_next)(const struct AVCodecDescriptor *);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* https://github.com/FFmpeg/FFmpeg/blob/release/3.2/libavcodec/avcodec.h#L4646
|
|
63
|
+
*/
|
|
64
|
+
struct AVCodec *(*avcodec_find_decoder)(enum AVCodecID);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
#define NULL_FFMPEG_LIBRARY \
|
|
68
|
+
(struct FFMPEG_Library) { NULL, NULL, NULL }
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Loader that will inject the loaded functions into a FFMPEG_Library structure.
|
|
72
|
+
*/
|
|
73
|
+
char *load_ffmpeg_library(struct FFMPEG_Library *library, char *library_path);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Free library.
|
|
77
|
+
*/
|
|
78
|
+
char *unload_ffmpeg_library(struct FFMPEG_Library *library);
|
|
79
|
+
|
|
80
|
+
#endif // FFMPEG_H guard
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2019 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
#ifndef LINUX_FFMPEG
|
|
18
|
+
#define LINUX_FFMPEG
|
|
19
|
+
|
|
20
|
+
#include <stdlib.h>
|
|
21
|
+
#include <dlfcn.h>
|
|
22
|
+
|
|
23
|
+
#include "ffmpeg.h"
|
|
24
|
+
|
|
25
|
+
char *load_ffmpeg_library(struct FFMPEG_Library *library, char *library_path)
|
|
26
|
+
{
|
|
27
|
+
void *handle = dlopen(library_path, RTLD_NOW);
|
|
28
|
+
char *error = dlerror();
|
|
29
|
+
if (error != NULL)
|
|
30
|
+
{
|
|
31
|
+
goto error;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
struct AVCodecDescriptor *(*avcodec_descriptor_next)(const struct AVCodecDescriptor *) = dlsym(handle, "avcodec_descriptor_next");
|
|
35
|
+
error = dlerror();
|
|
36
|
+
if (error != NULL)
|
|
37
|
+
{
|
|
38
|
+
goto error;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
struct AVCodec *(*avcodec_find_decoder)(enum AVCodecID) = dlsym(handle, "avcodec_find_decoder");
|
|
42
|
+
error = dlerror();
|
|
43
|
+
if (error != NULL)
|
|
44
|
+
{
|
|
45
|
+
goto error;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
library->handle = handle;
|
|
49
|
+
library->avcodec_descriptor_next = avcodec_descriptor_next;
|
|
50
|
+
library->avcodec_find_decoder = avcodec_find_decoder;
|
|
51
|
+
return NULL;
|
|
52
|
+
|
|
53
|
+
error:
|
|
54
|
+
if (handle != NULL)
|
|
55
|
+
{
|
|
56
|
+
dlclose(handle);
|
|
57
|
+
}
|
|
58
|
+
return error;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
char *unload_ffmpeg_library(struct FFMPEG_Library *library)
|
|
62
|
+
{
|
|
63
|
+
dlclose(library->handle);
|
|
64
|
+
*library = NULL_FFMPEG_LIBRARY;
|
|
65
|
+
return dlerror();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#endif // LINUX_FFMPEG guard
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2019 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
#ifndef MAC_FFMPEG
|
|
18
|
+
#define MAC_FFMPEG
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Mac seems to use the same libraries as Linux.
|
|
22
|
+
* Difference is that the compiler doesn't need to be told to use `-ldl`.
|
|
23
|
+
*/
|
|
24
|
+
#include "./linux-ffmpeg.c"
|
|
25
|
+
|
|
26
|
+
#endif // MAC_FFMPEG guard
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2019 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
#ifndef WIN_FFMPEG
|
|
17
|
+
#define WIN_FFMPEG
|
|
18
|
+
|
|
19
|
+
#include <windows.h>
|
|
20
|
+
|
|
21
|
+
#include "ffmpeg.h"
|
|
22
|
+
|
|
23
|
+
static char *error_library_not_found = "shared library not found";
|
|
24
|
+
static char *error_function_not_found = "function not found in shared library";
|
|
25
|
+
static char *error_cannot_free_library = "cannot free shared library";
|
|
26
|
+
|
|
27
|
+
char *load_ffmpeg_library(struct FFMPEG_Library *library, char *library_path)
|
|
28
|
+
{
|
|
29
|
+
char *error = NULL;
|
|
30
|
+
|
|
31
|
+
HMODULE handle = LoadLibrary(library_path);
|
|
32
|
+
if (!handle)
|
|
33
|
+
{
|
|
34
|
+
error = error_library_not_found;
|
|
35
|
+
goto error;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
struct AVCodecDescriptor *(*av_codec_next)(const struct AVCodecDescriptor *) = (struct AVCodecDescriptor * (*)(const struct AVCodecDescriptor *))
|
|
39
|
+
GetProcAddress(handle, "avcodec_descriptor_next");
|
|
40
|
+
if (!av_codec_next)
|
|
41
|
+
{
|
|
42
|
+
error = error_function_not_found;
|
|
43
|
+
goto error;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
struct AVCodec *(*avcodec_find_decoder)(enum AVCodecID) = (struct AVCodec * (*)(enum AVCodecID))
|
|
47
|
+
GetProcAddress(handle, "avcodec_find_decoder");
|
|
48
|
+
if (!avcodec_find_decoder)
|
|
49
|
+
{
|
|
50
|
+
error = error_function_not_found;
|
|
51
|
+
goto error;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
library->handle = handle;
|
|
55
|
+
library->avcodec_descriptor_next = av_codec_next;
|
|
56
|
+
library->avcodec_find_decoder = avcodec_find_decoder;
|
|
57
|
+
return NULL;
|
|
58
|
+
|
|
59
|
+
error:
|
|
60
|
+
if (handle)
|
|
61
|
+
{
|
|
62
|
+
FreeLibrary(handle);
|
|
63
|
+
}
|
|
64
|
+
return error;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
char *unload_ffmpeg_library(struct FFMPEG_Library *library)
|
|
68
|
+
{
|
|
69
|
+
if (library->handle && FreeLibrary(library->handle))
|
|
70
|
+
{
|
|
71
|
+
*library = NULL_FFMPEG_LIBRARY;
|
|
72
|
+
return NULL;
|
|
73
|
+
}
|
|
74
|
+
return error_cannot_free_library;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#endif // WIN_FFMPEG guard
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@theia/ffmpeg",
|
|
3
|
+
"version": "1.22.0",
|
|
4
|
+
"description": "Theia FFMPEG reader utility.",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"license": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/eclipse-theia/theia.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/eclipse-theia/theia/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/eclipse-theia/theia",
|
|
17
|
+
"main": "lib/index.js",
|
|
18
|
+
"files": [
|
|
19
|
+
"lib",
|
|
20
|
+
"native",
|
|
21
|
+
"src"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"lint": "theiaext lint",
|
|
25
|
+
"build": "theiaext build",
|
|
26
|
+
"watch": "theiaext watch",
|
|
27
|
+
"clean": "theiaext clean"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@electron/get": "^1.12.4",
|
|
31
|
+
"unzipper": "^0.9.11"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/unzipper": "^0.9.2"
|
|
35
|
+
},
|
|
36
|
+
"gitHead": "84cfe06b4b10720cc9915bc6e2f091a2b09b1087"
|
|
37
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2019 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import * as ffmpeg from './ffmpeg';
|
|
18
|
+
|
|
19
|
+
export interface CheckFfmpegOptions extends ffmpeg.FfmpegOptions {
|
|
20
|
+
json?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CheckFfmpegResult {
|
|
24
|
+
free: ffmpeg.Codec[],
|
|
25
|
+
proprietary: ffmpeg.Codec[],
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const KNOWN_PROPRIETARY_CODECS = new Set(['h264', 'aac']);
|
|
29
|
+
|
|
30
|
+
export async function checkFfmpeg(options: CheckFfmpegOptions = {}): Promise<void> {
|
|
31
|
+
const {
|
|
32
|
+
ffmpegPath = ffmpeg.ffmpegAbsolutePath(options),
|
|
33
|
+
json = false,
|
|
34
|
+
} = options;
|
|
35
|
+
const codecs = ffmpeg.getFfmpegCodecs(ffmpegPath);
|
|
36
|
+
const free = [];
|
|
37
|
+
const proprietary = [];
|
|
38
|
+
for (const codec of codecs) {
|
|
39
|
+
if (KNOWN_PROPRIETARY_CODECS.has(codec.name.toLowerCase())) {
|
|
40
|
+
proprietary.push(codec);
|
|
41
|
+
} else {
|
|
42
|
+
free.push(codec);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (json) {
|
|
46
|
+
// Pretty format JSON on stdout.
|
|
47
|
+
const result: CheckFfmpegResult = { free, proprietary };
|
|
48
|
+
console.log(JSON.stringify(result, undefined, 2));
|
|
49
|
+
}
|
|
50
|
+
if (proprietary.length > 0) {
|
|
51
|
+
// Should be displayed on stderr to not pollute the JSON on stdout.
|
|
52
|
+
throw new Error(`${proprietary.length} proprietary codecs found\n${proprietary.map(codec => `> ${codec.name} detected (${codec.longName})`).join('\n')}`);
|
|
53
|
+
}
|
|
54
|
+
// Print to stderr to not pollute the JSON on stdout.
|
|
55
|
+
console.warn(`"${ffmpegPath}" does not contain proprietary codecs (${codecs.length} found).`);
|
|
56
|
+
}
|
package/src/ffmpeg.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2019 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import path = require('path');
|
|
18
|
+
|
|
19
|
+
export interface Codec {
|
|
20
|
+
id: number
|
|
21
|
+
name: string
|
|
22
|
+
longName: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface FfmpegNativeAddon {
|
|
26
|
+
codecs(ffmpegPath: string): Codec[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let _FFMPEG: FfmpegNativeAddon;
|
|
30
|
+
try {
|
|
31
|
+
_FFMPEG = require('../build/Release/ffmpeg.node');
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error.code === 'MODULE_NOT_FOUND') {
|
|
34
|
+
_FFMPEG = require('../build/Debug/ffmpeg.node');
|
|
35
|
+
} else {
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export { _FFMPEG };
|
|
40
|
+
|
|
41
|
+
export interface FfmpegNameAndLocation {
|
|
42
|
+
/**
|
|
43
|
+
* Name with extension of the shared library.
|
|
44
|
+
*/
|
|
45
|
+
name: string
|
|
46
|
+
/**
|
|
47
|
+
* Relative location of the file from Electron's dist root.
|
|
48
|
+
*/
|
|
49
|
+
location: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface FfmpegOptions {
|
|
53
|
+
electronVersion?: string
|
|
54
|
+
electronDist?: string
|
|
55
|
+
ffmpegPath?: string
|
|
56
|
+
platform?: NodeJS.Platform
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @returns name and relative path from Electron's root where FFMPEG is located at.
|
|
61
|
+
*/
|
|
62
|
+
export function ffmpegNameAndLocation({
|
|
63
|
+
platform = process.platform
|
|
64
|
+
}: FfmpegOptions = {}): FfmpegNameAndLocation {
|
|
65
|
+
switch (platform) {
|
|
66
|
+
case 'darwin':
|
|
67
|
+
return {
|
|
68
|
+
name: 'libffmpeg.dylib',
|
|
69
|
+
location: 'Electron.app/Contents/Frameworks/Electron Framework.framework/Libraries/',
|
|
70
|
+
};
|
|
71
|
+
case 'win32':
|
|
72
|
+
return {
|
|
73
|
+
name: 'ffmpeg.dll',
|
|
74
|
+
location: '',
|
|
75
|
+
};
|
|
76
|
+
case 'linux':
|
|
77
|
+
return {
|
|
78
|
+
name: 'libffmpeg.so',
|
|
79
|
+
location: '',
|
|
80
|
+
};
|
|
81
|
+
default:
|
|
82
|
+
throw new Error(`${platform} is not supported`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @returns relative ffmpeg shared library path from the Electron distribution root.
|
|
88
|
+
*/
|
|
89
|
+
export function ffmpegRelativePath(options: FfmpegOptions = {}): string {
|
|
90
|
+
const { location, name } = ffmpegNameAndLocation(options);
|
|
91
|
+
return path.join(location, name);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @returns absolute ffmpeg shared library path.
|
|
96
|
+
*/
|
|
97
|
+
export function ffmpegAbsolutePath(options: FfmpegOptions = {}): string {
|
|
98
|
+
const {
|
|
99
|
+
electronDist = path.resolve(require.resolve('electron/package.json'), '..', 'dist')
|
|
100
|
+
} = options;
|
|
101
|
+
return path.join(electronDist, ffmpegRelativePath(options));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Dynamically link to `ffmpegPath` and use FFMPEG APIs to list the included `Codec`s.
|
|
106
|
+
* @param ffmpegPath absolute path the the FFMPEG shared library.
|
|
107
|
+
* @returns list of codecs for the given ffmpeg shared library.
|
|
108
|
+
*/
|
|
109
|
+
export function getFfmpegCodecs(ffmpegPath: string): Codec[] {
|
|
110
|
+
return _FFMPEG.codecs(ffmpegPath);
|
|
111
|
+
}
|
package/src/hash.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2021 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import crypto = require('crypto');
|
|
18
|
+
import fs = require('fs-extra');
|
|
19
|
+
|
|
20
|
+
export async function hashFile(filePath: string): Promise<Buffer> {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const sha256 = crypto.createHash('sha256');
|
|
23
|
+
fs.createReadStream(filePath)
|
|
24
|
+
.on('close', () => resolve(sha256.digest()))
|
|
25
|
+
.on('data', data => sha256.update(data))
|
|
26
|
+
.on('error', reject);
|
|
27
|
+
});
|
|
28
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2021 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
export * from './hash';
|
|
18
|
+
export * from './ffmpeg';
|
|
19
|
+
export * from './check-ffmpeg';
|
|
20
|
+
export * from './replace-ffmpeg';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2019 Ericsson and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import electronGet = require('@electron/get');
|
|
18
|
+
import fs = require('fs-extra');
|
|
19
|
+
import os = require('os');
|
|
20
|
+
import path = require('path');
|
|
21
|
+
import unzipper = require('unzipper');
|
|
22
|
+
import * as ffmpeg from './ffmpeg';
|
|
23
|
+
import { hashFile } from './hash';
|
|
24
|
+
|
|
25
|
+
export async function replaceFfmpeg(options: ffmpeg.FfmpegOptions = {}): Promise<void> {
|
|
26
|
+
let shouldDownload = true;
|
|
27
|
+
let shouldReplace = true;
|
|
28
|
+
const {
|
|
29
|
+
name: ffmpegName,
|
|
30
|
+
location: ffmpegLocation,
|
|
31
|
+
} = ffmpeg.ffmpegNameAndLocation(options);
|
|
32
|
+
const {
|
|
33
|
+
electronDist = path.resolve(require.resolve('electron/package.json'), '..', 'dist'),
|
|
34
|
+
electronVersion = await readElectronVersion(electronDist),
|
|
35
|
+
ffmpegPath = path.resolve(electronDist, ffmpegLocation, ffmpegName),
|
|
36
|
+
} = options;
|
|
37
|
+
const ffmpegCachedPath = path.join(os.tmpdir(), `theia-cli/cache/electron-v${electronVersion}`, ffmpegName);
|
|
38
|
+
if (await fs.pathExists(ffmpegCachedPath)) {
|
|
39
|
+
shouldDownload = false; // If the file is already cached, do not download.
|
|
40
|
+
console.warn('Found cached ffmpeg library.');
|
|
41
|
+
const [cacheHash, distHash] = await Promise.all([
|
|
42
|
+
hashFile(ffmpegCachedPath),
|
|
43
|
+
hashFile(ffmpegPath),
|
|
44
|
+
]);
|
|
45
|
+
if (cacheHash.equals(distHash)) {
|
|
46
|
+
shouldReplace = false; // If files are already the same, do not replace.
|
|
47
|
+
console.warn('Hashes are equal, not replacing the ffmpeg library.');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (shouldDownload) {
|
|
51
|
+
const ffmpegZipPath = await electronGet.downloadArtifact({
|
|
52
|
+
version: electronVersion,
|
|
53
|
+
artifactName: 'ffmpeg'
|
|
54
|
+
});
|
|
55
|
+
const ffmpegZip = await unzipper.Open.file(ffmpegZipPath);
|
|
56
|
+
const file = ffmpegZip.files.find(f => f.path.endsWith(ffmpegName));
|
|
57
|
+
if (!file) {
|
|
58
|
+
throw new Error(`Archive did not contain "${ffmpegName}".`);
|
|
59
|
+
}
|
|
60
|
+
// Extract file to cache.
|
|
61
|
+
await fs.mkdirp(path.dirname(ffmpegCachedPath));
|
|
62
|
+
await new Promise((resolve, reject) => {
|
|
63
|
+
file.stream()
|
|
64
|
+
.pipe(fs.createWriteStream(ffmpegCachedPath))
|
|
65
|
+
.on('finish', resolve)
|
|
66
|
+
.on('error', reject);
|
|
67
|
+
});
|
|
68
|
+
console.warn(`Downloaded ffmpeg shared library { version: "${electronVersion}", dist: "${electronDist}" }.`);
|
|
69
|
+
}
|
|
70
|
+
if (shouldReplace) {
|
|
71
|
+
await fs.copy(ffmpegCachedPath, ffmpegPath);
|
|
72
|
+
console.warn(`Successfully replaced "${ffmpegPath}".`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function readElectronVersion(electronDist: string): Promise<string> {
|
|
77
|
+
const electronVersionFilePath = path.resolve(electronDist, 'version');
|
|
78
|
+
const version = await fs.readFile(electronVersionFilePath, 'utf8');
|
|
79
|
+
return version.trim();
|
|
80
|
+
}
|