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",
|
"author": "OpenVidu",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "11.13.6",
|
"@types/node": "12.0.0",
|
||||||
"@types/platform": "1.3.2",
|
"@types/platform": "1.3.2",
|
||||||
"freeice": "2.2.2",
|
"freeice": "2.2.2",
|
||||||
"hark": "1.2.3",
|
"hark": "1.2.3",
|
||||||
|
@ -24,8 +24,8 @@
|
||||||
"tsify": "4.0.1",
|
"tsify": "4.0.1",
|
||||||
"tslint": "5.16.0",
|
"tslint": "5.16.0",
|
||||||
"typedoc": "0.14.2",
|
"typedoc": "0.14.2",
|
||||||
"typescript": "3.4.4",
|
"typescript": "3.4.5",
|
||||||
"uglify-js": "3.5.6"
|
"uglify-js": "3.5.11"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
|
|
|
@ -19,12 +19,15 @@ import { LocalRecorder } from './LocalRecorder';
|
||||||
import { Publisher } from './Publisher';
|
import { Publisher } from './Publisher';
|
||||||
import { Session } from './Session';
|
import { Session } from './Session';
|
||||||
import { Stream } from './Stream';
|
import { Stream } from './Stream';
|
||||||
|
import { StreamManager } from './StreamManager';
|
||||||
import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPropertyChangedEvent';
|
import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPropertyChangedEvent';
|
||||||
import { Device } from '../OpenViduInternal/Interfaces/Public/Device';
|
import { Device } from '../OpenViduInternal/Interfaces/Public/Device';
|
||||||
import { OpenViduAdvancedConfiguration } from '../OpenViduInternal/Interfaces/Public/OpenViduAdvancedConfiguration';
|
import { OpenViduAdvancedConfiguration } from '../OpenViduInternal/Interfaces/Public/OpenViduAdvancedConfiguration';
|
||||||
import { PublisherProperties } from '../OpenViduInternal/Interfaces/Public/PublisherProperties';
|
import { PublisherProperties } from '../OpenViduInternal/Interfaces/Public/PublisherProperties';
|
||||||
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
|
||||||
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
|
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 screenSharingAuto from '../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto';
|
||||||
import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturing';
|
import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturing';
|
||||||
|
@ -109,6 +112,7 @@ export class OpenVidu {
|
||||||
console.info("Detected IE Explorer " + platform.version);
|
console.info("Detected IE Explorer " + platform.version);
|
||||||
this.importIEAdapterJS();
|
this.importIEAdapterJS();
|
||||||
this.importURLLibrary();
|
this.importURLLibrary();
|
||||||
|
this.setGlobalIEFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
|
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
|
||||||
|
@ -781,7 +785,7 @@ export class OpenVidu {
|
||||||
}
|
}
|
||||||
|
|
||||||
private importURLLibrary(): void {
|
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';
|
const scriptId = 'url-script-element';
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
script.async = false;
|
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']) {
|
if (platform['isInternetExplorer']) {
|
||||||
this.videoReference = video;
|
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);
|
this.stream.setMediaStream(mediaStream);
|
||||||
|
@ -331,43 +341,15 @@ export class Publisher extends StreamManager {
|
||||||
this.videoReference = this.customAttachMediaStreamIE(this.videoReference, mediaStream);
|
this.videoReference = this.customAttachMediaStreamIE(this.videoReference, mediaStream);
|
||||||
if (this.stream.isSendVideo()) {
|
if (this.stream.isSendVideo()) {
|
||||||
if (!this.stream.isSendScreen()) {
|
if (!this.stream.isSendScreen()) {
|
||||||
/*this.videoReference.onloadedmetadata = () => {
|
this.videoReference.addEventListener('loadedmetadata', (<any>window).IEOnLoadedMetadata(this.videoReference, this.stream));
|
||||||
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!!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.videoReference.srcObject = mediaStream;
|
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
|
// When we are subscribed to our remote we don't still set the MediaStream object in the video elements to
|
||||||
// avoid early 'streamPlaying' event
|
// avoid early 'streamPlaying' event
|
||||||
this.stream.updateMediaStreamInVideos();
|
this.stream.updateMediaStreamInVideos();
|
||||||
|
@ -395,18 +377,18 @@ export class Publisher extends StreamManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
let interval;
|
let interval;
|
||||||
this.videoReference.onloadedmetadata = () => {
|
this.videoReference.addEventListener('loadedmetadata', () => {
|
||||||
if (this.videoReference.videoWidth === 0) {
|
if (this.videoReference.videoWidth === 0) {
|
||||||
interval = setInterval(() => {
|
interval = setInterval(() => {
|
||||||
if (this.videoReference.videoWidth !== 0) {
|
if (this.videoReference.videoWidth !== 0) {
|
||||||
videoDimensionsSet();
|
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
videoDimensionsSet();
|
||||||
}
|
}
|
||||||
}, 10);
|
}, 40);
|
||||||
} else {
|
} else {
|
||||||
videoDimensionsSet();
|
videoDimensionsSet();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
} else if (platform.name !== 'IE') {
|
} else if (platform.name !== 'IE') {
|
||||||
// Rest of platforms except IE
|
// Rest of platforms except IE
|
||||||
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
|
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
|
||||||
|
@ -430,7 +412,7 @@ export class Publisher extends StreamManager {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// With screen share, video dimension must be got from a video element (onloadedmetadata event)
|
// With screen share, video dimension must be got from a video element (onloadedmetadata event)
|
||||||
this.videoReference.onloadedmetadata = () => {
|
this.videoReference.addEventListener('loadedmetadata', () => {
|
||||||
this.stream.videoDimensions = {
|
this.stream.videoDimensions = {
|
||||||
width: this.videoReference.videoWidth,
|
width: this.videoReference.videoWidth,
|
||||||
height: this.videoReference.videoHeight
|
height: this.videoReference.videoHeight
|
||||||
|
@ -467,7 +449,7 @@ export class Publisher extends StreamManager {
|
||||||
}, 500);
|
}, 500);
|
||||||
this.stream.isLocalStreamReadyToPublish = true;
|
this.stream.isLocalStreamReadyToPublish = true;
|
||||||
this.stream.ee.emitEvent('stream-ready-to-publish', []);
|
this.stream.ee.emitEvent('stream-ready-to-publish', []);
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.stream.isLocalStreamReadyToPublish = true;
|
this.stream.isLocalStreamReadyToPublish = true;
|
||||||
|
|
|
@ -87,11 +87,11 @@ export class StreamManager implements EventDispatcher {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
protected ee = new EventEmitter();
|
ee = new EventEmitter();
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
protected canPlayListener: EventListenerOrEventListenerObject;
|
protected canPlayListener: EventListener;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,21 +123,23 @@ export class StreamManager implements EventDispatcher {
|
||||||
this.element = targEl;
|
this.element = targEl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.canPlayListener = () => {
|
if (!platform['isInternetExplorer']) {
|
||||||
if (this.stream.isLocal()) {
|
this.canPlayListener = () => {
|
||||||
if (!this.stream.displayMyRemote()) {
|
if (this.stream.isLocal()) {
|
||||||
console.info("Your local 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
if (!this.stream.displayMyRemote()) {
|
||||||
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
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 {
|
} else {
|
||||||
console.info("Your own remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
console.info("Remote 'Stream' with id [" + this.stream.streamId + '] video is now playing');
|
||||||
this.ee.emitEvent('remoteVideoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'remoteVideoPlaying')]);
|
this.ee.emitEvent('videoPlaying', [new VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
|
||||||
}
|
}
|
||||||
} else {
|
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent(this, 'streamPlaying', undefined)]);
|
||||||
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)]);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -393,7 +395,7 @@ export class StreamManager implements EventDispatcher {
|
||||||
|
|
||||||
this.videos.forEach(streamManagerVideo => {
|
this.videos.forEach(streamManagerVideo => {
|
||||||
// Remove oncanplay event listener (only OpenVidu browser one, not the user ones)
|
// 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) {
|
if (!!streamManagerVideo.targetElement) {
|
||||||
// Only remove from DOM videos created by OpenVidu Browser (those generated by passing a valid targetElement in OpenVidu.initPublisher
|
// 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
|
// 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() {
|
addPlayEventToFirstVideo() {
|
||||||
if ((!!this.videos[0]) && (!!this.videos[0].video) && (this.videos[0].video.oncanplay === null)) {
|
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 {
|
protected customAttachMediaStreamIE(video: HTMLVideoElement, mediaStream: MediaStream): HTMLVideoElement {
|
||||||
var simVideo = attachMediaStream(video, mediaStream);
|
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
|
// Replace HTMLVideoElemet (if exists) with new HTMLObjectElement returned by IE plugin
|
||||||
for (let i = 0; i < this.videos.length; i++) {
|
for (let i = 0; i < this.videos.length; i++) {
|
||||||
if (this.videos[i].video === video) {
|
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
|
// Always launch videoElementCreated event after IE plugin has inserted simulated video into DOM
|
||||||
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(simVideo, this, 'videoElementCreated')]);
|
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent(simVideo, this, 'videoElementCreated')]);
|
||||||
this.addPlayEventToFirstVideo();
|
|
||||||
return simVideo;
|
return simVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue