diff --git a/openvidu-browser/src/OpenVidu/LocalRecorder.ts b/openvidu-browser/src/OpenVidu/LocalRecorder.ts index 7e384670..1d8a2eef 100644 --- a/openvidu-browser/src/OpenVidu/LocalRecorder.ts +++ b/openvidu-browser/src/OpenVidu/LocalRecorder.ts @@ -202,6 +202,10 @@ export class LocalRecorder { this.videoPreview.id = this.id; this.videoPreview.autoplay = true; + if (platform.name === 'Safari' && platform.product === 'iPhone') { + this.videoPreview.setAttribute('playsinline', 'true'); + } + if (typeof parentElement === 'string') { this.htmlParentElementId = parentElement; diff --git a/openvidu-browser/src/OpenVidu/OpenVidu.ts b/openvidu-browser/src/OpenVidu/OpenVidu.ts index 4a10ee17..d1d08a5c 100644 --- a/openvidu-browser/src/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/src/OpenVidu/OpenVidu.ts @@ -77,7 +77,7 @@ export class OpenVidu { constructor() { console.info("'OpenVidu' initialized"); - if (platform.name!!.toLowerCase().indexOf('mobile') !== -1) { + if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') { // Listen to orientationchange only on mobile browsers (window).onorientationchange = () => { this.publishers.forEach(publisher => { @@ -484,7 +484,7 @@ export class OpenVidu { (platform.name!.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window')) { if (platform.name !== 'Chrome' && platform.name!.indexOf('Firefox') === -1 && platform.name !== 'Opera') { - const error = new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome and Firefox. Detected browser: ' + platform.name); + const error = new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name); console.error(error); reject(error); } else { diff --git a/openvidu-browser/src/OpenVidu/Publisher.ts b/openvidu-browser/src/OpenVidu/Publisher.ts index 283da9c4..022cbb17 100644 --- a/openvidu-browser/src/OpenVidu/Publisher.ts +++ b/openvidu-browser/src/OpenVidu/Publisher.ts @@ -292,6 +292,11 @@ export class Publisher extends StreamManager { } this.videoReference = document.createElement('video'); + + if (platform.name === 'Safari' && platform.product === 'iPhone') { + this.videoReference.setAttribute('playsinline', 'true'); + } + this.videoReference.srcObject = mediaStream; this.stream.setMediaStream(mediaStream); diff --git a/openvidu-browser/src/OpenVidu/StreamManager.ts b/openvidu-browser/src/OpenVidu/StreamManager.ts index 15b6cadd..9936f8c7 100644 --- a/openvidu-browser/src/OpenVidu/StreamManager.ts +++ b/openvidu-browser/src/OpenVidu/StreamManager.ts @@ -112,6 +112,9 @@ export class StreamManager implements EventDispatcher { video: document.createElement('video'), id: '' }; + if (platform.name === 'Safari' && platform.product === 'iPhone') { + this.firstVideoElement.video.setAttribute('playsinline', 'true'); + } this.targetElement = targEl; this.element = targEl; } @@ -329,6 +332,11 @@ export class StreamManager implements EventDispatcher { } video.autoplay = true; video.controls = false; + + if (platform.name === 'Safari' && platform.product === 'iPhone') { + video.setAttribute('playsinline', 'true'); + } + if (!video.id) { video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; // DEPRECATED property: assign once the property id if the user provided a valid targetElement diff --git a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts index 03806920..a1d9e3e8 100644 --- a/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts +++ b/openvidu-browser/src/OpenViduInternal/WebRtcPeer/WebRtcPeer.ts @@ -29,7 +29,7 @@ export interface WebRtcPeerConfiguration { onicecandidate: (event) => void; iceServers: RTCIceServer[] | undefined; mediaStream?: MediaStream; - mode?: string; // sendonly, reconly, sendrecv + mode?: 'sendonly' | 'recvonly' | 'sendrecv'; id?: string; } @@ -154,18 +154,52 @@ export class WebRtcPeer { console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); - this.pc.createOffer(constraints).then(offer => { - console.debug('Created SDP offer'); - return this.pc.setLocalDescription(offer); - }).then(() => { - const localDescription = this.pc.localDescription; - if (!!localDescription) { - console.debug('Local description set', localDescription.sdp); - resolve(localDescription.sdp); - } else { - reject('Local description is not defined'); + if (platform.name === 'Safari') { + // Safari, 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', { + direction: this.configuration.mode, + }); } - }).catch(error => reject(error)); + + if (offerVideo) { + this.pc.addTransceiver('video', { + direction: this.configuration.mode, + }); + } + + this.pc + .createOffer() + .then(offer => { + console.debug('Created SDP offer'); + return this.pc.setLocalDescription(offer); + }) + .then(() => { + const localDescription = this.pc.localDescription; + + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } else { + reject('Local description is not defined'); + } + }) + .catch(error => reject(error)); + } else { + this.pc.createOffer(constraints).then(offer => { + console.debug('Created SDP offer'); + return this.pc.setLocalDescription(offer); + }).then(() => { + const localDescription = this.pc.localDescription; + if (!!localDescription) { + console.debug('Local description set', localDescription.sdp); + resolve(localDescription.sdp); + } else { + reject('Local description is not defined'); + } + }) + .catch(error => reject(error)); + } }); }