mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: IE major compatibility (streamPlaying, videoDimensions)
parent
4e1a080232
commit
c8b648fef8
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"author": "OpenVidu",
|
||||
"dependencies": {
|
||||
"@types/node": "11.13.6",
|
||||
"@types/node": "12.0.0",
|
||||
"@types/platform": "1.3.2",
|
||||
"freeice": "2.2.2",
|
||||
"hark": "1.2.3",
|
||||
|
@ -24,8 +24,8 @@
|
|||
"tsify": "4.0.1",
|
||||
"tslint": "5.16.0",
|
||||
"typedoc": "0.14.2",
|
||||
"typescript": "3.4.4",
|
||||
"uglify-js": "3.5.6"
|
||||
"typescript": "3.4.5",
|
||||
"uglify-js": "3.5.11"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"main": "lib/index.js",
|
||||
|
|
|
@ -19,12 +19,15 @@ import { LocalRecorder } from './LocalRecorder';
|
|||
import { Publisher } from './Publisher';
|
||||
import { Session } from './Session';
|
||||
import { Stream } from './Stream';
|
||||
import { StreamManager } from './StreamManager';
|
||||
import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPropertyChangedEvent';
|
||||
import { Device } from '../OpenViduInternal/Interfaces/Public/Device';
|
||||
import { OpenViduAdvancedConfiguration } from '../OpenViduInternal/Interfaces/Public/OpenViduAdvancedConfiguration';
|
||||
import { PublisherProperties } from '../OpenViduInternal/Interfaces/Public/PublisherProperties';
|
||||
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
||||
import { VideoElementEvent } from '../OpenViduInternal/Events/VideoElementEvent';
|
||||
import { StreamManagerEvent } from '../OpenViduInternal/Events/StreamManagerEvent';
|
||||
|
||||
import * as screenSharingAuto from '../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto';
|
||||
import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturing';
|
||||
|
@ -109,6 +112,7 @@ export class OpenVidu {
|
|||
console.info("Detected IE Explorer " + platform.version);
|
||||
this.importIEAdapterJS();
|
||||
this.importURLLibrary();
|
||||
this.setGlobalIEFunctions();
|
||||
}
|
||||
|
||||
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
|
||||
|
@ -781,7 +785,7 @@ export class OpenVidu {
|
|||
}
|
||||
|
||||
private importURLLibrary(): void {
|
||||
const moduleSpecifier = 'https://polyfill.io/v3/polyfill.min.js?features=URL';
|
||||
const moduleSpecifier = 'https://cdn.jsdelivr.net/npm/url-polyfill@1.1.5/url-polyfill.min.js';
|
||||
const scriptId = 'url-script-element';
|
||||
var script = document.createElement('script');
|
||||
script.async = false;
|
||||
|
@ -800,4 +804,50 @@ export class OpenVidu {
|
|||
}
|
||||
}
|
||||
|
||||
private setGlobalIEFunctions(): void {
|
||||
// FIX: the IE plugin seems to require the handler functions to be globally accessible. Store the functions with unique streamId
|
||||
|
||||
// Global handler for onloadedmetadata
|
||||
(<any>window).IEOnLoadedMetadata = (simVideo: HTMLVideoElement, str: Stream) => {
|
||||
const videoDimensionsSet = () => {
|
||||
str.videoDimensions = {
|
||||
width: simVideo.videoWidth,
|
||||
height: simVideo.videoHeight
|
||||
};
|
||||
|
||||
// TODO: if screen-share, set this.screenShareResizeInterval
|
||||
|
||||
str.isLocalStreamReadyToPublish = true;
|
||||
str.ee.emitEvent('stream-ready-to-publish', []);
|
||||
};
|
||||
let interval;
|
||||
if (simVideo.videoWidth === 0) {
|
||||
interval = setInterval(() => {
|
||||
if (simVideo.videoWidth !== 0) {
|
||||
clearInterval(interval);
|
||||
videoDimensionsSet();
|
||||
}
|
||||
}, 40);
|
||||
} else {
|
||||
videoDimensionsSet();
|
||||
}
|
||||
};
|
||||
// Global handler for oncanplay
|
||||
(<any>window).IEOnCanPlay = (strManager: StreamManager) => {
|
||||
if (strManager.stream.isLocal()) {
|
||||
if (!strManager.stream.displayMyRemote()) {
|
||||
console.info("Your local 'Stream' with id [" + strManager.stream.streamId + '] video is now playing');
|
||||
strManager.ee.emitEvent('videoPlaying', [new VideoElementEvent(strManager.videos[0].video, strManager, 'videoPlaying')]);
|
||||
} else {
|
||||
console.info("Your own remote 'Stream' with id [" + strManager.stream.streamId + '] video is now playing');
|
||||
strManager.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(strManager.videos[0].video, strManager, 'remoteVideoPlaying')]);
|
||||
}
|
||||
} else {
|
||||
console.info("Remote 'Stream' with id [" + strManager.stream.streamId + '] video is now playing');
|
||||
strManager.ee.emitEvent('videoPlaying', [new VideoElementEvent(strManager.videos[0].video, strManager, 'videoPlaying')]);
|
||||
}
|
||||
strManager.ee.emitEvent('streamPlaying', [new StreamManagerEvent(strManager, 'streamPlaying', undefined)]);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -322,6 +322,16 @@ export class Publisher extends StreamManager {
|
|||
if (platform['isInternetExplorer']) {
|
||||
this.videoReference = video;
|
||||
}
|
||||
} else {
|
||||
if (platform['isInternetExplorer']) {
|
||||
// IE cannot have a video reference not inserted into DOM
|
||||
// Pick up the first video element of videos array
|
||||
this.videoReference = this.videos[0].video;
|
||||
if (!this.videoReference) {
|
||||
console.warn('IE requires the video element to be defined when initializing a Publisher. ' +
|
||||
'Be sure to initialize the publisher passing a pre-existing targetElement')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.stream.setMediaStream(mediaStream);
|
||||
|
@ -331,43 +341,15 @@ export class Publisher extends StreamManager {
|
|||
this.videoReference = this.customAttachMediaStreamIE(this.videoReference, mediaStream);
|
||||
if (this.stream.isSendVideo()) {
|
||||
if (!this.stream.isSendScreen()) {
|
||||
/*this.videoReference.onloadedmetadata = () => {
|
||||
this.stream.videoDimensions = {
|
||||
width: this.videoReference.videoWidth,
|
||||
height: this.videoReference.videoHeight
|
||||
};
|
||||
|
||||
// TODO: if screen-share, set this.screenShareResizeInterval
|
||||
|
||||
console.warn(this.stream.videoDimensions);
|
||||
this.stream.isLocalStreamReadyToPublish = true;
|
||||
this.stream.ee.emitEvent('stream-ready-to-publish', []);
|
||||
}*/
|
||||
|
||||
this.stream.videoDimensions = {
|
||||
width: this.videoReference.videoWidth,
|
||||
height: this.videoReference.videoHeight
|
||||
};
|
||||
|
||||
// TODO: if screen-share, set this.screenShareResizeInterval
|
||||
|
||||
console.warn(this.stream.videoDimensions);
|
||||
this.stream.isLocalStreamReadyToPublish = true;
|
||||
this.stream.ee.emitEvent('stream-ready-to-publish', []);
|
||||
|
||||
this.videoReference.onplaying = () => {
|
||||
console.warn("PLAYINNNGNGNGNGNGNG!!!");
|
||||
}
|
||||
|
||||
this.videoReference.addEventListener('loadedmetadata', (<any>window).IEOnLoadedMetadata(this.videoReference, this.stream));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
this.videoReference.srcObject = mediaStream;
|
||||
}
|
||||
|
||||
if (!this.stream.displayMyRemote()) {
|
||||
if (!this.stream.displayMyRemote() && (platform.name !== 'IE')) {
|
||||
// When we are subscribed to our remote we don't still set the MediaStream object in the video elements to
|
||||
// avoid early 'streamPlaying' event
|
||||
this.stream.updateMediaStreamInVideos();
|
||||
|
@ -395,18 +377,18 @@ export class Publisher extends StreamManager {
|
|||
};
|
||||
|
||||
let interval;
|
||||
this.videoReference.onloadedmetadata = () => {
|
||||
this.videoReference.addEventListener('loadedmetadata', () => {
|
||||
if (this.videoReference.videoWidth === 0) {
|
||||
interval = setInterval(() => {
|
||||
if (this.videoReference.videoWidth !== 0) {
|
||||
videoDimensionsSet();
|
||||
clearInterval(interval);
|
||||
videoDimensionsSet();
|
||||
}
|
||||
}, 10);
|
||||
}, 40);
|
||||
} else {
|
||||
videoDimensionsSet();
|
||||
}
|
||||
};
|
||||
});
|
||||
} else if (platform.name !== 'IE') {
|
||||
// Rest of platforms except IE
|
||||
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
|
||||
|
@ -430,7 +412,7 @@ export class Publisher extends StreamManager {
|
|||
}
|
||||
} else {
|
||||
// With screen share, video dimension must be got from a video element (onloadedmetadata event)
|
||||
this.videoReference.onloadedmetadata = () => {
|
||||
this.videoReference.addEventListener('loadedmetadata', () => {
|
||||
this.stream.videoDimensions = {
|
||||
width: this.videoReference.videoWidth,
|
||||
height: this.videoReference.videoHeight
|
||||
|
@ -467,7 +449,7 @@ export class Publisher extends StreamManager {
|
|||
}, 500);
|
||||
this.stream.isLocalStreamReadyToPublish = true;
|
||||
this.stream.ee.emitEvent('stream-ready-to-publish', []);
|
||||
};
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.stream.isLocalStreamReadyToPublish = true;
|
||||
|
|
|
@ -87,11 +87,11 @@ export class StreamManager implements EventDispatcher {
|
|||
/**
|
||||
* @hidden
|
||||
*/
|
||||
protected ee = new EventEmitter();
|
||||
ee = new EventEmitter();
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
protected canPlayListener: EventListenerOrEventListenerObject;
|
||||
protected canPlayListener: EventListener;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -123,21 +123,23 @@ export class StreamManager implements EventDispatcher {
|
|||
this.element = targEl;
|
||||
}
|
||||
}
|
||||
this.canPlayListener = () => {
|
||||
if (this.stream.isLocal()) {
|
||||
if (!this.stream.displayMyRemote()) {
|
||||
console.info("Your local 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||
if (!platform['isInternetExplorer']) {
|
||||
this.canPlayListener = () => {
|
||||
if (this.stream.isLocal()) {
|
||||
if (!this.stream.displayMyRemote()) {
|
||||
console.info("Your local 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||
} else {
|
||||
console.info("Your own remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||
this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]);
|
||||
}
|
||||
} else {
|
||||
console.info("Your own remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||
this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]);
|
||||
console.info("Remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||
}
|
||||
} else {
|
||||
console.info("Remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||
}
|
||||
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent(this, 'streamPlaying', undefined)]);
|
||||
};
|
||||
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent(this, 'streamPlaying', undefined)]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,7 +395,7 @@ export class StreamManager implements EventDispatcher {
|
|||
|
||||
this.videos.forEach(streamManagerVideo => {
|
||||
// Remove oncanplay event listener (only OpenVidu browser one, not the user ones)
|
||||
streamManagerVideo.video.removeEventListener('canplay', this.canPlayListener);
|
||||
streamManagerVideo.video.removeEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay : this.canPlayListener);
|
||||
if (!!streamManagerVideo.targetElement) {
|
||||
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
||||
// and Session.subscribe or those created by StreamManager.createVideoElement). All this videos triggered a videoElementCreated event
|
||||
|
@ -428,7 +430,7 @@ export class StreamManager implements EventDispatcher {
|
|||
*/
|
||||
addPlayEventToFirstVideo() {
|
||||
if ((!!this.videos[0]) && (!!this.videos[0].video) && (this.videos[0].video.oncanplay === null)) {
|
||||
this.videos[0].video.addEventListener('canplay', this.canPlayListener);
|
||||
this.videos[0].video.addEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay(this) : this.canPlayListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,6 +484,12 @@ export class StreamManager implements EventDispatcher {
|
|||
protected customAttachMediaStreamIE(video: HTMLVideoElement, mediaStream: MediaStream): HTMLVideoElement {
|
||||
var simVideo = attachMediaStream(video, mediaStream);
|
||||
|
||||
if (!simVideo) {
|
||||
console.error('The video element used by IE to insert its custom media element is not properly added to DOM (must be inserted and visible)');
|
||||
console.error(video);
|
||||
return simVideo;
|
||||
}
|
||||
|
||||
// Replace HTMLVideoElemet (if exists) with new HTMLObjectElement returned by IE plugin
|
||||
for (let i = 0; i < this.videos.length; i++) {
|
||||
if (this.videos[i].video === video) {
|
||||
|
@ -492,7 +500,6 @@ export class StreamManager implements EventDispatcher {
|
|||
|
||||
// Always launch videoElementCreated event after IE plugin has inserted simulated video into DOM
|
||||
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(simVideo, this, 'videoElementCreated')]);
|
||||
this.addPlayEventToFirstVideo();
|
||||
return simVideo;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue