зеркало из https://github.com/electron/electron.git
feat: modify API to use useSystemPicker option
This commit is contained in:
Родитель
ea905b2e04
Коммит
5a7b61ffcd
|
@ -16,19 +16,12 @@ app.whenReady().then(() => {
|
|||
const mainWindow = new BrowserWindow()
|
||||
|
||||
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
|
||||
// If we should use the system picker
|
||||
// Note: this is currently experimental
|
||||
if (desktopCapturer.isDisplayMediaSystemPickerAvailable()) {
|
||||
desktopCapturer.getNativePickerSource().then((source) => {
|
||||
callback({ video: source })
|
||||
return
|
||||
})
|
||||
}
|
||||
desktopCapturer.getSources({ types: ['screen'] }).then((sources) => {
|
||||
// Grant access to the first screen found.
|
||||
// Your app shows some UI, but in this exampe
|
||||
// grant access to the first screen found.
|
||||
callback({ video: sources[0], audio: 'loopback' })
|
||||
})
|
||||
})
|
||||
}, { useSystemPicker: true })
|
||||
|
||||
mainWindow.loadFile('index.html')
|
||||
})
|
||||
|
@ -46,7 +39,8 @@ startButton.addEventListener('click', () => {
|
|||
video: {
|
||||
width: 320,
|
||||
height: 240,
|
||||
frameRate: 30
|
||||
frameRate: 30,
|
||||
displaySurface: 'monitor'
|
||||
}
|
||||
}).then(stream => {
|
||||
video.srcObject = stream
|
||||
|
@ -102,7 +96,7 @@ which can detected by [`systemPreferences.getMediaAccessStatus`][].
|
|||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos
|
||||
|
||||
### `desktopCapturer.isDisplayMediaSystemPickerAvailable()` _Experimental_ _MacOS_
|
||||
### `desktopCapturer.isDisplayMediaSystemPickerAvailable()` _Experimental_ _macOS_
|
||||
|
||||
Returns `Boolean`, whether or not requesting desktop content via
|
||||
the system picker is supported on this platform.
|
||||
|
@ -112,12 +106,6 @@ true, use the `getNativePickerSource` method to return the system picker's
|
|||
selected media stream. Not doing so may cause a warning dialog to your users
|
||||
on macOS 15 and higher.
|
||||
|
||||
### `desktopCapturer.getNativePickerSource` _Experimental_ _Readonly_ _MacOS_
|
||||
|
||||
A `DesktopCapturerSource` property that should be used in conjunction with
|
||||
[`session.setDisplayMediaRequestHandler`](./session.md#sessetdisplaymediarequesthandlerhandler) to use the system picker instead
|
||||
of providing a specific video source from `getSources`.
|
||||
|
||||
## Caveats
|
||||
|
||||
`navigator.mediaDevices.getUserMedia` does not work on macOS for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html). Chromium, and by extension Electron, does not provide this.
|
||||
|
|
|
@ -953,7 +953,7 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
|
|||
})
|
||||
```
|
||||
|
||||
#### `ses.setDisplayMediaRequestHandler(handler)`
|
||||
#### `ses.setDisplayMediaRequestHandler(handler[, opts])`
|
||||
|
||||
* `handler` Function | null
|
||||
* `request` Object
|
||||
|
@ -980,6 +980,8 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
|
|||
and this is set to `true`, then local playback of audio will not be muted (e.g. using `MediaRecorder`
|
||||
to record `WebFrameMain` with this flag set to `true` will allow audio to pass through to the speakers
|
||||
while recording). Default is `false`.
|
||||
* `opts` Object (optional)
|
||||
* `useSystemPicker` Boolean - true if a user wants to use the native system picker
|
||||
|
||||
This handler will be called when web content requests access to display media
|
||||
via the `navigator.mediaDevices.getDisplayMedia` API. Use the
|
||||
|
|
|
@ -15,27 +15,6 @@ function isValid (options: Electron.SourcesOptions) {
|
|||
|
||||
export { isDisplayMediaSystemPickerAvailable };
|
||||
|
||||
export async function getNativePickerSource () {
|
||||
if (process.platform !== 'darwin') {
|
||||
throw new Error('Native system picker option is currently only supported on MacOS');
|
||||
}
|
||||
|
||||
if (!isDisplayMediaSystemPickerAvailable) {
|
||||
throw new Error(`Native system picker unavailable.
|
||||
Note: This is an experimental API; please check the API documentation for updated restrictions`);
|
||||
}
|
||||
|
||||
// Pass in the needed options for a more native experience
|
||||
// screen & windows by default, no thumbnails, since the native picker doesn't return them
|
||||
const options: Electron.SourcesOptions = {
|
||||
types: ['screen', 'window'],
|
||||
thumbnailSize: { width: 0, height: 0 },
|
||||
fetchWindowIcons: false
|
||||
};
|
||||
|
||||
return await getSources(options);
|
||||
}
|
||||
|
||||
export async function getSources (args: Electron.SourcesOptions) {
|
||||
if (!isValid(args)) throw new Error('Invalid options');
|
||||
|
||||
|
|
|
@ -1,11 +1,46 @@
|
|||
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
|
||||
import { net } from 'electron/main';
|
||||
import { desktopCapturer, net } from 'electron/main';
|
||||
const { fromPartition, fromPath, Session } = process._linkedBinding('electron_browser_session');
|
||||
const { isDisplayMediaSystemPickerAvailable } = process._linkedBinding('electron_browser_desktop_capturer');
|
||||
|
||||
async function getNativePickerSource () {
|
||||
if (process.platform !== 'darwin') {
|
||||
throw new Error('Native system picker option is currently only supported on MacOS');
|
||||
}
|
||||
|
||||
if (!isDisplayMediaSystemPickerAvailable) {
|
||||
throw new Error(`Native system picker unavailable.
|
||||
Note: This is an experimental API; please check the API documentation for updated restrictions`);
|
||||
}
|
||||
|
||||
// Pass in the needed options for a more native experience
|
||||
// screen & windows by default, no thumbnails, since the native picker doesn't return them
|
||||
const options: Electron.SourcesOptions = {
|
||||
types: ['screen', 'window'],
|
||||
thumbnailSize: { width: 0, height: 0 },
|
||||
fetchWindowIcons: false
|
||||
};
|
||||
|
||||
const mediaStreams = await desktopCapturer.getSources(options);
|
||||
return mediaStreams[0];
|
||||
}
|
||||
|
||||
Session.prototype.fetch = function (input: RequestInfo, init?: RequestInit) {
|
||||
return fetchWithSession(input, init, this, net.request);
|
||||
};
|
||||
|
||||
Session.prototype.setDisplayMediaRequestHandler = function (handler, opts) {
|
||||
if (!handler) return this._setDisplayMediaRequestHandler(handler, opts);
|
||||
|
||||
this._setDisplayMediaRequestHandler(async (req, callback) => {
|
||||
if (opts && opts.useSystemPicker && isDisplayMediaSystemPickerAvailable()) {
|
||||
return callback({ video: await getNativePickerSource() });
|
||||
}
|
||||
|
||||
return handler(req, callback);
|
||||
}, opts);
|
||||
};
|
||||
|
||||
export default {
|
||||
fromPartition,
|
||||
fromPath,
|
||||
|
|
|
@ -110,10 +110,10 @@ index 2215bf4589342fa4619fb58ec3e21ff5ef3ed3b4..3e52ce331b80cf97fd7b9bcbf7dd4311
|
|||
// There was a bug in ScreenCaptureKit that was fixed in 14.4,
|
||||
// see b/40076027.
|
||||
diff --git a/content/browser/media/capture/native_screen_capture_picker_mac.mm b/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
index b5a776f37b4bb667bc1aa62a08102b67a12f5b64..36b1508f0a8bd17bec0e49bf797a64c2fcc38bc2 100644
|
||||
index b34d8402c213329620683e41588c0411d45124fb..1b8e95f476a032f60ea7e578fac480344924ab50 100644
|
||||
--- a/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
+++ b/content/browser/media/capture/native_screen_capture_picker_mac.mm
|
||||
@@ -117,8 +117,11 @@ void Open(DesktopMediaID::Type type,
|
||||
@@ -132,8 +132,11 @@ void Open(DesktopMediaID::Type type,
|
||||
base::OnceCallback<void()> cancel_callback,
|
||||
base::OnceCallback<void()> error_callback) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
@ -126,14 +126,13 @@ index b5a776f37b4bb667bc1aa62a08102b67a12f5b64..36b1508f0a8bd17bec0e49bf797a64c2
|
|||
if (@available(macOS 14.0, *)) {
|
||||
NSNumber* source_id = @(next_id_);
|
||||
auto picker_observer = [[PickerObserver alloc]
|
||||
@@ -135,20 +138,14 @@ void Open(DesktopMediaID::Type type,
|
||||
@@ -150,19 +153,13 @@ void Open(DesktopMediaID::Type type,
|
||||
// TODO(https://crbug.com/360781940): Add support for changing selected
|
||||
// content. The problem to solve is how this should interact with stream
|
||||
// restart.
|
||||
- config.allowsChangingSelectedContent = false;
|
||||
+ config.allowsChangingSelectedContent = true;
|
||||
// Limits the maximum number of screen/window capture to 5.
|
||||
NSNumber* max_stream_count = @5;
|
||||
NSNumber* max_stream_count = @(kMaxContentShareCountValue.Get());
|
||||
- if (type == DesktopMediaID::Type::TYPE_SCREEN) {
|
||||
- config.allowedPickerModes = SCContentSharingPickerModeSingleDisplay;
|
||||
- picker.defaultConfiguration = config;
|
||||
|
|
|
@ -14,4 +14,4 @@ bool DesktopCapturer::IsDisplayMediaSystemPickerAvailable() {
|
|||
return false;
|
||||
}
|
||||
|
||||
} // namespace electron::api
|
||||
} // namespace electron::api
|
||||
|
|
|
@ -1607,7 +1607,7 @@ void Session::FillObjectTemplate(v8::Isolate* isolate,
|
|||
&Session::SetPermissionRequestHandler)
|
||||
.SetMethod("setPermissionCheckHandler",
|
||||
&Session::SetPermissionCheckHandler)
|
||||
.SetMethod("setDisplayMediaRequestHandler",
|
||||
.SetMethod("_setDisplayMediaRequestHandler",
|
||||
&Session::SetDisplayMediaRequestHandler)
|
||||
.SetMethod("setDevicePermissionHandler",
|
||||
&Session::SetDevicePermissionHandler)
|
||||
|
|
|
@ -127,6 +127,14 @@ declare namespace Electron {
|
|||
type?: 'backgroundPage' | 'window' | 'browserView' | 'remote' | 'webview' | 'offscreen';
|
||||
}
|
||||
|
||||
interface Session {
|
||||
_setDisplayMediaRequestHandler: Electron.Session['setDisplayMediaRequestHandler'];
|
||||
}
|
||||
|
||||
interface DisplayMediaRequestHandlerOpts {
|
||||
userSystemPicker: boolean,
|
||||
}
|
||||
|
||||
type CreateWindowFunction = (options: BrowserWindowConstructorOptions) => WebContents;
|
||||
|
||||
interface Menu {
|
||||
|
|
Загрузка…
Ссылка в новой задаче