mirror of https://github.com/OpenVidu/openvidu.git
ov-components: enhance screenshare button functionality for Firefox
- Updated the screenshare button in the toolbar to behave differently based on the browser type (Firefox vs others). - Added an input property `isFirefoxBrowser` to the `ToolbarMediaButtonsComponent` to determine the browser type. - Modified the HTML template to conditionally render the screenshare button and its menu based on the browser. - Improved the `switchScreenshare` method in the `ParticipantService` to handle errors more gracefully and ensure the local participant is defined before proceeding. - Refactored the `switchScreenshare` method in the `ParticipantModel` to reject promises with meaningful messages when no active screen share track is found.master
parent
87b3ac3716
commit
34e34ee078
File diff suppressed because it is too large
Load Diff
|
|
@ -36,6 +36,19 @@
|
|||
|
||||
<!-- Screenshare button - Only visible on tablet+ or when active -->
|
||||
@if (showScreenshareButtonDirect()) {
|
||||
@if (isFirefoxBrowser) {
|
||||
<button
|
||||
mat-icon-button
|
||||
id="screenshare-btn"
|
||||
[disabled]="isConnectionLost"
|
||||
[class.active-btn]="isScreenShareEnabled"
|
||||
[class.mobile-btn]="isMobileView()"
|
||||
matTooltip="{{ isScreenShareEnabled ? ('TOOLBAR.DISABLE_SCREEN' | translate) : ('TOOLBAR.ENABLE_SCREEN' | translate) }}"
|
||||
(click)="onScreenShareToggle()"
|
||||
>
|
||||
<mat-icon>screen_share</mat-icon>
|
||||
</button>
|
||||
} @else {
|
||||
<button
|
||||
mat-icon-button
|
||||
id="screenshare-btn"
|
||||
|
|
@ -62,6 +75,7 @@
|
|||
</button>
|
||||
</mat-menu>
|
||||
}
|
||||
}
|
||||
|
||||
<!-- Additional buttons injection from parent component (desktop/tablet only) -->
|
||||
@if (showAdditionalButtonsOutside() && additionalButtonsPosition === 'beforeMenu') {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export class ToolbarMediaButtonsComponent {
|
|||
// Screenshare related inputs
|
||||
@Input() showScreenshareButton: boolean = true;
|
||||
@Input() isScreenShareEnabled: boolean = false;
|
||||
@Input() isFirefoxBrowser: boolean = false;
|
||||
|
||||
// Device availability inputs
|
||||
@Input() hasVideoDevices: boolean = true;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
[microphoneMuteChanging]="microphoneMuteChanging"
|
||||
[showScreenshareButton]="showScreenshareButton"
|
||||
[isScreenShareEnabled]="isScreenShareEnabled"
|
||||
[isFirefoxBrowser]="isFirefoxBrowser"
|
||||
[hasVideoDevices]="hasVideoDevices"
|
||||
[hasAudioDevices]="hasAudioDevices"
|
||||
[isConnectionLost]="isConnectionLost"
|
||||
|
|
|
|||
|
|
@ -344,6 +344,11 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
*/
|
||||
showCaptionsButton: boolean = true;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
isFirefoxBrowser: boolean = false;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
|
@ -450,6 +455,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
private templateManagerService: TemplateManagerService
|
||||
) {
|
||||
this.log = this.loggerSrv.get('ToolbarComponent');
|
||||
this.isFirefoxBrowser = this.platformService.isFirefox();
|
||||
|
||||
// Effect to react to local participant changes
|
||||
effect(() => {
|
||||
|
|
|
|||
|
|
@ -436,14 +436,19 @@ export class ParticipantModel {
|
|||
* @internal
|
||||
*/
|
||||
async switchScreenshare(newTrack: LocalTrack): Promise<void> {
|
||||
if (this.participant instanceof LocalParticipant) {
|
||||
const screenTrack = this.tracks.find((track) => track.source === Track.Source.ScreenShare);
|
||||
if (screenTrack) {
|
||||
await (screenTrack.videoTrack as LocalTrack).replaceTrack(newTrack.mediaStreamTrack);
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (!(this.participant instanceof LocalParticipant)) {
|
||||
return Promise.reject("Remote participant can't switch screen share");
|
||||
}
|
||||
|
||||
const screenTrack = this.tracks.find((track) => track.source === Track.Source.ScreenShare);
|
||||
if (!screenTrack || !screenTrack.videoTrack) {
|
||||
return Promise.reject('No active screen share track to switch');
|
||||
}
|
||||
|
||||
const currentTrack = screenTrack.videoTrack as LocalTrack;
|
||||
|
||||
await currentTrack.replaceTrack(newTrack.mediaStreamTrack);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -189,19 +189,26 @@ export class ParticipantService {
|
|||
* Switches the active screen share track showing a native browser dialog to select a screen or window.
|
||||
*/
|
||||
async switchScreenShare(): Promise<void> {
|
||||
if (this.localParticipant) {
|
||||
if (!this.localParticipant) {
|
||||
this.log.e('Local participant is undefined when switching screenshare');
|
||||
return;
|
||||
}
|
||||
|
||||
// Chrome / Safari: seamless replaceTrack keeps the same publication SID.
|
||||
const options = this.getScreenCaptureOptions();
|
||||
const [newTrack] = await this.localParticipant.createScreenTracks(options);
|
||||
if (newTrack) {
|
||||
newTrack?.addListener('ended', async () => {
|
||||
newTrack.addListener('ended', async () => {
|
||||
this.log.d('Clicked native stop button. Stopping screen sharing');
|
||||
await this.setScreenShareEnabled(false);
|
||||
});
|
||||
|
||||
try {
|
||||
await this.localParticipant.switchScreenshare(newTrack);
|
||||
} catch (error) {
|
||||
newTrack.stop();
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
this.log.e('Local participant is undefined when switching screenshare');
|
||||
}
|
||||
|
||||
// this.updateLocalParticipant();
|
||||
|
|
@ -459,7 +466,6 @@ export class ParticipantService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the participant with the given identity.
|
||||
* @param identity
|
||||
|
|
|
|||
Loading…
Reference in New Issue