Update after multiple changes

This commit is contained in:
Chigozirim Igweamaka 2024-04-23 16:55:08 +01:00
parent 9c9156c6a4
commit e661dc5e2f
8 changed files with 251 additions and 62 deletions

View file

@ -21,6 +21,7 @@
"react-scripts": "4.0.3",
"react-slick": "^0.30.2",
"react-toastify": "^8.1.0",
"react-youtube": "^10.1.0",
"simple-peer": "^9.11.1",
"slick-carousel": "^1.8.1",
"socket.io-client": "^2.5.0",
@ -14311,6 +14312,11 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"node_modules/load-script": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
"integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA=="
},
"node_modules/loader-runner": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
@ -17974,6 +17980,22 @@
"react-dom": ">=16"
}
},
"node_modules/react-youtube": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-10.1.0.tgz",
"integrity": "sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg==",
"dependencies": {
"fast-deep-equal": "3.1.3",
"prop-types": "15.8.1",
"youtube-player": "5.5.2"
},
"engines": {
"node": ">= 14.x"
},
"peerDependencies": {
"react": ">=0.14.1"
}
},
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -19448,6 +19470,11 @@
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
},
"node_modules/sister": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz",
"integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA=="
},
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@ -23696,6 +23723,29 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/youtube-player": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz",
"integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==",
"dependencies": {
"debug": "^2.6.6",
"load-script": "^1.0.0",
"sister": "^3.0.0"
}
},
"node_modules/youtube-player/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/youtube-player/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
},
"dependencies": {
@ -34380,6 +34430,11 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"load-script": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
"integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA=="
},
"loader-runner": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
@ -37318,6 +37373,16 @@
"clsx": "^1.1.1"
}
},
"react-youtube": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-10.1.0.tgz",
"integrity": "sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg==",
"requires": {
"fast-deep-equal": "3.1.3",
"prop-types": "15.8.1",
"youtube-player": "5.5.2"
}
},
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -38455,6 +38520,11 @@
}
}
},
"sister": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz",
"integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA=="
},
"sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@ -41868,6 +41938,31 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
},
"youtube-player": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz",
"integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==",
"requires": {
"debug": "^2.6.6",
"load-script": "^1.0.0",
"sister": "^3.0.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
}
}
}

View file

@ -16,6 +16,7 @@
"react-scripts": "4.0.3",
"react-slick": "^0.30.2",
"react-toastify": "^8.1.0",
"react-youtube": "^10.1.0",
"simple-peer": "^9.11.1",
"slick-carousel": "^1.8.1",
"socket.io-client": "^2.5.0",

View file

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useRef } from "react";
import Peer from "simple-peer";
import io from "socket.io-client";
import Form from "./components/Form";
@ -9,6 +9,8 @@ import { FaMasksTheater, FaMicrophoneLines } from "react-icons/fa6";
import { LiaLaptopSolid } from "react-icons/lia";
import { ToastContainer, toast, Slide } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { MediaRecorder, register } from "extendable-media-recorder";
import { connect } from "extendable-media-recorder-wav-encoder";
// const socket = io.connect('http://localhost:5000/');
var socket = io("http://localhost:5000/");
@ -23,6 +25,65 @@ function App() {
const [peerConnection, setPeerConnection] = useState();
const [serverEngaged, setServerEngaged] = useState(false);
const streamRef = useRef(stream);
// const serverEngagedRef = useRef(serverEngaged);
const peerConnectionRef = useRef(peerConnection);
async function record1() {
const mediaDevice =
audioInput == "device"
? navigator.mediaDevices.getDisplayMedia.bind(navigator.mediaDevices)
: navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
await register(await connect());
const stream = await mediaDevice({ audio: true });
const audioTracks = stream.getAudioTracks();
const audioStream = new MediaStream(audioTracks);
for (const track of stream.getVideoTracks()) {
track.stop();
}
const mediaRecorder = new MediaRecorder(audioStream, {
mimeType: "audio/wav",
});
const chunks = [];
mediaRecorder.ondataavailable = function (e) {
chunks.push(e.data);
};
mediaRecorder.addEventListener("stop", () => {
const blob = new Blob(chunks, { type: "audio/wav" });
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = (event) => {
const arrayBuffer = event.target.result;
var binary = "";
var bytes = new Uint8Array(arrayBuffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
// Convert byte array to base64
const base64data = btoa(binary);
socket.emit("blob", base64data);
};
});
mediaRecorder.start();
// Stop recording after 15 seconds
setTimeout(function () {
mediaRecorder.stop();
}, 15000);
}
function record() {
const mediaDevice =
audioInput == "device"
@ -90,9 +151,10 @@ function App() {
}
function cleanUp() {
if (stream != null) {
const currentStream = streamRef.current;
if (currentStream) {
console.log("Cleaning tracks");
stream.getTracks().forEach((track) => track.stop());
currentStream.getTracks().forEach((track) => track.stop());
}
setStream(null);
setisListening(false);
@ -108,7 +170,7 @@ function App() {
// Handle peer events:
peer.on("signal", (offerData) => {
console.log("Setting Offer!");
console.log("Offer generated");
setOffer(JSON.stringify(offerData));
setPeerConnection(peer);
});
@ -124,14 +186,19 @@ function App() {
});
}
useEffect(() => {
streamRef.current = stream;
peerConnectionRef.current = peerConnection;
}, [stream, peerConnection]);
useEffect(() => {
if (offer) {
console.log("Offer updated:", offer);
console.log("Sending Offer");
let offerEncoded = btoa(offer);
socket.emit("engage", offerEncoded);
socket.on("serverEngaged", (answer) => {
console.log("ServerSDP: ", answer);
console.log("Received answer");
let decodedAnswer = atob(answer);
if (!serverEngaged && !stream && !peerConnection.destroyed) {
peerConnection.signal(decodedAnswer);
@ -145,6 +212,30 @@ function App() {
useEffect(() => {
socket.on("connect", () => {
createPeerConnection();
socket.emit("totalSongs", "");
});
// socket.on("serverEngaged", (answer) => {
// console.log("Received answer");
// let decodedAnswer = atob(answer);
// if (
// !serverEngagedRef.current &&
// !streamRef.current &&
// !peerConnectionRef.current.destroyed
// ) {
// console.log("Adding answer");
// peerConnectionRef.current.signal(decodedAnswer);
// }
// console.log("Engaged Server");
// setServerEngaged(true);
// });
socket.on("failedToEngage", () => {
console.log("Server failed to engage");
stopListening();
});
socket.on("matches", (matches) => {
@ -153,6 +244,7 @@ function App() {
setMatches(matches);
console.log("Matches: ", matches);
} else {
toast("No song found.");
console.log("No Matches");
}
@ -189,7 +281,7 @@ function App() {
function stopListening() {
console.log("Pause Clicked");
cleanUp();
peerConnection.destroy();
peerConnectionRef.current.destroy();
setTimeout(() => {
createPeerConnection();
@ -209,7 +301,6 @@ function App() {
setisListening(true);
setStream(stream);
stream.getVideoTracks()[0].onended = stopListening;
stream.getAudioTracks()[0].onended = stopListening;
})
.catch((error) => {
@ -243,7 +334,7 @@ function App() {
<Listen
stopListening={stopListening}
disable={!serverEngaged}
startListening={startListening}
startListening={record1}
isListening={isListening}
/>
</div>

View file

@ -1,8 +1,33 @@
import React from "react";
import React, { useRef } from "react";
import YouTube from "react-youtube";
import styles from "./styles/CarouselSliders.module.css";
const CarouselSliders = (props) => {
const [activeIdx, setActiveIdx] = React.useState(0);
const players = useRef({});
const opts = {
// width: "420",
// height: "210",
};
const onReady = (event, videoId) => {
players.current[videoId] = event.target;
};
const onPlay = (event) => {
const videoId = event.target.getVideoData().video_id;
// Pause other videos
Object.values(players.current).forEach((player) => {
const otherVideoId = player.getVideoData().video_id;
if (
otherVideoId !== videoId &&
player.getPlayerState() === 1 /* Playing */
) {
player.pauseVideo();
}
});
};
return (
<>
@ -15,22 +40,22 @@ const CarouselSliders = (props) => {
parseInt(h, 10) * 360 + parseInt(m, 10) * 60 + parseInt(s, 10);
return (
<>
<div
key={index}
id={`slide-${index}`}
className={styles.SlideItem}
>
<iframe
className="iframe-youtube"
src={`https://www.youtube.com/embed/${match.youtubeid}?start=${timestamp}`}
title={match.songname}
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
></iframe>
</div>
</>
<div
key={index}
id={`slide-${index}`}
className={styles.SlideItem}
>
<YouTube
videoId={match.youtubeid}
opts={{
...opts,
playerVars: { start: timestamp, rel: 0 },
}}
iframeClassName={styles.Iframe}
onReady={(event) => onReady(event, match.youtubeid)}
onPlay={onPlay}
/>
</div>
);
})}
</div>

View file

@ -40,7 +40,7 @@ const Form = ({ socket }) => {
return (
<form className={styles.Form}>
<div style={{ flexGrow: 1 }}>
<div>Download songs to the server</div>
<div>Add songs to the server</div>
<input
type="text"
name="spotifyUrl"

View file

@ -32,9 +32,8 @@
}
.SlideItem {
/* height: 100%;
height: 100%;
width: 100%;
min-width: 90%; */
margin-left: 20px;
flex-grow: 1;
scroll-snap-align: center;
@ -44,13 +43,13 @@
.SlideItem:nth-child(2) { background-color: dodgerblue;}
.SlideItem:nth-child(3) { background-color: greenyellow;}
.iframe-youtube {
width: 420px;
height: 210px;
.Iframe {
width: 500px;
height: 300px;
}
@media screen and (max-width: 500px) {
.iframe-youtube {
.Iframe {
width: 420px;
height: 200px;
}
@ -79,15 +78,18 @@
}
}
@media screen and (max-width: 600px) {
.iframe-youtube {
.Iframe {
width: 820px;
height: 400px;
}
}
@media screen and (max-width: 700px) {
.iframe-youtube {
.Iframe {
width: 420px;
height: 210px;
}
/* .SlideItem {
width: 20;
} */
}

View file

@ -1,6 +1,7 @@
Form {
width: 80%;
margin: auto;
margin-bottom: 30px;
display: flex;
gap: 12px;
align-items: end;
@ -17,30 +18,3 @@ Form {
justify-content: center;
}
}
.FormStatus {
margin-bottom: 2px;
padding: 2px 5px;
background-color: #3498db;
border-radius: 2px;
animation: slideUp 0.8s forwards;
}
.FormStatus.NoMessage {
/* animation: slideDown 0.8s forwards; */
transform: translateX(-50%) translateY(100%);
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
/* .slideDown {
transform: translateX(-50%) translateY(100%);
} */

View file

@ -50,6 +50,7 @@ main {
.App {
width: 65%;
margin: auto;
padding-bottom: 20px;
}
.songs {