openvidu-browser: StreamManager fix for streamPlaying event on addVideoElement/createVideoElement

pull/263/head
pabloFuente 2019-05-29 14:54:37 +02:00
parent 8c561147f2
commit 67fdfb47e7
7 changed files with 167 additions and 150 deletions

View File

@ -378,7 +378,7 @@ export class OpenVidu {
*/ */
getDevices(): Promise<Device[]> { getDevices(): Promise<Device[]> {
return new Promise<Device[]>((resolve, reject) => { return new Promise<Device[]>((resolve, reject) => {
navigator.mediaDevices.enumerateDevices().then((deviceInfos) => { navigator.mediaDevices.enumerateDevices().then(deviceInfos => {
const devices: Device[] = []; const devices: Device[] = [];
deviceInfos.forEach(deviceInfo => { deviceInfos.forEach(deviceInfo => {
if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') { if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') {

View File

@ -111,7 +111,8 @@ export class StreamManager implements EventDispatcher {
this.firstVideoElement = { this.firstVideoElement = {
targetElement: targEl, targetElement: targEl,
video: document.createElement('video'), video: document.createElement('video'),
id: '' id: '',
canplayListenerAdded: false
}; };
if (platform.name === 'Safari') { if (platform.name === 'Safari') {
this.firstVideoElement.video.setAttribute('playsinline', 'true'); this.firstVideoElement.video.setAttribute('playsinline', 'true');
@ -239,8 +240,10 @@ export class StreamManager implements EventDispatcher {
this.initializeVideoProperties(video); this.initializeVideoProperties(video);
if (this.stream.isLocal() && this.stream.displayMyRemote()) { if (this.stream.isLocal() && this.stream.displayMyRemote()) {
if (video.srcObject !== this.stream.getMediaStream()) {
video.srcObject = this.stream.getMediaStream(); video.srcObject = this.stream.getMediaStream();
} }
}
if (platform['isInternetExplorer'] && !!this.stream.getMediaStream()) { if (platform['isInternetExplorer'] && !!this.stream.getMediaStream()) {
video = this.customAttachMediaStreamIE(video, this.stream.getMediaStream()); video = this.customAttachMediaStreamIE(video, this.stream.getMediaStream());
@ -268,7 +271,8 @@ export class StreamManager implements EventDispatcher {
this.pushNewStreamManagerVideo({ this.pushNewStreamManagerVideo({
video, video,
id: video.id id: video.id,
canplayListenerAdded: false
}); });
console.info('New video element associated to ', this); console.info('New video element associated to ', this);
@ -285,6 +289,8 @@ export class StreamManager implements EventDispatcher {
* *
* @param targetElement HTML DOM element (or its `id` attribute) in which the video element of the Publisher/Subscriber will be inserted * @param targetElement HTML DOM element (or its `id` attribute) in which the video element of the Publisher/Subscriber will be inserted
* @param insertMode How the video element will be inserted accordingly to `targetElemet` * @param insertMode How the video element will be inserted accordingly to `targetElemet`
*
* @returns The created HTMLVideoElement
*/ */
createVideoElement(targetElement?: string | HTMLElement, insertMode?: VideoInsertMode): HTMLVideoElement { createVideoElement(targetElement?: string | HTMLElement, insertMode?: VideoInsertMode): HTMLVideoElement {
let targEl; let targEl;
@ -333,7 +339,8 @@ export class StreamManager implements EventDispatcher {
targetElement: targEl, targetElement: targEl,
video, video,
insertMode: insMode, insertMode: insMode,
id: video.id id: video.id,
canplayListenerAdded: false
}; };
this.pushNewStreamManagerVideo(v); this.pushNewStreamManagerVideo(v);
@ -353,8 +360,11 @@ export class StreamManager implements EventDispatcher {
initializeVideoProperties(video: HTMLVideoElement): void { initializeVideoProperties(video: HTMLVideoElement): void {
if (!(this.stream.isLocal() && this.stream.displayMyRemote())) { if (!(this.stream.isLocal() && this.stream.displayMyRemote())) {
// Avoid setting the MediaStream into the srcObject if remote subscription before publishing // Avoid setting the MediaStream into the srcObject if remote subscription before publishing
if (video.srcObject !== this.stream.getMediaStream()) {
// If srcObject already set don't do it again
video.srcObject = this.stream.getMediaStream(); video.srcObject = this.stream.getMediaStream();
} }
}
video.autoplay = true; video.autoplay = true;
video.controls = false; video.controls = false;
@ -392,8 +402,9 @@ 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 listener, not the user ones)
streamManagerVideo.video.removeEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay : this.canPlayListener); streamManagerVideo.video.removeEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay : this.canPlayListener);
streamManagerVideo.canplayListenerAdded = false;
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
@ -414,6 +425,7 @@ export class StreamManager implements EventDispatcher {
let disassociated = false; let disassociated = false;
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) {
this.videos[i].video.removeEventListener('canplay', platform['isInternetExplorer'] ? (<any>window).IEOnCanPlay : this.canPlayListener);
this.videos.splice(i, 1); this.videos.splice(i, 1);
disassociated = true; disassociated = true;
console.info('Video element disassociated from ', this); console.info('Video element disassociated from ', this);
@ -427,7 +439,7 @@ export class StreamManager implements EventDispatcher {
* @hidden * @hidden
*/ */
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].canplayListenerAdded)) {
if (platform['isInternetExplorer']) { if (platform['isInternetExplorer']) {
if (!(this.videos[0].video instanceof HTMLVideoElement)) { if (!(this.videos[0].video instanceof HTMLVideoElement)) {
// Add canplay event listener only after plugin has inserted custom video element (not a DOM HTMLVideoElement) // Add canplay event listener only after plugin has inserted custom video element (not a DOM HTMLVideoElement)
@ -436,6 +448,7 @@ export class StreamManager implements EventDispatcher {
} else { } else {
this.videos[0].video.addEventListener('canplay', this.canPlayListener); this.videos[0].video.addEventListener('canplay', this.canPlayListener);
} }
this.videos[0].canplayListenerAdded = true;
} }
} }

View File

@ -21,7 +21,7 @@ import { StreamManager } from '../../OpenVidu/StreamManager';
/** /**
* Defines the following events: * Defines the following events:
* - `streamPlaying`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) whenever its media stream starts playing (one of its videos has media * - `streamPlaying`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) whenever its media stream starts playing (one of its videos has media
* and has begun to play) * and has begun to play). This event will be dispatched when these 3 conditions are met 1) The StreamManager has no video associated in the DOM 2) It is associated to one video 3) That video starts playing
* - `streamAudioVolumeChange`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) when the volume of its Stream's audio track * - `streamAudioVolumeChange`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) when the volume of its Stream's audio track
* changes. Only applies if [[Stream.hasAudio]] is `true`. The frequency this event is fired with is defined by property `interval` of * changes. Only applies if [[Stream.hasAudio]] is `true`. The frequency this event is fired with is defined by property `interval` of
* [[OpenViduAdvancedConfiguration.publisherSpeakingEventsOptions]] (default 50ms) * [[OpenViduAdvancedConfiguration.publisherSpeakingEventsOptions]] (default 50ms)

View File

@ -15,8 +15,6 @@
* *
*/ */
import { Connection } from '../../../OpenVidu/Connection';
import { StreamManager } from '../../../OpenVidu/StreamManager';
import { VideoInsertMode } from '../../Enums/VideoInsertMode'; import { VideoInsertMode } from '../../Enums/VideoInsertMode';
@ -54,4 +52,10 @@ export interface StreamManagerVideo {
*/ */
insertMode?: VideoInsertMode; insertMode?: VideoInsertMode;
/**
* @hidden
*/
canplayListenerAdded: boolean;
} }

View File

@ -74,7 +74,7 @@ export class WebRtcPeer {
sdpMLineIndex: iceCandidate.sdpMLineIndex sdpMLineIndex: iceCandidate.sdpMLineIndex
}; };
const finalIECandidate = new RTCIceCandidate(iceCandidateAuxIE); const finalIECandidate = new RTCIceCandidate(iceCandidateAuxIE);
(<any>this.pc).addIceCandidate(finalIECandidate, () => {}, () => {}); (<any>this.pc).addIceCandidate(finalIECandidate, () => { }, () => { });
} }
} else { } else {
this.pc.addIceCandidate(<RTCIceCandidate>this.iceCandidateList.shift()); this.pc.addIceCandidate(<RTCIceCandidate>this.iceCandidateList.shift());