UNPKG

@vrspace/babylonjs

Version:

vrspace.org babylonjs client

147 lines (134 loc) 4.88 kB
import { OpenViduStreams } from '../../core/media-streams.js'; import { WorldListener } from '../../world/world-listener.js'; import { WorldManager } from '../../core/world-manager.js'; /** * Base screen sharing class, sending side. * Using should be simple - construct and init. All methods except startSharing/stopSharing are internally called, * intended to be overridden by subclasses. * Receiving side of the screen is implemented by RemoteScreen script. */ export class Screencast extends WorldListener { /** * Creates but hides meshes. * * @param world the world * @param name screen share name, displayed when sharing. Defaults to user name or id. */ constructor(world, name="Shared screen") { super(); /** text to display on the share screen button, by default Share screen */ this.text = 'Share screen'; this.world = world; this.scene = world.scene; this.name = name; /** Screen size, default 3. Height is fixed, width may scale accordingly. */ this.size = 3; /** Add manupulation handles? Default true. */ this.addHandles = true; /** Screen position, default 0,3,0 */ this.position = new BABYLON.Vector3(0, 3, 0); /** Screen rotation, default Math.PI - away from presenter */ this.rotation = new BABYLON.Vector3(0, Math.PI, 0); /** Contains VRObject used to exchange screens share messages, exists only on the sending side */ this.screenShare = null; /** Callback executed when sharing state changes, passed true/false */ this.callback = null; /** @type {WorldManager} */ this.worldManager = null; } /** Initialize the sharing component. Requires functional WorldManager attached to the world, so is safe to call from World.entered() method, or after it has been called. */ init() { this.worldManager = this.world.worldManager; this.world.addListener(this); this.setupStreaming(); } /** * Called from init(). Attaches itself to MediaStreams, creates new MediaStreams if required. * Registers handleSceneEvent() as a SceneListener with WorldManager. */ setupStreaming() { this.client = this.worldManager.VRSPACE.me; if ( ! this.worldManager.mediaStreams ) { this.worldManager.mediaStreams = new OpenViduStreams(this.scene, 'videos'); this.worldManager.pubSub(this.client, false); // audio only } } /** * Starts the screencast: creates new shared VRObject, and calls MediaStreams.shareScreen(). */ startSharing() { let screenName = this.name; if ( ! screenName ) { if ( this.client.name ) { screenName = this.client.name; } else { screenName = 'u'+this.client.id; } } this.worldManager.VRSPACE.createSharedObject({ properties:{ screenName:screenName, type: "Screencast", clientId: this.client.id, size:this.size, addHandles:this.addHandles }, active:true, script:'/babylon/js/scripts/remote-screen.js', position: {x: this.position.x, y: this.position.y, z: this.position.z}, rotation: {x: this.rotation.x, y: this.rotation.y, z: this.rotation.z} }).then(obj=>{ this.screenShare = obj; console.log("Created new VRObject", obj); this.worldManager.mediaStreams.shareScreen(()=>{ // end callback, executed when user presses browser stop share button this.deleteSharedObject(); }).then((mediaStream)=>{ console.log("streaming",mediaStream); // imageArea is created by scene event handler //this.imageArea.loadStream(mediaStream); obj.attachedScript.playStream(mediaStream, true); }).catch((e) => { console.log('sharing denied', e); this.deleteSharedObject(); }); }); } /** * Stop sharing and delete shared object. */ stopSharing() { this.deleteSharedObject(); this.worldManager.mediaStreams.stopSharingScreen(); } /** * Internally used to delete the shared object. */ deleteSharedObject() { if ( this.screenShare ) { this.worldManager.VRSPACE.deleteSharedObject(this.screenShare); this.screenShare = null; } } /** * Clean up. */ dispose() { this.stopSharing(); } /** WorldListener interface */ added(vrObject){ if ( vrObject.properties && vrObject.properties.screenName ) { this.sharing(true); } } /** WorldListener interface */ removed(vrObject){ if ( vrObject.properties && vrObject.properties.screenName ) { this.sharing(false); } } /** Called when sharing starts/stops (shared object is added/removed), executes callback */ sharing(state) { if ( this.callback ) { this.callback(state); } } }