First working version of video embed

This commit is contained in:
Lukas von Blarer 2021-02-03 17:21:41 +01:00 committed by Thomas Basler
parent ea9c9ff2c3
commit 429a17b89b
4 changed files with 213 additions and 0 deletions

View File

@ -126,6 +126,15 @@
<div id="audioplayer" style="visibility: hidden"></div>
</div>
</div>
<div id="videoplayerctrl" class="hidden">
<div class="videoplayer">
<div id="videoplayer"></div>
<label id="label-videoplayer_decrease_while_talking" for="videoplayer_decrease_while_talking" title="decrease background volume by 50% when entering conversations">
autoreduce
<input type="checkbox" id="videoplayer_decrease_while_talking" checked />
</label>
</div>
</div>
<div class="audio-playing">
<img src="/resources/logos/megaphone.svg" />
</div>

View File

@ -97,6 +97,7 @@ import {waScaleManager} from "../Services/WaScaleManager";
import {peerStore} from "../../Stores/PeerStore";
import {EmoteManager} from "./EmoteManager";
import { InteractiveLayer } from "../Map/InteractiveLayer";
import {videoManager} from "../../WebRtc/VideoManager";
export interface GameSceneInitInterface {
initPosition: PointInterface|null,
@ -721,6 +722,19 @@ export class GameScene extends DirtyScene implements CenterListener {
}
}
private playVideo(url: string|number|boolean|undefined, loop=false): void {
if (url === undefined) {
videoManager.unloadVideo();
} else {
const realVideoPath = '' + url;
videoManager.loadVideo(realVideoPath);
if (loop) {
videoManager.loop();
}
}
}
private triggerOnMapLayerPropertyChange(){
this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => {
if (newValue) this.onMapExit(newValue as string);
@ -866,6 +880,13 @@ ${escapedMessage}
this.popUpElements.set(openPopupEvent.popupId, domElement);
}));
this.gameMap.onPropertyChange('playVideo', (newValue, oldValue) => {
this.playVideo(newValue);
});
this.gameMap.onPropertyChange('playVideoLoop', (newValue, oldValue) => {
this.playVideo(newValue, true);
});
this.iframeSubscriptionList.push(iframeListener.closePopupStream.subscribe((closePopupEvent) => {
const popUpElement = this.popUpElements.get(closePopupEvent.popupId);

View File

@ -0,0 +1,159 @@
import {HtmlUtils} from "./HtmlUtils";
import {isUndefined} from "generic-type-guard";
enum videoStates {
closed = 0,
loading = 1,
playing = 2
}
const videoPlayerDivId = "videoplayer";
const videoPlayerCtrlId = "videoplayerctrl";
const animationTime = 500;
class VideoManager {
private opened = videoStates.closed;
private videoPlayerDiv: HTMLDivElement;
private videoPlayerCtrl: HTMLDivElement;
private videoPlayerElem: HTMLVideoElement | undefined;
private volume = 1;
private muted = false;
private decreaseWhileTalking = true;
private volumeReduced = false;
constructor() {
this.videoPlayerDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(videoPlayerDivId);
this.videoPlayerCtrl = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(videoPlayerCtrlId);
const storedVolume = localStorage.getItem('volume')
if (storedVolume === null) {
this.setVolume(1);
} else {
this.volume = parseFloat(storedVolume);
//HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_volume').value = storedVolume;
}
//HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_volume').value = '' + this.volume;
}
private close(): void {
this.videoPlayerCtrl.classList.remove('loading');
this.videoPlayerCtrl.classList.add('hidden');
this.opened = videoStates.closed;
}
private load(): void {
this.videoPlayerCtrl.classList.remove('hidden');
this.videoPlayerCtrl.classList.add('loading');
this.opened = videoStates.loading;
}
private open(): void {
this.videoPlayerCtrl.classList.remove('hidden', 'loading');
this.opened = videoStates.playing;
}
private changeVolume(talking = false): void {
if (!isUndefined(this.videoPlayerElem)) {
this.videoPlayerElem.volume = this.naturalVolume(talking && this.decreaseWhileTalking);
this.videoPlayerElem.muted = this.muted;
}
}
private naturalVolume(makeSofter: boolean = false): number {
const volume = this.volume
const retVol = makeSofter && !this.volumeReduced ? Math.pow(volume * 0.5, 3) : volume
this.volumeReduced = makeSofter
return retVol;
}
private setVolume(volume: number): void {
this.volume = volume;
localStorage.setItem('volume', '' + volume);
}
public loadVideo(url: string): void {
this.load();
/* Solution 1, remove whole video player */
this.videoPlayerDiv.innerHTML = ''; // necessary, if switching from one video context to another! (else both streams would play simultaneously)
this.videoPlayerElem = document.createElement('video');
this.videoPlayerElem.id = 'videoplayerelem';
this.videoPlayerElem.controls = true;
this.videoPlayerElem.preload = 'none';
const srcElem = document.createElement('source');
srcElem.src = url;
this.videoPlayerElem.append(srcElem);
this.videoPlayerDiv.append(this.videoPlayerElem);
this.changeVolume();
this.videoPlayerElem.play();
/*const muteElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_mute');
muteElem.onclick = (ev: Event)=> {
this.muted = !this.muted;
this.changeVolume();
if (this.muted) {
HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_volume_icon_playing').classList.add('muted');
} else {
HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_volume_icon_playing').classList.remove('muted');
}
}
const volumeElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_volume');
volumeElem.oninput = (ev: Event)=> {
this.setVolume(parseFloat((<HTMLInputElement>ev.currentTarget).value));
this.changeVolume();
(<HTMLInputElement>ev.currentTarget).blur();
}*/
const decreaseElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('videoplayer_decrease_while_talking');
decreaseElem.oninput = (ev: Event)=> {
this.decreaseWhileTalking = (<HTMLInputElement>ev.currentTarget).checked;
this.changeVolume();
}
this.open();
}
public loop(): void {
if (this.videoPlayerElem !== undefined) {
this.videoPlayerElem.loop = true;
}
}
public unloadVideo(): void {
try {
const videoElem = HtmlUtils.getElementByIdOrFail<HTMLVideoElement>('videoplayerelem');
this.volume = videoElem.volume;
this.muted = videoElem.muted;
videoElem.pause();
videoElem.loop = false;
videoElem.src = "";
videoElem.innerHTML = "";
videoElem.load();
} catch (e) {
console.log('No video element loaded to unload');
}
this.close();
}
public decreaseVolume(): void {
this.changeVolume(true);
}
public restoreVolume(): void {
this.changeVolume(false);
}
}
export const videoManager = new VideoManager();

View File

@ -581,6 +581,30 @@ input[type=range]:focus::-ms-fill-upper {
background: #FFFFFF;
}
#videoplayerctrl {
position: fixed;
width: 25%;
top: 0;
right: 75%;
transform: translate(50%, 0);
padding: 0.3rem 0.5rem;
color: white;
transition: transform 0.5s;
}
/*
* sollte eigentlich in den aspect-ratio teil ..
*/
#videoplayerctrl.loading {
transform: translate(50%, -90%);
}
#videoplayerctrl.hidden {
transform: translate(50%, -100%);
}
#videoplayerelem {
width: 100%;
}
.game-overlay {
display: none;