video player for lols

This commit is contained in:
Evert Prants 2022-04-09 21:53:02 +03:00
parent 6b9b5ef186
commit a6dd97f777
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
4 changed files with 126 additions and 0 deletions

13
package-lock.json generated
View File

@ -38,6 +38,7 @@
"babel-loader": "^8.2.4", "babel-loader": "^8.2.4",
"concurrently": "^7.1.0", "concurrently": "^7.1.0",
"css-loader": "^6.7.1", "css-loader": "^6.7.1",
"hls.js": "^1.1.5",
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.6.0", "mini-css-extract-plugin": "^2.6.0",
"nodemon": "^2.0.15", "nodemon": "^2.0.15",
@ -5558,6 +5559,12 @@
"he": "bin/he" "he": "bin/he"
} }
}, },
"node_modules/hls.js": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.1.5.tgz",
"integrity": "sha512-mQX5TSNtJEzGo5HPpvcQgCu+BWoKDQM6YYtg/KbgWkmVAcqOCvSTi0SuqG2ZJLXxIzdnFcKU2z7Mrw/YQWhPOA==",
"dev": true
},
"node_modules/hpack.js": { "node_modules/hpack.js": {
"version": "2.1.6", "version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@ -14469,6 +14476,12 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true "dev": true
}, },
"hls.js": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.1.5.tgz",
"integrity": "sha512-mQX5TSNtJEzGo5HPpvcQgCu+BWoKDQM6YYtg/KbgWkmVAcqOCvSTi0SuqG2ZJLXxIzdnFcKU2z7Mrw/YQWhPOA==",
"dev": true
},
"hpack.js": { "hpack.js": {
"version": "2.1.6", "version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",

View File

@ -41,6 +41,7 @@
"babel-loader": "^8.2.4", "babel-loader": "^8.2.4",
"concurrently": "^7.1.0", "concurrently": "^7.1.0",
"css-loader": "^6.7.1", "css-loader": "^6.7.1",
"hls.js": "^1.1.5",
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.6.0", "mini-css-extract-plugin": "^2.6.0",
"nodemon": "^2.0.15", "nodemon": "^2.0.15",

View File

@ -1,3 +1,4 @@
import e from 'express';
import { Socket } from 'socket.io-client'; import { Socket } from 'socket.io-client';
import { isMobileOrTablet } from '../common/helper'; import { isMobileOrTablet } from '../common/helper';
import { CompositePacket } from '../common/types/packet'; import { CompositePacket } from '../common/types/packet';
@ -5,6 +6,7 @@ import { IcyNetUser } from '../common/types/user';
import { ThirdPersonCamera } from './object/camera'; import { ThirdPersonCamera } from './object/camera';
import { Chat } from './object/chat'; import { Chat } from './object/chat';
import { Joystick } from './object/joystick'; import { Joystick } from './object/joystick';
import { VideoPlayer } from './object/other/video-player';
import { Player } from './object/player'; import { Player } from './object/player';
import { PlayerEntity } from './object/player-entity'; import { PlayerEntity } from './object/player-entity';
import modelLoaderInstance from './object/pony-loader'; import modelLoaderInstance from './object/pony-loader';
@ -20,6 +22,8 @@ export class Game {
public renderer = new Renderer(); public renderer = new Renderer();
private videoTest = new VideoPlayer();
constructor(public socket: Socket) {} constructor(public socket: Socket) {}
async initialize(): Promise<void> { async initialize(): Promise<void> {
@ -31,7 +35,30 @@ export class Game {
this.chat.initialize(); this.chat.initialize();
this.socket.connect(); this.socket.connect();
// experimental
this.videoTest.initialize();
this.videoTest.mesh.position.set(0, 6, -20);
this.renderer.scene.add(this.videoTest.mesh);
// end of
this.chat.registerSendFunction((message) => { this.chat.registerSendFunction((message) => {
// experimental
if (message.startsWith('!play')) {
const [cmd, src] = message.split(' ');
if (src) {
this.videoTest.setSource(src, true);
} else {
this.videoTest.play();
}
return;
}
if (message.startsWith('!stop')) {
this.videoTest.stop();
return;
}
// end of
this.socket.emit('chat-send', message); this.socket.emit('chat-send', message);
}); });

View File

@ -0,0 +1,85 @@
import Hls from 'hls.js';
import {
FrontSide,
Mesh,
MeshBasicMaterial,
PlaneGeometry,
VideoTexture,
} from 'three';
export class VideoPlayer {
public video = document.createElement('video');
public material!: MeshBasicMaterial;
public texture!: VideoTexture;
public mesh!: Mesh;
public hls?: Hls;
public playable: boolean;
public geometry!: PlaneGeometry;
initialize() {
this.texture = new VideoTexture(this.video);
this.material = new MeshBasicMaterial({
map: this.texture,
side: FrontSide,
toneMapped: false,
});
this.geometry = new PlaneGeometry(24, 12);
this.mesh = new Mesh(this.geometry, this.material);
this.video.addEventListener('canplay', () => {
this.playable = true;
});
}
public setSource(source: string, autoplay = false) {
if (this.hls) {
this.hls.stopLoad();
this.hls.destroy();
}
if (source.endsWith('m3u8')) {
if (this.video.canPlayType('application/vnd.apple.mpegurl')) {
// Continue
} else if (Hls.isSupported()) {
this.hls = new Hls();
this.hls.loadSource(source);
this.hls.attachMedia(this.video);
this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
this.playable = true;
if (autoplay) {
this.video.play();
} else {
this.hls.stopLoad();
}
});
this.hls.on(Hls.Events.ERROR, (e, d) => {
this.playable = false;
// if (!d.fatal) return;
});
return;
}
}
this.video.src = source;
if (autoplay) {
this.video.play();
}
}
public play() {
if (this.playable) {
if (this.hls) {
this.hls.startLoad(-1);
}
this.video.play();
}
}
public stop() {
this.video.pause();
if (this.hls) {
this.hls.stopLoad();
}
}
}