diff --git a/src/components/media-views.js b/src/components/media-views.js index f82840a425f50ad9d83d670acdd55c737e8a13ee..49eae14a33263aed6b8955d4afe9d46b1eaa7a42 100644 --- a/src/components/media-views.js +++ b/src/components/media-views.js @@ -327,15 +327,17 @@ AFRAME.registerComponent("media-video", { return; } - texture.audioSource = this.el.sceneEl.audioListener.context.createMediaElementSource(texture.image); - this.video = texture.image; + if (!src.startsWith("webrtc://")) { + texture.audioSource = this.el.sceneEl.audioListener.context.createMediaElementSource(texture.image); + + const sound = new THREE.PositionalAudio(this.el.sceneEl.audioListener); + sound.setNodeSource(texture.audioSource); + this.el.setObject3D("sound", sound); + } + this.video = texture.image; this.video.addEventListener("pause", this.onPauseStateChange); this.video.addEventListener("play", this.onPauseStateChange); - - const sound = new THREE.PositionalAudio(this.el.sceneEl.audioListener); - sound.setNodeSource(texture.audioSource); - this.el.setObject3D("sound", sound); } catch (e) { console.error("Error loading video", this.data.src, e); texture = errorTexture; diff --git a/src/scene-entry-manager.js b/src/scene-entry-manager.js index 6b956f587beb1bace822441add905f9e13e98e67..bee6875991fdccc1a38f9bc505ee98364b708225 100644 --- a/src/scene-entry-manager.js +++ b/src/scene-entry-manager.js @@ -174,6 +174,8 @@ export default class SceneEntryManager { orientation: or }); }); + + return entity; }; this.scene.addEventListener("add_media", e => { @@ -186,6 +188,8 @@ export default class SceneEntryManager { const el = e.detail.el; const networkId = el.components.networked.data.networkId; const gltfNode = pinnedEntityToGltf(el); + if (!gltfNode) return; + el.setAttribute("networked", { persistent: true }); this.hubChannel.pin(networkId, gltfNode); @@ -235,26 +239,70 @@ export default class SceneEntryManager { } }); - this.scene.addEventListener("action_share_screen", async () => { - const constraints = { + let currentVideoShareEntity; + let isHandlingVideoShare = false; + + const shareVideoMediaStream = async constraints => { + if (isHandlingVideoShare) return; + isHandlingVideoShare = true; + + if (!currentVideoShareEntity) { + const newStream = await navigator.mediaDevices.getUserMedia(constraints); + const videoTracks = newStream ? newStream.getVideoTracks() : []; + + if (videoTracks.length > 0) { + newStream.getVideoTracks().forEach(track => mediaStream.addTrack(track)); + NAF.connection.adapter.setLocalMediaStream(mediaStream); + currentVideoShareEntity = spawnMediaInfrontOfPlayer(mediaStream, undefined); + } + } else { + currentVideoShareEntity.parentNode.removeChild(currentVideoShareEntity); + + for (const track of mediaStream.getVideoTracks()) { + mediaStream.removeTrack(track); + } + + NAF.connection.adapter.setLocalMediaStream(mediaStream); + currentVideoShareEntity = null; + } + + isHandlingVideoShare = false; + }; + + this.scene.addEventListener("action_share_camera", () => { + shareVideoMediaStream({ video: { - mediaSource: "screen", + mediaSource: "camera", + width: 720, + frameRate: 30 + } + }); + }); + + this.scene.addEventListener("action_share_window", () => { + shareVideoMediaStream({ + video: { + mediaSource: "window", // Work around BMO 1449832 by calculating the width. This will break for multi monitors if you share anything // other than your current monitor that has a different aspect ratio. width: 720 * (screen.width / screen.height), height: 720, frameRate: 30 } - }; - - const newStream = await navigator.mediaDevices.getUserMedia(constraints); - const videoTracks = newStream ? newStream.getVideoTracks() : []; + }); + }); - if (videoTracks.length > 0) { - newStream.getVideoTracks().forEach(track => mediaStream.addTrack(track)); - NAF.connection.adapter.setLocalMediaStream(mediaStream); - spawnMediaInfrontOfPlayer(mediaStream, undefined); - } + this.scene.addEventListener("action_share_screen", () => { + shareVideoMediaStream({ + video: { + mediaSource: "screen", + // Work around BMO 1449832 by calculating the width. This will break for multi monitors if you share anything + // other than your current monitor that has a different aspect ratio. + width: 720 * (screen.width / screen.height), + height: 720, + frameRate: 30 + } + }); }); }; diff --git a/src/utils/pinned-entity-to-gltf.js b/src/utils/pinned-entity-to-gltf.js index c820dd786c5d5714c2faf008b49182c08bc63513..b5cb91b7f055d169fd925e2455b1406826c76267 100644 --- a/src/utils/pinned-entity-to-gltf.js +++ b/src/utils/pinned-entity-to-gltf.js @@ -20,7 +20,14 @@ export default function pinnedEntityToGltf(el) { if (!equalArray(scale, [1, 1, 1])) gltfNode.scale = scale; if (components["media-loader"]) { - gltfComponents.media = { src: components["media-loader"].data.src, id: networkId }; + const mediaSrc = components["media-loader"].data.src; + + if (mediaSrc.startsWith("webrtc://")) { + // Do not persist webrtc media shares + return null; + } + + gltfComponents.media = { src: mediaSrc, id: networkId }; if (components["media-pager"]) { gltfComponents.media.pageIndex = components["media-pager"].data.index;