Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add downloadAlternateFFmpeg option #7247

Closed

Conversation

baparham
Copy link
Contributor

@baparham baparham commented Nov 8, 2022

This is a possible solution to the question proposed in #7210 addressing the need/desire to have an automatic FFmpeg download as part of downloading the standard electron distributable.

@changeset-bot
Copy link

changeset-bot bot commented Nov 8, 2022

🦋 Changeset detected

Latest commit: 4dcd9ff

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
app-builder-lib Minor
dmg-builder Minor
electron-builder-squirrel-windows Minor
electron-builder Minor
electron-forge-maker-appimage Minor
electron-forge-maker-nsis-web Minor
electron-forge-maker-nsis Minor
electron-forge-maker-snap Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link

netlify bot commented Nov 8, 2022

Deploy Preview for car-park-attendant-cleat-11576 ready!

Name Link
🔨 Latest commit 4dcd9ff
🔍 Latest deploy log https://app.netlify.com/sites/car-park-attendant-cleat-11576/deploys/636a73e4578a310009eb0594
😎 Deploy Preview https://deploy-preview-7247--car-park-attendant-cleat-11576.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

/**
* Whether to download the alternate FFmpeg library from Electron's release assets and replace the default FFmpeg library prior to signing
*/
readonly downloadAlternateFFmpeg?: boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are your thoughts on renaming this to: injectElectronFFmpeg or something similar? downloadAlternate seems odd to me because it can also use ELECTRON_BUILDER_CACHE and this seems to be more Electron-specific than just a generic alternate library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, a name for this is kind of hard. It's also not just downloading it is really using the alternate ffmpeg library. I was also hesitant to call it nonProprietary since I don't really have a guarantee from electron that it is non proprietary...we as consumers are supposed to be the ones checking this sort of thing. Granted, it's built with the proprietary_codecs=false flag from chromium.

Anyway, all Electron's come with this ffmpeg library, its just that we want to use an alternative one that supposedly has only non proprietary codecs in it. With that, I'd say the best name maybe is useNonProprietaryFFmpeg ... that seems to be as descriptive and accurate as it gets.

if (packager.config.downloadAlternateFFmpeg) {
log.info("downloading and unpacking alternate FFmpeg")
const ffmpegOptions = Object.assign({}, options)
ffmpegOptions.customFilename = `ffmpeg-v${options.version}-${options.platform}-${options.arch}.zip`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the logic above for const zipFile = electron-v${options.version}-${platformName}-${options.arch}.zip``, I think we can use platformName instead of `options.platform`? That way we're labeling for sure the same download file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the naming logic here mirrors the unpack-electron options (since the full options object is just passed to the app-builder-bin call), since this case is only handled when we are downloading the default electron distributable (i.e. dist === null). The zipFile reference above is referencing something the user can manually override and specify custom platforms for, and we won't run this ffmpeg option in such a case. The user is expected to have the dlls in that electron distributable the way they want them.

log.info("downloading and unpacking alternate FFmpeg")
const ffmpegOptions = Object.assign({}, options)
ffmpegOptions.customFilename = `ffmpeg-v${options.version}-${options.platform}-${options.arch}.zip`
let ffmpegLocation = path.join(appOutDir, "..")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would path.dirname(appOutDir) work better here? Either that or path.resolve?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, probably best to just stick to path.dirname(appOutDir) to avoid the ... I'll fix.

if (!isEmptyOrSpaces(process.env.ELECTRON_BUILDER_CACHE)) {
ffmpegLocation = process.env.ELECTRON_BUILDER_CACHE
}
ffmpegOptions.cache = ffmpegLocation
Copy link
Collaborator

@mmaietta mmaietta Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the logic for options.cache = resolvedDist, I think the options.cache is supposed to be an absolute path to the actual file (as opposed to a folder, which is what I'm under the impression the BUILDER_CACHE should be)

Copy link
Contributor Author

@baparham baparham Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I was basing this off of the app-builder arguments, where it expects the cache property in the config to be a directory.

[edit: I'm bummed these permalinks below didn't auto render as code snippets, so apologies for making you jump over to a new tab to see what I am referring to]

https://github.com/develar/app-builder/blob/4e2aa6a12e2bc3d31ec0d01d661fb3a4d65248ff/pkg/electron/electronDownloader.go#L20

and

https://github.com/develar/app-builder/blob/4e2aa6a12e2bc3d31ec0d01d661fb3a4d65248ff/pkg/electron/electronDownloader.go#L62

However, I mistakenly read the ELECTRON_CACHE as ELECTRON_BUILDER_CACHE and defaulted to that if it were explicitly specified other than the default [edit: i.e. path.dirname(appOutDir)] to take advantage of caching this ffmpeg download between runs if users had specified the ELECTRON_CACHE folder.

I was really hoping to use a getCacheFolder method that I could call and not have to specify any specific directory, since we a) probably want to keep this download cached like we do electron distributables and b) we need to know where it ends up after downloading so that we can unzip it.

Perhaps the caching is a premature optimization and it's easiest and cleanest to just keep it up in path.dirname(appOutDir) for now without the caching logic, since this zip is ever only around 1mb.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha gotcha. Yes, great callout as well, I think the caching is an unnecessary optimization for now when it's that is only 1mb.

Just to double check, is this working in your personal/test project?
Have you given any thought on how we could integration test this? I'll continue thinking from my end. Is there a way for us to detect whether a new FFmpeg was downloaded or not? As we do have a post-packaging hook for verifying app contents.

@@ -6416,6 +6416,11 @@
],
"description": "macOS DMG options."
},
"downloadAlternateFFmpeg": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the schema, we'll also need to run pnpm generate-all to update the docs+schema together

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, ok, thanks for the tip. I'll run that and submit another commit with the updates.

Copy link
Contributor Author

@baparham baparham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! I've answered your questions though it seems like there's still some more discussion needed before I push anything back up to the branch, so I'll hold off until I hear your thoughts.

@@ -6416,6 +6416,11 @@
],
"description": "macOS DMG options."
},
"downloadAlternateFFmpeg": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, ok, thanks for the tip. I'll run that and submit another commit with the updates.

/**
* Whether to download the alternate FFmpeg library from Electron's release assets and replace the default FFmpeg library prior to signing
*/
readonly downloadAlternateFFmpeg?: boolean
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, a name for this is kind of hard. It's also not just downloading it is really using the alternate ffmpeg library. I was also hesitant to call it nonProprietary since I don't really have a guarantee from electron that it is non proprietary...we as consumers are supposed to be the ones checking this sort of thing. Granted, it's built with the proprietary_codecs=false flag from chromium.

Anyway, all Electron's come with this ffmpeg library, its just that we want to use an alternative one that supposedly has only non proprietary codecs in it. With that, I'd say the best name maybe is useNonProprietaryFFmpeg ... that seems to be as descriptive and accurate as it gets.

if (packager.config.downloadAlternateFFmpeg) {
log.info("downloading and unpacking alternate FFmpeg")
const ffmpegOptions = Object.assign({}, options)
ffmpegOptions.customFilename = `ffmpeg-v${options.version}-${options.platform}-${options.arch}.zip`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the naming logic here mirrors the unpack-electron options (since the full options object is just passed to the app-builder-bin call), since this case is only handled when we are downloading the default electron distributable (i.e. dist === null). The zipFile reference above is referencing something the user can manually override and specify custom platforms for, and we won't run this ffmpeg option in such a case. The user is expected to have the dlls in that electron distributable the way they want them.

log.info("downloading and unpacking alternate FFmpeg")
const ffmpegOptions = Object.assign({}, options)
ffmpegOptions.customFilename = `ffmpeg-v${options.version}-${options.platform}-${options.arch}.zip`
let ffmpegLocation = path.join(appOutDir, "..")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, probably best to just stick to path.dirname(appOutDir) to avoid the ... I'll fix.

if (!isEmptyOrSpaces(process.env.ELECTRON_BUILDER_CACHE)) {
ffmpegLocation = process.env.ELECTRON_BUILDER_CACHE
}
ffmpegOptions.cache = ffmpegLocation
Copy link
Contributor Author

@baparham baparham Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I was basing this off of the app-builder arguments, where it expects the cache property in the config to be a directory.

[edit: I'm bummed these permalinks below didn't auto render as code snippets, so apologies for making you jump over to a new tab to see what I am referring to]

https://github.com/develar/app-builder/blob/4e2aa6a12e2bc3d31ec0d01d661fb3a4d65248ff/pkg/electron/electronDownloader.go#L20

and

https://github.com/develar/app-builder/blob/4e2aa6a12e2bc3d31ec0d01d661fb3a4d65248ff/pkg/electron/electronDownloader.go#L62

However, I mistakenly read the ELECTRON_CACHE as ELECTRON_BUILDER_CACHE and defaulted to that if it were explicitly specified other than the default [edit: i.e. path.dirname(appOutDir)] to take advantage of caching this ffmpeg download between runs if users had specified the ELECTRON_CACHE folder.

I was really hoping to use a getCacheFolder method that I could call and not have to specify any specific directory, since we a) probably want to keep this download cached like we do electron distributables and b) we need to know where it ends up after downloading so that we can unzip it.

Perhaps the caching is a premature optimization and it's easiest and cleanest to just keep it up in path.dirname(appOutDir) for now without the caching logic, since this zip is ever only around 1mb.

@baparham
Copy link
Contributor Author

baparham commented Dec 1, 2022

@mmaietta are you waiting on me to do anything else?

@baparham
Copy link
Contributor Author

baparham commented Dec 1, 2022

@mmaietta are you waiting on me to do anything else?

ah, sorry, I see some things I said I would fix. My mistake.

@calisven
Copy link

@mmaietta are you waiting on me to do anything else?

ah, sorry, I see some things I said I would fix. My mistake.

@baparham Hello, is there any update on when this will be released? Appreciate your and the team's great work!

@baparham
Copy link
Contributor Author

Hey, been in holiday mode and then sick. Hopefully I can get back on it and get this merged in within a few weeks

@baparham
Copy link
Contributor Author

Hey, been in holiday mode and then sick. Hopefully I can get back on it and get this merged in within a few weeks

Still on my to-do list, but I haven't forgotten! Thanks for the patience

@mmaietta
Copy link
Collaborator

Hey @baparham ! During some other research, I came across this npm package for handling non-proprietary ffmpeg (https://www.npmjs.com/package/electron-packager-plugin-non-proprietary-codecs-ffmpeg)

I gave it a shot. Would you be willing to test it after merge? I don't know how to set up a test for this PR #7477

@baparham
Copy link
Contributor Author

The only test I've come up with is doing like an objdump or dumpbin.exe on windows to look for some specific strings like x264 or aac but even that is subjective, since they are still defined, there are just many fewer occurrences of that string when proprietary_codecs=false, it makes for a somewhat fragile test, but it's something.

@mmaietta mmaietta closed this Mar 19, 2023
@mmaietta
Copy link
Collaborator

Closing. Added functionality via #7477 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants