mirror of
https://github.com/Llewellynvdm/nativefier.git
synced 2025-01-03 06:10:20 +00:00
As documented in #1153, for Widevine support to work properly, we need to listen for the Widevine ready event, and as well for certain sites the app must be signed. This PR adds the events, and as well adds better documentation on the signing limitation. This may also help resolve #1147
This commit is contained in:
parent
d2c7de37a2
commit
f6e1ebd876
2
.gitignore
vendored
2
.gitignore
vendored
@ -43,6 +43,8 @@ build/Release
|
||||
# Dependency directory
|
||||
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
|
||||
node_modules
|
||||
# Python virtual environment in case it's created for the Castlabs code signing tool
|
||||
venv
|
||||
|
||||
# IntelliJ project files
|
||||
.idea
|
||||
|
162
app/src/main.ts
162
app/src/main.ts
@ -190,83 +190,107 @@ if (shouldQuit) {
|
||||
}
|
||||
});
|
||||
|
||||
app.on('ready', () => {
|
||||
mainWindow = createMainWindow(appArgs, app.quit.bind(this), setDockBadge);
|
||||
createTrayIcon(appArgs, mainWindow);
|
||||
if (appArgs.widevine !== undefined) {
|
||||
// @ts-ignore This event only appear on the widevine version of electron, which we'd see at runtime
|
||||
app.on('widevine-ready', (version, lastVersion) => {
|
||||
console.log('widevine-ready', version, lastVersion);
|
||||
onReady();
|
||||
});
|
||||
|
||||
// Register global shortcuts
|
||||
if (appArgs.globalShortcuts) {
|
||||
appArgs.globalShortcuts.forEach((shortcut) => {
|
||||
globalShortcut.register(shortcut.key, () => {
|
||||
shortcut.inputEvents.forEach((inputEvent) => {
|
||||
mainWindow.webContents.sendInputEvent(inputEvent);
|
||||
});
|
||||
// @ts-ignore This event only appear on the widevine version of electron, which we'd see at runtime
|
||||
app.on('widevine-update-pending', (currentVersion, pendingVersion) => {
|
||||
console.log(
|
||||
`Widevine ${currentVersion} is ready to be upgraded to ${pendingVersion}`,
|
||||
);
|
||||
});
|
||||
|
||||
// @ts-ignore This event only appear on the widevine version of electron, which we'd see at runtime
|
||||
app.on('widevine-error', (error) => {
|
||||
console.error('WIDEVINE ERROR: ', error);
|
||||
});
|
||||
} else {
|
||||
app.on('ready', () => {
|
||||
console.log('ready');
|
||||
onReady();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onReady(): void {
|
||||
mainWindow = createMainWindow(appArgs, app.quit.bind(this), setDockBadge);
|
||||
createTrayIcon(appArgs, mainWindow);
|
||||
|
||||
// Register global shortcuts
|
||||
if (appArgs.globalShortcuts) {
|
||||
appArgs.globalShortcuts.forEach((shortcut) => {
|
||||
globalShortcut.register(shortcut.key, () => {
|
||||
shortcut.inputEvents.forEach((inputEvent) => {
|
||||
mainWindow.webContents.sendInputEvent(inputEvent);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (isOSX() && appArgs.accessibilityPrompt) {
|
||||
const mediaKeys = [
|
||||
'MediaPlayPause',
|
||||
'MediaNextTrack',
|
||||
'MediaPreviousTrack',
|
||||
'MediaStop',
|
||||
];
|
||||
const globalShortcutsKeys = appArgs.globalShortcuts.map((g) => g.key);
|
||||
const mediaKeyWasSet = globalShortcutsKeys.find((g) =>
|
||||
mediaKeys.includes(g),
|
||||
);
|
||||
if (
|
||||
mediaKeyWasSet &&
|
||||
!systemPreferences.isTrustedAccessibilityClient(false)
|
||||
) {
|
||||
// Since we're trying to set global keyboard shortcuts for media keys, we need to prompt
|
||||
// the user for permission on Mac.
|
||||
// For reference:
|
||||
// https://www.electronjs.org/docs/api/global-shortcut?q=MediaPlayPause#globalshortcutregisteraccelerator-callback
|
||||
const accessibilityPromptResult = dialog.showMessageBoxSync(null, {
|
||||
type: 'question',
|
||||
message: 'Accessibility Permissions Needed',
|
||||
buttons: ['Yes', 'No', 'No and never ask again'],
|
||||
defaultId: 0,
|
||||
detail:
|
||||
`${appArgs.name} would like to use one or more of your keyboard's media keys (start, stop, next track, or previous track) to control it.\n\n` +
|
||||
`Would you like Mac OS to ask for your permission to do so?\n\n` +
|
||||
`If so, you will need to restart ${appArgs.name} after granting permissions for these keyboard shortcuts to begin working.`,
|
||||
});
|
||||
switch (accessibilityPromptResult) {
|
||||
// User clicked Yes, prompt for accessibility
|
||||
case 0:
|
||||
systemPreferences.isTrustedAccessibilityClient(true);
|
||||
break;
|
||||
// User cliecked Never Ask Me Again, save that info
|
||||
case 2:
|
||||
appArgs.accessibilityPrompt = false;
|
||||
saveAppArgs(appArgs);
|
||||
break;
|
||||
// User clicked No
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (isOSX() && appArgs.accessibilityPrompt) {
|
||||
const mediaKeys = [
|
||||
'MediaPlayPause',
|
||||
'MediaNextTrack',
|
||||
'MediaPreviousTrack',
|
||||
'MediaStop',
|
||||
];
|
||||
const globalShortcutsKeys = appArgs.globalShortcuts.map((g) => g.key);
|
||||
const mediaKeyWasSet = globalShortcutsKeys.find((g) =>
|
||||
mediaKeys.includes(g),
|
||||
);
|
||||
if (
|
||||
mediaKeyWasSet &&
|
||||
!systemPreferences.isTrustedAccessibilityClient(false)
|
||||
) {
|
||||
// Since we're trying to set global keyboard shortcuts for media keys, we need to prompt
|
||||
// the user for permission on Mac.
|
||||
// For reference:
|
||||
// https://www.electronjs.org/docs/api/global-shortcut?q=MediaPlayPause#globalshortcutregisteraccelerator-callback
|
||||
const accessibilityPromptResult = dialog.showMessageBoxSync(null, {
|
||||
type: 'question',
|
||||
message: 'Accessibility Permissions Needed',
|
||||
buttons: ['Yes', 'No', 'No and never ask again'],
|
||||
defaultId: 0,
|
||||
detail:
|
||||
`${appArgs.name} would like to use one or more of your keyboard's media keys (start, stop, next track, or previous track) to control it.\n\n` +
|
||||
`Would you like Mac OS to ask for your permission to do so?\n\n` +
|
||||
`If so, you will need to restart ${appArgs.name} after granting permissions for these keyboard shortcuts to begin working.`,
|
||||
});
|
||||
switch (accessibilityPromptResult) {
|
||||
// User clicked Yes, prompt for accessibility
|
||||
case 0:
|
||||
systemPreferences.isTrustedAccessibilityClient(true);
|
||||
break;
|
||||
// User cliecked Never Ask Me Again, save that info
|
||||
case 2:
|
||||
appArgs.accessibilityPrompt = false;
|
||||
saveAppArgs(appArgs);
|
||||
break;
|
||||
// User clicked No
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!appArgs.disableOldBuildWarning &&
|
||||
new Date().getTime() - appArgs.buildDate > OLD_BUILD_WARNING_THRESHOLD_MS
|
||||
) {
|
||||
const oldBuildWarningText =
|
||||
appArgs.oldBuildWarningText ||
|
||||
'This app was built a long time ago. Nativefier uses the Chrome browser (through Electron), and it is insecure to keep using an old version of it. Please upgrade Nativefier and rebuild this app.';
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
dialog.showMessageBox(null, {
|
||||
type: 'warning',
|
||||
message: 'Old build detected',
|
||||
detail: oldBuildWarningText,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (
|
||||
!appArgs.disableOldBuildWarning &&
|
||||
new Date().getTime() - appArgs.buildDate > OLD_BUILD_WARNING_THRESHOLD_MS
|
||||
) {
|
||||
const oldBuildWarningText =
|
||||
appArgs.oldBuildWarningText ||
|
||||
'This app was built a long time ago. Nativefier uses the Chrome browser (through Electron), and it is insecure to keep using an old version of it. Please upgrade Nativefier and rebuild this app.';
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
dialog.showMessageBox(null, {
|
||||
type: 'warning',
|
||||
message: 'Old build detected',
|
||||
detail: oldBuildWarningText,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
app.on('new-window-for-tab', () => {
|
||||
mainWindow.emit('new-tab');
|
||||
});
|
||||
|
@ -225,7 +225,7 @@ Electron version without the `v`, see https://github.com/atom/electron/releases.
|
||||
|
||||
Use a Widevine-enabled version of Electron for DRM playback, see https://github.com/castlabs/electron-releases.
|
||||
|
||||
Note: some sites (like Udemy or HBO Max) using Widevine may still refuse to load videos. Try signing your app using CastLabs tools. See [#1147](https://github.com/nativefier/nativefier/issues/1147#issuecomment-828750362). TL;DR:
|
||||
Note: some sites using Widevine (like Udemy or HBO Max) may still refuse to load videos, and require EVS-signing your Nativefier app to work. Try signing your app using CastLabs tools. See https://github.com/castlabs/electron-releases/wiki/EVS and [#1147](https://github.com/nativefier/nativefier/issues/1147#issuecomment-828750362). TL;DR:
|
||||
|
||||
```bash
|
||||
# Install CastLabs tools:
|
||||
@ -234,7 +234,7 @@ pip install --upgrade castlabs-evs
|
||||
# Sign up:
|
||||
python3 -m castlabs_evs.account signup
|
||||
|
||||
# Signed the generated app
|
||||
# Sign your app
|
||||
python -m castlabs_evs.vmp sign-pkg Udemy-win32-x64
|
||||
```
|
||||
|
||||
|
@ -83,6 +83,7 @@ function pickElectronAppArgs(options: AppOptions): any {
|
||||
userAgentOverriden: options.nativefier.userAgentOverriden,
|
||||
versionString: options.nativefier.versionString,
|
||||
width: options.nativefier.width,
|
||||
widevine: options.nativefier.widevine,
|
||||
win32metadata: options.packager.win32metadata,
|
||||
x: options.nativefier.x,
|
||||
y: options.nativefier.y,
|
||||
|
@ -53,6 +53,7 @@ export interface AppOptions {
|
||||
verbose: boolean;
|
||||
versionString: string;
|
||||
width: number;
|
||||
widevine: boolean;
|
||||
height: number;
|
||||
minWidth: number;
|
||||
minHeight: number;
|
||||
|
@ -101,6 +101,7 @@ export async function getOptions(rawOptions: any): Promise<AppOptions> {
|
||||
minHeight: rawOptions.minHeight,
|
||||
maxWidth: rawOptions.maxWidth,
|
||||
maxHeight: rawOptions.maxHeight,
|
||||
widevine: rawOptions.widevine || false,
|
||||
x: rawOptions.x,
|
||||
y: rawOptions.y,
|
||||
zoom: rawOptions.zoom || 1.0,
|
||||
@ -158,7 +159,11 @@ export async function getOptions(rawOptions: any): Promise<AppOptions> {
|
||||
log.warn(
|
||||
`\nATTENTION: Using the **unofficial** Electron from castLabs`,
|
||||
"\nIt implements Google's Widevine Content Decryption Module (CDM) for DRM-enabled playback.",
|
||||
`\nSimply abort & re-run without passing the widevine flag to default to ${DEFAULT_ELECTRON_VERSION}`,
|
||||
`\nSimply abort & re-run without passing the widevine flag to default to ${
|
||||
rawOptions.electronVersion !== undefined
|
||||
? (rawOptions.electronVersion as string)
|
||||
: DEFAULT_ELECTRON_VERSION
|
||||
}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user