First working version of video embed
This commit is contained in:
parent
ea9c9ff2c3
commit
429a17b89b
9
front/dist/index.tmpl.html
vendored
9
front/dist/index.tmpl.html
vendored
@ -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>
|
||||
|
@ -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);
|
||||
|
159
front/src/WebRtc/VideoManager.ts
Normal file
159
front/src/WebRtc/VideoManager.ts
Normal 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();
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user