Skip to content

Commit 91f86ae

Browse files
authored
fix: refactoring ffmpeg implementation and removing related npm dependency (#7495)
1 parent b23a9b6 commit 91f86ae

12 files changed

+97
-247
lines changed

.changeset/violet-dots-joke.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"app-builder-lib": patch
3+
---
4+
5+
fix: removing ffmpeg dependency due to dependency vulnerability

.github/workflows/test.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ jobs:
4444
id: changed-files-specific
4545
uses: tj-actions/changed-files@ce4b8e3cba2220de8132ac9721ff754efd6bb7d7 # v34
4646
with:
47-
files: docker/**
47+
files: docker/**/*
4848

4949
- name: Dockerfile has changed, rebuild for tests
50-
if: ${{ github.event.inputs.build-docker-locally == 'true' }} || steps.changed-files-specific.outputs.any_changed == 'true'
50+
if: steps.changed-files-specific.outputs.any_changed == 'true'
5151
run: pnpm docker-images
5252

5353
- name: Run tests in docker image
@@ -84,7 +84,7 @@ jobs:
8484
- name: Setup Tests
8585
uses: ./.github/actions/pretest
8686
with:
87-
cache-path: ~/Library/Caches/electron
87+
cache-path: ~/.cache/electron
8888
cache-key: v-11.0.0-update-electron
8989

9090
- name: Test

packages/app-builder-lib/package.json

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"out",
88
"templates",
99
"scheme.json",
10-
"electron-osx-sign",
1110
"certs/root_certs.keychain"
1211
],
1312
"repository": {
@@ -61,7 +60,6 @@
6160
"chromium-pickle-js": "^0.2.0",
6261
"debug": "^4.3.4",
6362
"ejs": "^3.1.8",
64-
"electron-packager-plugin-non-proprietary-codecs-ffmpeg": "^1.0.2",
6563
"electron-publish": "workspace:*",
6664
"form-data": "^4.0.0",
6765
"fs-extra": "^10.1.0",

packages/app-builder-lib/src/electron/ElectronFramework.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { getTemplatePath } from "../util/pathManager"
1414
import { createMacApp } from "./electronMac"
1515
import { computeElectronVersion, getElectronVersionFromInstalled } from "./electronVersion"
1616
import * as fs from "fs/promises"
17-
import replaceFFMPEG from "electron-packager-plugin-non-proprietary-codecs-ffmpeg"
17+
import injectFFMPEG from "./injectFFMPEG"
1818

1919
export type ElectronPlatformName = "darwin" | "linux" | "win32" | "mas"
2020

@@ -136,8 +136,7 @@ class ElectronFramework implements Framework {
136136
async prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions) {
137137
await unpack(options, createDownloadOpts(options.packager.config, options.platformName, options.arch, this.version), this.distMacOsAppName)
138138
if (options.packager.config.downloadAlternateFFmpeg) {
139-
log.info(null, "downloading non-proprietary FFMPEG, piping output")
140-
await new Promise<void>(resolve => replaceFFMPEG(options.appOutDir, options.version, options.platformName, options.arch, resolve))
139+
await injectFFMPEG(options, this.version)
141140
}
142141
}
143142

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as fs from "fs"
2+
import * as path from "path"
3+
import { ElectronPlatformName } from "./ElectronFramework"
4+
5+
import { log } from "builder-util"
6+
import { getBin } from "../binDownload"
7+
import { PrepareApplicationStageDirectoryOptions } from "../Framework"
8+
9+
// NOTE: Adapted from https://github.com/MarshallOfSound/electron-packager-plugin-non-proprietary-codecs-ffmpeg to resolve dependency vulnerabilities
10+
const downloadFFMPEG = async (electronVersion: string, platform: ElectronPlatformName, arch: string) => {
11+
const ffmpegFileName = `ffmpeg-v${electronVersion}-${platform}-${arch}.zip`
12+
const url = `https://github.com/electron/electron/releases/download/v${electronVersion}/${ffmpegFileName}`
13+
14+
log.info({ file: ffmpegFileName }, "downloading non-proprietary FFMPEG")
15+
return getBin(ffmpegFileName, url)
16+
}
17+
18+
const copyFFMPEG = (targetPath: string, platform: ElectronPlatformName) => (sourcePath: string) => {
19+
let fileName = "ffmpeg.dll"
20+
if (["darwin", "mas"].includes(platform)) {
21+
fileName = "libffmpeg.dylib"
22+
} else if (platform === "linux") {
23+
fileName = "libffmpeg.so"
24+
}
25+
26+
const libPath = path.resolve(sourcePath, fileName)
27+
const libTargetPath = path.resolve(targetPath, fileName)
28+
log.info({ lib: libPath, target: libTargetPath }, "copying non-proprietary FFMPEG")
29+
30+
// If the source doesn't exist we have a problem
31+
if (!fs.existsSync(libPath)) {
32+
throw new Error(`Failed to find FFMPEG library file at path: ${libPath}`)
33+
}
34+
35+
// If we are copying to the source we can stop immediately
36+
if (libPath !== libTargetPath) {
37+
fs.copyFileSync(libPath, libTargetPath)
38+
}
39+
return libTargetPath
40+
}
41+
42+
export default function injectFFMPEG(options: PrepareApplicationStageDirectoryOptions, electrionVersion: string) {
43+
let libPath = options.appOutDir
44+
if (options.platformName === "darwin") {
45+
libPath = path.resolve(options.appOutDir, "Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries")
46+
}
47+
48+
return downloadFFMPEG(electrionVersion, options.platformName, options.arch).then(copyFFMPEG(libPath, options.platformName))
49+
}

0 commit comments

Comments
 (0)