mirror of https://github.com/OpenVidu/openvidu.git
Merge pull request #550 from OpenVidu/ov_browser/platform
openvidu-browser: Wrapped platform librarypull/553/head
commit
6c49f8463b
|
@ -17,8 +17,8 @@
|
|||
|
||||
import { Stream } from './Stream';
|
||||
import { LocalRecorderState } from '../OpenViduInternal/Enums/LocalRecorderState';
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,11 @@ declare var MediaRecorder: any;
|
|||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
|
||||
/**
|
||||
* Easy recording of [[Stream]] objects straightaway from the browser. Initialized with [[OpenVidu.initLocalRecorder]] method
|
||||
|
@ -211,7 +216,7 @@ export class LocalRecorder {
|
|||
this.videoPreview.id = this.id;
|
||||
this.videoPreview.autoplay = true;
|
||||
|
||||
if (platform.name === 'Safari') {
|
||||
if (platform.isSafariBrowser()) {
|
||||
this.videoPreview.setAttribute('playsinline', 'true');
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import { CustomMediaStreamConstraints } from '../OpenViduInternal/Interfaces/Pri
|
|||
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
|
||||
|
||||
import * as screenSharingAuto from '../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto';
|
||||
import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturing';
|
||||
|
@ -39,13 +40,6 @@ import EventEmitter = require('wolfy87-eventemitter');
|
|||
* @hidden
|
||||
*/
|
||||
import RpcBuilder = require('../OpenViduInternal/KurentoUtils/kurento-jsonrpc');
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
import platform = require('platform');
|
||||
|
||||
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua!!.indexOf('Safari') === -1;
|
||||
platform['isIonicAndroid'] = platform.os!!.family === 'Android' && platform.name == "Android Browser";
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
|
@ -60,6 +54,11 @@ declare var cordova: any;
|
|||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
/**
|
||||
* Entrypoint of OpenVidu Browser library.
|
||||
* Use it to initialize objects of type [[Session]], [[Publisher]] and [[LocalRecorder]]
|
||||
|
@ -122,7 +121,7 @@ export class OpenVidu {
|
|||
logger.info("'OpenVidu' initialized");
|
||||
logger.info("openvidu-browser version: " + this.libraryVersion);
|
||||
|
||||
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
|
||||
if (platform.isMobileDevice()) {
|
||||
// Listen to orientationchange only on mobile devices
|
||||
(<any>window).addEventListener('orientationchange', () => {
|
||||
this.publishers.forEach(publisher => {
|
||||
|
@ -135,7 +134,7 @@ export class OpenVidu {
|
|||
|
||||
const getNewVideoDimensions = (): Promise<{ newWidth: number, newHeight: number }> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (platform['isIonicIos']) {
|
||||
if (platform.isIonicIos()) {
|
||||
// iOS Ionic. Limitation: must get new dimensions from an existing video element already inserted into DOM
|
||||
resolve({
|
||||
newWidth: publisher.stream.streamManager.videos[0].video.videoWidth,
|
||||
|
@ -146,8 +145,8 @@ export class OpenVidu {
|
|||
// New resolution got from different places for Chrome and Firefox. Chrome needs a videoWidth and videoHeight of a videoElement.
|
||||
// Firefox needs getSettings from the videoTrack
|
||||
const firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings();
|
||||
const newWidth = <number>((platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth);
|
||||
const newHeight = <number>((platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight);
|
||||
const newWidth = <number>((platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) ? firefoxSettings.width : publisher.videoReference.videoWidth);
|
||||
const newHeight = <number>((platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) ? firefoxSettings.height : publisher.videoReference.videoHeight);
|
||||
resolve({ newWidth, newHeight });
|
||||
}
|
||||
});
|
||||
|
@ -336,8 +335,8 @@ export class OpenVidu {
|
|||
*/
|
||||
checkSystemRequirements(): number {
|
||||
|
||||
if (this.isIPhoneOrIPad()) {
|
||||
if (this.isIOSWithSafari() || platform['isIonicIos']) {
|
||||
if (platform.isIPhoneOrIPad()) {
|
||||
if (platform.isIOSWithSafari() || platform.isIonicIos()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -345,10 +344,10 @@ export class OpenVidu {
|
|||
|
||||
// Accept: Chrome (desktop and Android), Firefox (desktop and Android), Opera (desktop and Android),
|
||||
// Safari (OSX and iOS), Ionic (Android and iOS), Samsung Internet Browser (Android)
|
||||
if (this.isSafariBrowser() || this.isChromeBrowser() || this.isChromeMobileBrowser() ||
|
||||
this.isFirefoxBrowser() || this.isFirefoxMobileBrowser() || this.isOperaBrowser() ||
|
||||
this.isOperaMobileBrowser() || this.isAndroidBrowser() || this.isElectron() ||
|
||||
this.isSamsungBrowser()
|
||||
if (platform.isSafariBrowser() || platform.isChromeBrowser() || platform.isChromeMobileBrowser() ||
|
||||
platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser() || platform.isOperaBrowser() ||
|
||||
platform.isOperaMobileBrowser() || platform.isAndroidBrowser() || platform.isElectron() ||
|
||||
platform.isSamsungBrowser()
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -362,22 +361,8 @@ export class OpenVidu {
|
|||
* Checks if the browser supports screen-sharing. Desktop Chrome, Firefox and Opera support screen-sharing
|
||||
* @returns 1 if the browser supports screen-sharing, 0 otherwise
|
||||
*/
|
||||
checkScreenSharingCapabilities(): number {
|
||||
const browser = platform.name;
|
||||
const version = platform?.version ? parseFloat(platform.version) : -1;
|
||||
const family = platform.os!!.family;
|
||||
|
||||
// Reject mobile devices
|
||||
if (family === 'iOS' || family === 'Android') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera') && (browser !== 'Electron') &&
|
||||
(browser === 'Safari' && version < 13)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
checkScreenSharingCapabilities(): boolean {
|
||||
return platform.canScreenShare();
|
||||
}
|
||||
|
||||
|
||||
|
@ -390,7 +375,7 @@ export class OpenVidu {
|
|||
const devices: Device[] = [];
|
||||
|
||||
// Ionic Android devices
|
||||
if (platform['isIonicAndroid'] && typeof cordova != "undefined" && cordova?.plugins?.EnumerateDevicesPlugin) {
|
||||
if (platform.isIonicAndroid() && typeof cordova != "undefined" && cordova?.plugins?.EnumerateDevicesPlugin) {
|
||||
cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then((pluginDevices: Device[]) => {
|
||||
let pluginAudioDevices: Device[] = [];
|
||||
let videoDevices: Device[] = [];
|
||||
|
@ -582,10 +567,10 @@ export class OpenVidu {
|
|||
// Video is deviceId or screen sharing
|
||||
if (options.videoSource === 'screen' ||
|
||||
options.videoSource === 'window' ||
|
||||
(platform.name === 'Electron' && options.videoSource.startsWith('screen:'))) {
|
||||
(platform.isElectron() && options.videoSource.startsWith('screen:'))) {
|
||||
// Video is screen sharing
|
||||
mustAskForAudioTrackLater = !myConstraints.audioTrack && (options.audioSource !== null && options.audioSource !== false);
|
||||
if (navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') {
|
||||
if (navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron()) {
|
||||
// getDisplayMedia supported
|
||||
navigator.mediaDevices['getDisplayMedia']({ video: true })
|
||||
.then(mediaStream => {
|
||||
|
@ -872,98 +857,6 @@ export class OpenVidu {
|
|||
return mediaStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isChromeBrowser(): boolean {
|
||||
return platform.name === 'Chrome';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isSafariBrowser(): boolean {
|
||||
return platform.name === 'Safari';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isChromeMobileBrowser(): boolean {
|
||||
return platform.name === 'Chrome Mobile';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isFirefoxBrowser(): boolean {
|
||||
return platform.name === 'Firefox';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isFirefoxMobileBrowser(): boolean {
|
||||
return platform.name === 'Firefox Mobile';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isOperaBrowser(): boolean {
|
||||
return platform.name === 'Opera';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isOperaMobileBrowser(): boolean {
|
||||
return platform.name === 'Opera Mobile';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isAndroidBrowser(): boolean {
|
||||
return platform.name === 'Android Browser';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isElectron(): boolean {
|
||||
return platform.name === 'Electron';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isSamsungBrowser(): boolean {
|
||||
return platform.name === 'Samsung Internet Mobile' || platform.name === 'Samsung Internet';
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isIPhoneOrIPad(): boolean {
|
||||
const userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
|
||||
|
||||
const isTouchable = 'ontouchend' in document;
|
||||
const isIPad = /\b(\w*Macintosh\w*)\b/.test(userAgent) && isTouchable;
|
||||
const isIPhone = /\b(\w*iPhone\w*)\b/.test(userAgent) && /\b(\w*Mobile\w*)\b/.test(userAgent) && isTouchable;
|
||||
|
||||
return isIPad || isIPhone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isIOSWithSafari(): boolean {
|
||||
const userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
|
||||
return /\b(\w*Apple\w*)\b/.test(navigator.vendor) && /\b(\w*Safari\w*)\b/.test(userAgent)
|
||||
&& !/\b(\w*CriOS\w*)\b/.test(userAgent) && !/\b(\w*FxiOS\w*)\b/.test(userAgent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
@ -984,12 +877,12 @@ export class OpenVidu {
|
|||
// Screen sharing
|
||||
|
||||
if (!this.checkScreenSharingCapabilities()) {
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera, Safari (>=13.0) or Electron. Detected client: ' + platform.name);
|
||||
const error = new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera, Safari (>=13.0) or Electron. Detected client: ' + platform.getName());
|
||||
logger.error(error);
|
||||
reject(error);
|
||||
} else {
|
||||
|
||||
if (platform.name === 'Electron') {
|
||||
if (platform.isElectron()) {
|
||||
const prefix = "screen:";
|
||||
const videoSourceString: string = videoSource;
|
||||
const electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length);
|
||||
|
@ -1003,7 +896,7 @@ export class OpenVidu {
|
|||
|
||||
} else {
|
||||
|
||||
if (!!this.advancedConfiguration.screenShareChromeExtension && !(platform.name!.indexOf('Firefox') !== -1) && !navigator.mediaDevices['getDisplayMedia']) {
|
||||
if (!!this.advancedConfiguration.screenShareChromeExtension && !(platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) && !navigator.mediaDevices['getDisplayMedia']) {
|
||||
|
||||
// Custom screen sharing extension for Chrome (and Opera) and no support for MediaDevices.getDisplayMedia()
|
||||
|
||||
|
@ -1042,7 +935,7 @@ export class OpenVidu {
|
|||
resolve(myConstraints);
|
||||
} else {
|
||||
// Default screen sharing extension for Chrome/Opera, or is Firefox < 66
|
||||
const firefoxString = platform.name!.indexOf('Firefox') !== -1 ? publisherProperties.videoSource : undefined;
|
||||
const firefoxString = (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) ? publisherProperties.videoSource : undefined;
|
||||
|
||||
screenSharingAuto.getScreenId(firefoxString, (error, sourceId, screenConstraints) => {
|
||||
if (!!error) {
|
||||
|
@ -1150,7 +1043,7 @@ export class OpenVidu {
|
|||
private isScreenShare(videoSource: string) {
|
||||
return videoSource === 'screen' ||
|
||||
videoSource === 'window' ||
|
||||
(platform.name === 'Electron' && videoSource.startsWith('screen:'))
|
||||
(platform.isElectron() && videoSource.startsWith('screen:'))
|
||||
}
|
||||
|
||||
}
|
|
@ -27,15 +27,19 @@ import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPro
|
|||
import { VideoElementEvent } from '../OpenViduInternal/Events/VideoElementEvent';
|
||||
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
/**
|
||||
* Packs local media streams. Participants can publish it to a session. Initialized with [[OpenVidu.initPublisher]] method
|
||||
*
|
||||
|
@ -400,7 +404,7 @@ export class Publisher extends StreamManager {
|
|||
if (this.stream.isSendVideo()) {
|
||||
if (!this.stream.isSendScreen()) {
|
||||
|
||||
if (platform['isIonicIos'] || platform.name === 'Safari') {
|
||||
if (platform.isIonicIos() || platform.isSafariBrowser()) {
|
||||
// iOS Ionic or Safari. Limitation: cannot set videoDimensions directly, as the videoReference is not loaded
|
||||
// if not added to DOM. Must add it to DOM and wait for videoWidth and videoHeight properties to be defined
|
||||
|
||||
|
@ -436,7 +440,7 @@ export class Publisher extends StreamManager {
|
|||
// Orientation must be checked for mobile devices (width and height are reversed)
|
||||
const { width, height } = this.getVideoDimensions(mediaStream);
|
||||
|
||||
if ((platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') && (window.innerHeight > window.innerWidth)) {
|
||||
if (platform.isMobileDevice() && (window.innerHeight > window.innerWidth)) {
|
||||
// Mobile portrait mode
|
||||
this.stream.videoDimensions = {
|
||||
width: height || 0,
|
||||
|
@ -460,8 +464,8 @@ export class Publisher extends StreamManager {
|
|||
};
|
||||
this.screenShareResizeInterval = setInterval(() => {
|
||||
const firefoxSettings = mediaStream.getVideoTracks()[0].getSettings();
|
||||
const newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? this.videoReference.videoWidth : firefoxSettings.width;
|
||||
const newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? this.videoReference.videoHeight : firefoxSettings.height;
|
||||
const newWidth = (platform.isChromeBrowser() || platform.isOperaBrowser()) ? this.videoReference.videoWidth : firefoxSettings.width;
|
||||
const newHeight = (platform.isChromeBrowser() || platform.isOperaBrowser()) ? this.videoReference.videoHeight : firefoxSettings.height;
|
||||
if (this.stream.isLocalStreamPublished &&
|
||||
(newWidth !== this.stream.videoDimensions.width ||
|
||||
newHeight !== this.stream.videoDimensions.height)) {
|
||||
|
@ -631,7 +635,7 @@ export class Publisher extends StreamManager {
|
|||
startTime = Date.now();
|
||||
this.setPermissionDialogTimer(timeForDialogEvent);
|
||||
|
||||
if (this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && platform.name !== 'Electron') {
|
||||
if (this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron()) {
|
||||
navigator.mediaDevices['getDisplayMedia']({ video: true })
|
||||
.then(mediaStream => {
|
||||
this.openvidu.addAlreadyProvidedTracks(myConstraints, mediaStream);
|
||||
|
@ -680,7 +684,7 @@ export class Publisher extends StreamManager {
|
|||
initializeVideoReference(mediaStream: MediaStream) {
|
||||
this.videoReference = document.createElement('video');
|
||||
|
||||
if (platform.name === 'Safari') {
|
||||
if (platform.isSafariBrowser()) {
|
||||
this.videoReference.setAttribute('playsinline', 'true');
|
||||
}
|
||||
|
||||
|
|
|
@ -40,15 +40,19 @@ import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPro
|
|||
import { NetworkQualityLevelChangedEvent } from '../OpenViduInternal/Events/NetworkQualityLevelChangedEvent';
|
||||
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
/**
|
||||
* Represents a video call. It can also be seen as a videoconference room where multiple users can connect.
|
||||
* Participants who publish their videos to a session can be seen by the rest of users connected to that specific session.
|
||||
|
@ -193,7 +197,7 @@ export class Session extends EventDispatcher {
|
|||
reject(error);
|
||||
});
|
||||
} else {
|
||||
reject(new OpenViduError(OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os!!.family + ' is not supported in OpenVidu'));
|
||||
reject(new OpenViduError(OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.getName() + ' (version ' + platform.getVersion() + ') for ' + platform.getFamily() + ' is not supported in OpenVidu'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1122,7 +1126,7 @@ export class Session extends EventDispatcher {
|
|||
const joinParams = {
|
||||
token: (!!token) ? token : '',
|
||||
session: this.sessionId,
|
||||
platform: !!platform.description ? platform.description : 'unknown',
|
||||
platform: !!platform.getDescription() ? platform.getDescription() : 'unknown',
|
||||
metadata: !!this.options.metadata ? this.options.metadata : '',
|
||||
secret: this.openvidu.getSecret(),
|
||||
recorder: this.openvidu.getRecorder()
|
||||
|
@ -1132,10 +1136,10 @@ export class Session extends EventDispatcher {
|
|||
|
||||
sendVideoData(streamManager: StreamManager, intervalSeconds: number = 1) {
|
||||
if(
|
||||
this.openvidu.isChromeBrowser() || this.openvidu.isChromeMobileBrowser() || this.openvidu.isOperaBrowser() ||
|
||||
this.openvidu.isOperaMobileBrowser() || this.openvidu.isElectron() || this.openvidu.isSafariBrowser() ||
|
||||
this.openvidu.isAndroidBrowser() || this.openvidu.isSamsungBrowser() ||
|
||||
(this.openvidu.isIPhoneOrIPad() && this.openvidu.isIOSWithSafari())
|
||||
platform.isChromeBrowser() || platform.isChromeMobileBrowser() || platform.isOperaBrowser() ||
|
||||
platform.isOperaMobileBrowser() || platform.isElectron() || platform.isSafariBrowser() ||
|
||||
platform.isAndroidBrowser() || platform.isSamsungBrowser() ||
|
||||
(platform.isIPhoneOrIPad() && platform.isIOSWithSafari())
|
||||
) {
|
||||
setTimeout(async () => {
|
||||
const statsMap = await streamManager.stream.getWebRtcPeer().pc.getStats();
|
||||
|
@ -1154,7 +1158,7 @@ export class Session extends EventDispatcher {
|
|||
}
|
||||
});
|
||||
}, intervalSeconds * 1000);
|
||||
} else if (this.openvidu.isFirefoxBrowser() || this.openvidu.isFirefoxMobileBrowser()) {
|
||||
} else if (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) {
|
||||
// Basic version for Firefox. It does not support stats
|
||||
this.openvidu.sendRequest('videoData', {
|
||||
height: streamManager.stream.videoDimensions.height,
|
||||
|
@ -1167,7 +1171,7 @@ export class Session extends EventDispatcher {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
console.error('Browser ' + platform.name + ' (version ' + platform.version + ') for ' + platform.os!!.family + ' is not supported in OpenVidu for Network Quality');
|
||||
logger.error('Browser ' + platform.getName() + ' (version ' + platform.getVersion() + ') for ' + platform.getFamily() + ' is not supported in OpenVidu for Network Quality');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,19 +30,22 @@ import { PublisherSpeakingEvent } from '../OpenViduInternal/Events/PublisherSpea
|
|||
import { StreamManagerEvent } from '../OpenViduInternal/Events/StreamManagerEvent';
|
||||
import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPropertyChangedEvent';
|
||||
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
import hark = require('hark');
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
/**
|
||||
* Represents each one of the media streams available in OpenVidu Server for certain session.
|
||||
|
@ -108,7 +111,7 @@ export class Stream extends EventDispatcher {
|
|||
* - `"SCREEN"`: when the video source comes from screen-sharing.
|
||||
* - `"CUSTOM"`: when [[PublisherProperties.videoSource]] has been initialized in the Publisher side with a custom MediaStreamTrack when calling [[OpenVidu.initPublisher]]).
|
||||
* - `"IPCAM"`: when the video source comes from an IP camera participant instead of a regular participant (see [IP cameras](/en/stable/advanced-features/ip-cameras/)).
|
||||
*
|
||||
*
|
||||
* If [[hasVideo]] is false, this property is undefined
|
||||
*/
|
||||
typeOfVideo?: string;
|
||||
|
@ -537,7 +540,7 @@ export class Stream extends EventDispatcher {
|
|||
*/
|
||||
isSendScreen(): boolean {
|
||||
let screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen';
|
||||
if (platform.name === 'Electron') {
|
||||
if (platform.isElectron()) {
|
||||
screen = typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' &&
|
||||
this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:');
|
||||
}
|
||||
|
|
|
@ -22,14 +22,19 @@ import { Event } from '../OpenViduInternal/Events/Event';
|
|||
import { StreamManagerEvent } from '../OpenViduInternal/Events/StreamManagerEvent';
|
||||
import { VideoElementEvent } from '../OpenViduInternal/Events/VideoElementEvent';
|
||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
/**
|
||||
* Interface in charge of displaying the media streams in the HTML DOM. This wraps any [[Publisher]] and [[Subscriber]] object.
|
||||
* You can insert as many video players fo the same Stream as you want by calling [[StreamManager.addVideoElement]] or
|
||||
|
@ -121,7 +126,7 @@ export class StreamManager extends EventDispatcher {
|
|||
id: '',
|
||||
canplayListenerAdded: false
|
||||
};
|
||||
if (platform.name === 'Safari') {
|
||||
if (platform.isSafariBrowser()) {
|
||||
this.firstVideoElement.video.setAttribute('playsinline', 'true');
|
||||
}
|
||||
this.targetElement = targEl;
|
||||
|
@ -379,7 +384,7 @@ export class StreamManager extends EventDispatcher {
|
|||
video.autoplay = true;
|
||||
video.controls = false;
|
||||
|
||||
if (platform.name === 'Safari') {
|
||||
if (platform.isSafariBrowser()) {
|
||||
video.setAttribute('playsinline', 'true');
|
||||
}
|
||||
|
||||
|
@ -463,7 +468,7 @@ export class StreamManager extends EventDispatcher {
|
|||
updateMediaStream(mediaStream: MediaStream) {
|
||||
this.videos.forEach(streamManagerVideo => {
|
||||
streamManagerVideo.video.srcObject = mediaStream;
|
||||
if (platform['isIonicIos']) {
|
||||
if (platform.isIonicIos()) {
|
||||
// iOS Ionic. LIMITATION: must reinsert the video in the DOM for
|
||||
// the media stream to be updated
|
||||
const vParent = streamManagerVideo.video.parentElement;
|
||||
|
@ -506,7 +511,7 @@ export class StreamManager extends EventDispatcher {
|
|||
}
|
||||
|
||||
private mirrorVideo(video): void {
|
||||
if (!platform['isIonicIos']) {
|
||||
if (!platform.isIonicIos()) {
|
||||
video.style.transform = 'rotateY(180deg)';
|
||||
video.style.webkitTransform = 'rotateY(180deg)';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
import platform = require("platform");
|
||||
|
||||
export class PlatformUtils {
|
||||
private static instance: PlatformUtils;
|
||||
private constructor() {}
|
||||
|
||||
static getInstance(): PlatformUtils {
|
||||
if (!PlatformUtils.instance) {
|
||||
PlatformUtils.instance = new PlatformUtils();
|
||||
}
|
||||
return PlatformUtils.instance;
|
||||
}
|
||||
|
||||
public isChromeBrowser(): boolean {
|
||||
return platform.name === "Chrome";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isSafariBrowser(): boolean {
|
||||
return platform.name === "Safari";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isChromeMobileBrowser(): boolean {
|
||||
return platform.name === "Chrome Mobile";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isFirefoxBrowser(): boolean {
|
||||
return platform.name === "Firefox";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isFirefoxMobileBrowser(): boolean {
|
||||
return platform.name === "Firefox Mobile";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isOperaBrowser(): boolean {
|
||||
return platform.name === "Opera";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isOperaMobileBrowser(): boolean {
|
||||
return platform.name === "Opera Mobile";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isAndroidBrowser(): boolean {
|
||||
return platform.name === "Android Browser";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isElectron(): boolean {
|
||||
return platform.name === "Electron";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isSamsungBrowser(): boolean {
|
||||
return (
|
||||
platform.name === "Samsung Internet Mobile" ||
|
||||
platform.name === "Samsung Internet"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isIPhoneOrIPad(): boolean {
|
||||
const userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
|
||||
|
||||
const isTouchable = "ontouchend" in document;
|
||||
const isIPad = /\b(\w*Macintosh\w*)\b/.test(userAgent) && isTouchable;
|
||||
const isIPhone =
|
||||
/\b(\w*iPhone\w*)\b/.test(userAgent) &&
|
||||
/\b(\w*Mobile\w*)\b/.test(userAgent) &&
|
||||
isTouchable;
|
||||
|
||||
return isIPad || isIPhone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isIOSWithSafari(): boolean {
|
||||
const userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
|
||||
return (
|
||||
/\b(\w*Apple\w*)\b/.test(navigator.vendor) &&
|
||||
/\b(\w*Safari\w*)\b/.test(userAgent) &&
|
||||
!/\b(\w*CriOS\w*)\b/.test(userAgent) &&
|
||||
!/\b(\w*FxiOS\w*)\b/.test(userAgent)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isIonicIos(): boolean {
|
||||
return this.isIPhoneOrIPad() && platform.ua!!.indexOf("Safari") === -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isIonicAndroid(): boolean {
|
||||
return (
|
||||
platform.os!!.family === "Android" && platform.name == "Android Browser"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public isMobileDevice(): boolean {
|
||||
return platform.os!!.family === "iOS" || platform.os!!.family === "Android";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public canScreenShare(): boolean {
|
||||
const version = platform?.version ? parseFloat(platform.version) : -1;
|
||||
|
||||
// Reject mobile devices
|
||||
if (this.isMobileDevice()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
this.isChromeBrowser() ||
|
||||
this.isFirefoxBrowser() ||
|
||||
this.isOperaBrowser() ||
|
||||
this.isElectron() ||
|
||||
(this.isSafariBrowser() && version >= 13)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public getName(): string {
|
||||
return platform.name || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public getVersion(): string {
|
||||
return platform.version || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public getFamily(): string {
|
||||
return platform.os!!.family || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public getDescription(): string {
|
||||
return platform.description || "";
|
||||
}
|
||||
}
|
|
@ -17,12 +17,17 @@
|
|||
|
||||
import freeice = require('freeice');
|
||||
import uuid = require('uuid');
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../Utils/Platform';
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
|
||||
export interface WebRtcPeerConfiguration {
|
||||
|
@ -139,7 +144,7 @@ export class WebRtcPeer {
|
|||
|
||||
logger.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints));
|
||||
|
||||
if (platform.name === 'Safari' && platform.ua!!.indexOf('Safari') !== -1) {
|
||||
if (platform.isSafariBrowser() && !platform.isIonicIos()) {
|
||||
// Safari (excluding Ionic), at least on iOS just seems to support unified plan, whereas in other browsers is not yet ready and considered experimental
|
||||
if (offerAudio) {
|
||||
this.pc.addTransceiver('audio', {
|
||||
|
@ -217,7 +222,7 @@ export class WebRtcPeer {
|
|||
* @hidden
|
||||
*/
|
||||
setRemoteDescription(answer: RTCSessionDescriptionInit, needsTimeoutOnProcessAnswer: boolean, resolve: (value?: string | PromiseLike<string> | undefined) => void, reject: (reason?: any) => void) {
|
||||
if (platform['isIonicIos']) {
|
||||
if (platform.isIonicIos()) {
|
||||
// Ionic iOS platform
|
||||
if (needsTimeoutOnProcessAnswer) {
|
||||
// 400 ms have not elapsed yet since first remote stream triggered Stream#initWebRtcPeerReceive
|
||||
|
|
|
@ -18,13 +18,16 @@
|
|||
// tslint:disable:no-string-literal
|
||||
|
||||
import { Stream } from '../../OpenVidu/Stream';
|
||||
import platform = require('platform');
|
||||
import { OpenViduLogger } from '../Logger/OpenViduLogger';
|
||||
import { PlatformUtils } from '../Utils/Platform';
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
const platform: PlatformUtils = PlatformUtils.getInstance();
|
||||
|
||||
export class WebRtcStats {
|
||||
|
||||
|
@ -103,7 +106,7 @@ export class WebRtcStats {
|
|||
return new Promise((resolve, reject) => {
|
||||
this.getStatsAgnostic(this.stream.getRTCPeerConnection(),
|
||||
(stats) => {
|
||||
if ((platform.name!.indexOf('Chrome') !== -1) || (platform.name!.indexOf('Opera') !== -1)) {
|
||||
if (platform.isChromeBrowser() || platform.isChromeMobileBrowser() || platform.isOperaBrowser() || platform.isOperaMobileBrowser()) {
|
||||
let localCandidateId, remoteCandidateId, googCandidatePair;
|
||||
const localCandidates = {};
|
||||
const remoteCandidates = {};
|
||||
|
@ -181,7 +184,7 @@ export class WebRtcStats {
|
|||
|
||||
const f = (stats) => {
|
||||
|
||||
if (platform.name!.indexOf('Firefox') !== -1) {
|
||||
if (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) {
|
||||
stats.forEach((stat) => {
|
||||
|
||||
let json = {};
|
||||
|
@ -278,7 +281,7 @@ export class WebRtcStats {
|
|||
sendPost(JSON.stringify(json));
|
||||
}
|
||||
});
|
||||
} else if ((platform.name!.indexOf('Chrome') !== -1) || (platform.name!.indexOf('Opera') !== -1)) {
|
||||
} else if (platform.isChromeBrowser() || platform.isChromeMobileBrowser() || platform.isOperaBrowser() || platform.isOperaMobileBrowser()) {
|
||||
for (const key of Object.keys(stats)) {
|
||||
const stat = stats[key];
|
||||
if (stat.type === 'ssrc') {
|
||||
|
@ -377,7 +380,7 @@ export class WebRtcStats {
|
|||
logger.log(response);
|
||||
const standardReport = {};
|
||||
|
||||
if (platform.name!.indexOf('Firefox') !== -1) {
|
||||
if (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) {
|
||||
Object.keys(response).forEach(key => {
|
||||
logger.log(response[key]);
|
||||
});
|
||||
|
@ -400,13 +403,13 @@ export class WebRtcStats {
|
|||
}
|
||||
|
||||
private getStatsAgnostic(pc, successCb, failureCb) {
|
||||
if (platform.name!.indexOf('Firefox') !== -1) {
|
||||
if (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) {
|
||||
// getStats takes args in different order in Chrome and Firefox
|
||||
return pc.getStats(null).then(response => {
|
||||
const report = this.standardizeReport(response);
|
||||
successCb(report);
|
||||
}).catch(failureCb);
|
||||
} else if ((platform.name!.indexOf('Chrome') !== -1) || (platform.name!.indexOf('Opera') !== -1)) {
|
||||
} else if (platform.isChromeBrowser() || platform.isChromeMobileBrowser() || platform.isOperaBrowser() || platform.isOperaMobileBrowser()) {
|
||||
// In Chrome, the first two arguments are reversed
|
||||
return pc.getStats((response) => {
|
||||
const report = this.standardizeReport(response);
|
||||
|
|
Loading…
Reference in New Issue