/* * options: name: XXX data: true (Maybe this is based on webrtc) audio: true, * video: true, url: "file:///..." > Player screen: true > Desktop (implicit * video:true, audio:false) audio: true, video: true > Webcam * * stream.hasAudio(); stream.hasVideo(); stream.hasData(); */ import { Connection } from './Connection'; import { SessionInternal } from './SessionInternal'; import { OpenViduInternal, Callback } from './OpenViduInternal'; import EventEmitter = require('wolfy87-eventemitter'); import * as kurentoUtils from '../KurentoUtils/kurento-utils-js'; import * as adapter from 'webrtc-adapter'; declare var navigator: any; declare var RTCSessionDescription: any; if (window) { window["adapter"] = adapter; } function jq(id: string): string { return id.replace(/(@|:|\.|\[|\]|,)/g, "\\$1"); } function show(id: string) { document.getElementById(jq(id))!.style.display = 'block'; } function hide(id: string) { document.getElementById(jq(id))!.style.display = 'none'; } export interface StreamOptions { id: string; connection: Connection; recvVideo: any; recvAudio: any; video: boolean; audio: boolean; data: boolean; mediaConstraints: any; audioOnly: boolean; } export interface VideoOptions { thumb: string; video: HTMLVideoElement; } export class Stream { public connection: Connection; private ee = new EventEmitter(); private wrStream: any; private wp: any; private id: string; private video: HTMLVideoElement; private videoElements: VideoOptions[] = []; private elements: HTMLDivElement[] = []; private speechEvent: any; private recvVideo: any; private recvAudio: any; private sendVideo: boolean; private sendAudio: boolean; private mediaConstraints: any; private showMyRemote = false; private localMirrored = false; private chanId = 0; private dataChannel: boolean; private dataChannelOpened = false; private audioOnly = false; private videoSrcObject: MediaStream | null; private parentId: string; public isReady: boolean = false; public isVideoELementCreated: boolean = false; public accessIsAllowed: boolean = false; public accessIsDenied: boolean = false; constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: StreamOptions) { if (options.id) { this.id = options.id; } else { this.id = "webcam"; } this.connection = options.connection; this.recvVideo = options.recvVideo; this.recvAudio = options.recvAudio; this.dataChannel = options.data || false; this.sendVideo = options.video; this.sendAudio = options.audio; this.mediaConstraints = options.mediaConstraints; this.audioOnly = options.audioOnly || false; this.addEventListener('src-added', (srcEvent) => { this.videoSrcObject = srcEvent.srcObject; if (this.video) this.video.srcObject = srcEvent.srcObject; console.debug("Video srcObject [" + srcEvent.srcObject + "] added to stream [" + this.getId() + "]"); }); } emitSrcEvent(wrstream) { this.ee.emitEvent('src-added', [{ srcObject: wrstream }]); } emitStreamReadyEvent() { this.ee.emitEvent('stream-ready'), [{}]; } getVideoSrcObject() { return this.videoSrcObject; } removeVideo(parentElement: string); removeVideo(parentElement: Element); removeVideo(); removeVideo(parentElement?) { if (typeof parentElement === "string") { document.getElementById(parentElement)!.removeChild(this.video); } else if (parentElement instanceof Element) { parentElement.removeChild(this.video); } else if (!parentElement) { if (document.getElementById(this.parentId)) { document.getElementById(this.parentId)!.removeChild(this.video); } } } getVideoElement(): HTMLVideoElement { return this.video; } setVideoElement(video: HTMLVideoElement) { this.video = video; } getRecvVideo() { return this.recvVideo; } getRecvAudio() { return this.recvAudio; } subscribeToMyRemote() { this.showMyRemote = true; } displayMyRemote() { return this.showMyRemote; } mirrorLocalStream(wr) { this.showMyRemote = true; this.localMirrored = true; if (wr) { this.wrStream = wr; this.emitSrcEvent(this.wrStream); } } isLocalMirrored() { return this.localMirrored; } getChannelName() { return this.getId() + '_' + this.chanId++; } isDataChannelEnabled() { return this.dataChannel; } isDataChannelOpened() { return this.dataChannelOpened; } onDataChannelOpen(event) { console.debug('Data channel is opened'); this.dataChannelOpened = true; } onDataChannelClosed(event) { console.debug('Data channel is closed'); this.dataChannelOpened = false; } sendData(data) { if (this.wp === undefined) { throw new Error('WebRTC peer has not been created yet'); } if (!this.dataChannelOpened) { throw new Error('Data channel is not opened'); } console.info("Sending through data channel: " + data); this.wp.send(data); } getWrStream() { return this.wrStream; } getWebRtcPeer() { return this.wp; } addEventListener(eventName: string, listener: any) { this.ee.addListener(eventName, listener); } addOnceEventListener(eventName: string, listener: any) { this.ee.addOnceListener(eventName, listener); } removeListener(eventName) { this.ee.removeAllListeners(eventName); } showSpinner(spinnerParentId: string) { let progress = document.createElement('div'); progress.id = 'progress-' + this.getId(); progress.style.background = "center transparent url('img/spinner.gif') no-repeat"; let spinnerParent = document.getElementById(spinnerParentId); if (spinnerParent) { spinnerParent.appendChild(progress); } } hideSpinner(spinnerId?: string) { spinnerId = (spinnerId === undefined) ? this.getId() : spinnerId; hide('progress-' + spinnerId); } playOnlyVideo(parentElement, thumbnailId) { // TO-DO: check somehow if the stream is audio only, so the element created is