Function Description
This article mainly introduces how to implement screen sharing function in TRTC Web SDK.
Implementation Process
-
Start Local Screen Sharing
const trtcA = TRTC.create(); await trtcA.enterRoom({ scene: 'rtc', sdkAppId: 140000000, // Fill in your sdkAppId userId: 'userA', // Fill in your userId userSig: 'userA_sig', // Fill in userSig corresponding to userId roomId: 6969 }) await trtcA.startScreenShare();
-
Play Remote Screen Sharing
const trtcB = TRTC.create(); trtcB.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => { // Main video stream, generally the stream pushed by the camera if (streamType === TRTC.TYPE.STREAM_TYPE_MAIN) { // 1. Place a div tag with an id of `${userId}_main` on the page to play the main stream in the div tag. The business side can customize the id of the div tag. This is just an example. // 2. Play the main video stream trtcB.startRemoteVideo({ userId, streamType, view: `${userId}_main` }); } else { // Sub video stream, generally the stream pushed by screen sharing. // 1. Place a div tag with an id of `${userId}_screen` on the page to play the screen sharing in the div tag. The business side can customize the id of the div tag. This is just an example. // 2. Play screen sharing trtcB.startRemoteVideo({ userId, streamType, view: `${userId}_screen` }); } }); await trtcB.enterRoom({ scene: 'rtc', sdkAppId: 140000000, // Fill in your sdkAppId userId: 'userB', // Fill in your userId userSig: 'userB_sig', // Fill in userSig corresponding to userId roomId: 6969 })
-
Start Camera + Screen Sharing at the Same Time
await trtcA.startLocalVideo(); await trtcA.startScreenShare();
-
Screen Sharing + System Audio
System audio collection is supported by Chrome M74+
- On Windows and Chrome OS, the audio of the entire system can be collected.
- On Linux and Mac, only the audio of a certain page can be collected.
- Other Chrome versions, other systems, and other browsers are not supported.
await trtcA.startScreenShare({ option: { systemAudio: true }});
Check
Share audio
in the pop-up dialog box, and the system audio will be mixed with the local microphone and published. Other users in the room will receive the TRTC.EVENT.REMOTE_AUDIO_AVALIABLE event. -
Stop Screen Sharing
// Stop screen sharing collection and publishing await trtcA.stopScreenShare(); // Other users in the room will receive the TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE event, and streamType is TRTC.TYPE.STREAM_TYPE_SUB. trtcB.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, ({ userId, streamType }) => { if (streamType === TRTC.TYPE.STREAM_TYPE_SUB) { } })
In addition, users may also stop screen sharing through the browser's own button, so the screen sharing stream needs to listen for the screen sharing stop event and respond accordingly.
// Listen for screen sharing stop event trtcA.on(TRTC.EVENT.SCREEN_SHARE_STOPPED, () => { console.log('screen sharing was stopped'); });
Electron uses TRTC Web SDK for screen sharing
The preferred recommendation is to use the TRTC Electron SDK
Because Electron does not implement the browser-supported WebRTC standard getDisplayMedia
interface, if a web page contains WebRTC screen share-related logic, it will not be possible to use the TRTC Web SDK for screen share in Electron as a normal browser. If you only want to use the TRTC Web SDK, please refer to the following solution.
To implement screen share, you need to use Electron's API:desktopCapturer.getSources({ types: ['window', 'screen'] })
- The main process
main.js
listens for the page to finish loading, gets the list of screen share sources viadesktopCapturer.getSources
, and sends the list of screen share sources to the rendering process. - The rendering process listens to the main process events to get a list of screen share sources.
- Create screen share streams and push them through the TRTC Web SDK.
- Get the screen-sharing
MediaStream
from the system API vianavigator.mediaDevices.getUserMedia()
. - Pass the custom captured videoTrack in the
option
parameter ofTRTC.startScreenShare()
to push the screen sharing stream.
- Get the screen-sharing
// 【1】main.js Master process gets list of screen share sources
const { app, BrowserWindow, desktopCapturer, systemPreferences } = require('electron');
function createWindow () {
const win = new BrowserWindow({
// ...
});
win.loadFile('./src/index.html');
win.webContents.on('did-finish-load', async () => {
if (win) {
const sources = await desktopCapturer.getSources({
types: ["window", "screen"],
});
win.webContents.send("SEND_SCREEN_SHARE_SOURCES", sources);
}
});
}
// 【2】Render process listens to main process events to get a list of screen share sources
const { ipcRenderer } = require('electron');
let shareSourceList = [];
ipcRenderer.on('SEND_SCREEN_SHARE_SOURCES', async (event, sources) => {
const selectContainer = window.document.getElementById('screen-share-select');
shareSourceList = sources;
sources.forEach(obj => {
const optionElement = document.createElement('option');
optionElement.innerText = `${obj.name}`;
selectContainer.appendChild(optionElement);
});
})
// 【3】Rendering process push screen share
async function startScreenShare() {
const selectContainer = document.getElementById('screen-share-select');
const selectValue = selectContainer.options[selectContainer.selectedIndex].value;
const [ source ] = shareSourceList.filter(obj => obj.name === `${selectValue}`);
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: source.id, // screen share source id
minWidth: 1280,
maxWidth: 1280,
minHeight: 720,
maxHeight: 720
}
}
});
const trtc = TRTC.create();
await trtc.enterRoom({
// ...
});
await trtc.startScreenShare({
option: {
videoTrack: stream.getVideoTracks()[0],
}
})
} catch (error) {
console.error('start screen share error = ', error)
}
}
Precautions
- What is the main/sub video stream?
- The SDK uses the
1080p
parameter configuration by default to collect screen sharing. For details, refer to the interface: startScreenShare
Common Issues
-
Safari screen sharing error
getDisplayMedia must be called from a user gesture handler
This is because Safari restricts the
getDisplayMedia
screen capture interface, which must be called within 1 second of the callback function of the user click event.Reference: webkit issue.
// good async function onClick() { // It is recommended to execute the collection logic first when onClick is executed await trtcA.startScreenShare(); await trtcA.enterRoom({ roomId: 123123, sdkAppId: 140000000, // Fill in your sdkAppId userId: 'userA', // Fill in your userId userSig: 'userA_sig', // Fill in userSig corresponding to userId }); } // bad async function onClick() { await trtcA.enterRoom({ roomId: 123123, sdkAppId: 140000000, // Fill in your sdkAppId userId: 'userA', // Fill in your userId userSig: 'userA_sig', // Fill in userSig corresponding to userId }); // Entering the room may take more than 1s, and the collection may fail await trtcA.startScreenShare(); }
-
macOS Monterey(12.2.1), device permissions need to be requested in the master process
async function checkAndApplyDeviceAccessPrivilege() { const cameraPrivilege = systemPreferences.getMediaAccessStatus('camera'); console.log( `checkAndApplyDeviceAccessPrivilege before apply cameraPrivilege: ${cameraPrivilege}` ); if (cameraPrivilege !== 'granted') { await systemPreferences.askForMediaAccess('camera'); } const micPrivilege = systemPreferences.getMediaAccessStatus('microphone'); console.log( `checkAndApplyDeviceAccessPrivilege before apply micPrivilege: ${micPrivilege}` ); if (micPrivilege !== 'granted') { await systemPreferences.askForMediaAccess('microphone'); } const screenPrivilege = systemPreferences.getMediaAccessStatus('screen'); console.log( `checkAndApplyDeviceAccessPrivilege before apply screenPrivilege: ${screenPrivilege}` ); }
-
Mac Chrome screen sharing fails with the error message "NotAllowedError: Permission denied by system" or "NotReadableError: Could not start video source" when screen recording is already authorized. Chrome bug. Solution: Open 【Settings】> Click 【Security & Privacy】> Click 【Privacy】> Click 【Screen Recording】> Turn off Chrome screen recording authorization > Reopen Chrome screen recording authorization > Close Chrome browser > Reopen Chrome browser.