mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 04:54:23 +00:00
start integrating websocket, player basically done
This commit is contained in:
@@ -5,6 +5,10 @@ import jwt from 'jsonwebtoken';
|
||||
import cors from 'cors';
|
||||
import account from './account';
|
||||
import sdk from 'oauth-janishutz-client-server';
|
||||
import { createServer } from 'node:http';
|
||||
import { Server } from 'socket.io';
|
||||
import crypto from 'node:crypto';
|
||||
import type { Room, Song } from './definitions';
|
||||
|
||||
declare let __dirname: string | undefined
|
||||
if ( typeof( __dirname ) === 'undefined' ) {
|
||||
@@ -22,6 +26,8 @@ const run = () => {
|
||||
origin: true
|
||||
} ) );
|
||||
|
||||
const httpServer = createServer( app );
|
||||
|
||||
// Load id.janishutz.com SDK and allow signing in
|
||||
sdk.routes( app, ( uid: string ) => {
|
||||
return new Promise( ( resolve, reject ) => {
|
||||
@@ -42,11 +48,126 @@ const run = () => {
|
||||
} );
|
||||
}, sdkConfig );
|
||||
|
||||
// Websocket for events
|
||||
interface SocketData {
|
||||
[key: string]: Room;
|
||||
}
|
||||
const socketData: SocketData = {};
|
||||
const io = new Server( httpServer, {
|
||||
cors: {
|
||||
origin: true,
|
||||
credentials: true,
|
||||
}
|
||||
} );
|
||||
|
||||
app.get( '/', ( request, response ) => {
|
||||
io.on( 'connection', ( socket ) => {
|
||||
socket.on( 'create-room', ( room: { name: string, token: string }, cb: ( res: { status: boolean, msg: string } ) => void ) => {
|
||||
if ( room.token === socketData[ room.name ].roomToken ) {
|
||||
socket.join( room.name );
|
||||
cb( {
|
||||
status: true,
|
||||
msg: 'ADDED_TO_ROOM'
|
||||
} )
|
||||
} else {
|
||||
cb( {
|
||||
status: false,
|
||||
msg: 'ERR_TOKEN_INVALID'
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
socket.on( 'join-room', ( room: string, cb: ( res: { status: boolean, msg: string, data?: { playbackStatus: boolean, playbackStart: number, playlist: Song[], playlistIndex: number } } ) => void ) => {
|
||||
if ( socketData[ room ] ) {
|
||||
socket.join( room );
|
||||
cb( {
|
||||
data: {
|
||||
playbackStart: socketData[ room ].playbackStart,
|
||||
playbackStatus: socketData[ room ].playbackStatus,
|
||||
playlist: socketData[ room ].playlist,
|
||||
playlistIndex: socketData[ room ].playlistIndex,
|
||||
},
|
||||
msg: 'STATUS_OK',
|
||||
status: true,
|
||||
} )
|
||||
} else {
|
||||
cb( {
|
||||
msg: 'ERR_NO_ROOM_WITH_THIS_ID',
|
||||
status: false,
|
||||
} )
|
||||
}
|
||||
} );
|
||||
|
||||
socket.on( 'tampering', ( data: { msg: string, roomName: string } ) => {
|
||||
if ( data.roomName ) {
|
||||
socket.to( data.roomName ).emit( 'tampering-msg', data.msg );
|
||||
}
|
||||
} )
|
||||
|
||||
socket.on( 'playlist', ( data: { roomName: string, roomToken: string, data: Song[] } ) => {
|
||||
if ( socketData[ data.roomName ] ) {
|
||||
if ( socketData[ data.roomName ].roomToken === data.roomToken ) {
|
||||
socketData[ data.roomName ].playlist = data.data;
|
||||
io.to( data.roomName ).emit( 'playlist', data.data );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
socket.on( 'playback', ( data: { roomName: string, roomToken: string, data: boolean } ) => {
|
||||
if ( socketData[ data.roomName ] ) {
|
||||
if ( socketData[ data.roomName ].roomToken === data.roomToken ) {
|
||||
socketData[ data.roomName ].playbackStatus = data.data;
|
||||
io.to( data.roomName ).emit( 'playback', data.data );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
socket.on( 'playlist-index', ( data: { roomName: string, roomToken: string, data: number } ) => {
|
||||
if ( socketData[ data.roomName ] ) {
|
||||
if ( socketData[ data.roomName ].roomToken === data.roomToken ) {
|
||||
socketData[ data.roomName ].playlistIndex = data.data;
|
||||
io.to( data.roomName ).emit( 'playlist-index', data.data );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
socket.on( 'playback-start', ( data: { roomName: string, roomToken: string, data: number } ) => {
|
||||
if ( socketData[ data.roomName ] ) {
|
||||
if ( socketData[ data.roomName ].roomToken === data.roomToken ) {
|
||||
socketData[ data.roomName ].playbackStart = data.data;
|
||||
io.to( data.roomName ).emit( 'playback-start', data.data );
|
||||
}
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
|
||||
app.get( '/', ( request: express.Request, response: express.Response ) => {
|
||||
response.send( 'Please visit <a href="https://music.janishutz.com">https://music.janishutz.com</a> to use this service' );
|
||||
} );
|
||||
|
||||
|
||||
app.get( '/createRoomToken', ( request: express.Request, response: express.Response ) => {
|
||||
if ( sdk.checkAuth( request ) ) {
|
||||
const roomName = String( request.query.roomName ) ?? '';
|
||||
if ( !socketData[ roomName ] ) {
|
||||
const roomToken = crypto.randomUUID();
|
||||
socketData[ roomName ] = {
|
||||
playbackStart: 0,
|
||||
playbackStatus: false,
|
||||
playlist: [],
|
||||
playlistIndex: 0,
|
||||
roomName: roomName,
|
||||
roomToken: roomToken,
|
||||
};
|
||||
response.send( roomToken );
|
||||
} else {
|
||||
response.status( 409 ).send( 'ERR_CONFLICT' );
|
||||
}
|
||||
} else {
|
||||
response.status( 403 ).send( 'ERR_FORBIDDEN' );
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
app.get( '/getAppleMusicDevToken', ( req, res ) => {
|
||||
// sign dev token
|
||||
@@ -73,7 +194,7 @@ const run = () => {
|
||||
|
||||
|
||||
const PORT = process.env.PORT || 8081;
|
||||
app.listen( PORT );
|
||||
httpServer.listen( PORT );
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
16
backend/src/definitions.d.ts
vendored
Normal file
16
backend/src/definitions.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export interface Room {
|
||||
playbackStatus: boolean;
|
||||
playbackStart: number;
|
||||
playlist: Song[];
|
||||
playlistIndex: number;
|
||||
roomName: string;
|
||||
roomToken: string;
|
||||
}
|
||||
|
||||
export interface Song {
|
||||
title: string;
|
||||
artist: string;
|
||||
duration: number;
|
||||
cover: string;
|
||||
additionalInfo?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user