Skip to content

Commit fcf6d32

Browse files
committedFeb 10, 2023
fix microphone switching bug
1 parent 5e0f99a commit fcf6d32

13 files changed

+1644
-32
lines changed
 

‎next.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ const nextConfig = {
44
experimental: {
55
appDir: true,
66
},
7+
webpack: (config) => {
8+
config.module.rules.push({
9+
test: /\.svg$/,
10+
use: ["@svgr/webpack"]
11+
});
12+
return config;
13+
}
714
}
815

916
module.exports = nextConfig

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@next/font": "13.1.5",
1414
"@pixi/react": "^7.0.0-alpha.2",
1515
"@pixi/tilemap": "^3.2.2",
16+
"@svgr/webpack": "^6.5.1",
1617
"@types/node": "18.11.18",
1718
"@types/react": "18.0.27",
1819
"@types/react-dom": "18.0.10",

‎public/favicon.ico

-10.3 KB
Binary file not shown.

‎public/livekit/logo-reduced.svg

+8
Loading

‎public/livekit/logo.svg

+12
Loading

‎src/app/layout.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default function RootLayout({
66
children: React.ReactNode;
77
}) {
88
return (
9-
<html lang="en" data-theme="cyberpunk">
9+
<html lang="en" data-theme="cupcake">
1010
{/*
1111
<head /> will contain the components returned by the nearest parent
1212
head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head

‎src/components/BottomBar.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ export function BottomBar() {
66
return (
77
<div className="flex w-full h-full justify-between">
88
<div className="flex h-full">
9-
<div className="max-w-[200px]">
9+
<MicrophoneMuteButton />
10+
<div className="">
1011
<MicrophoneSelector />
1112
</div>
12-
<MicrophoneMuteButton />
1313
</div>
1414
<div className="pr-2">
1515
<PoweredByLiveKit />

‎src/components/MicrophoneSelector.tsx

+67-17
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,78 @@
11
import { useMicrophone } from "@/providers/audio/microphone";
2-
import { useEffect } from "react";
2+
import { useMemo } from "react";
3+
import SineWaveSvg from "./icons/sine-wave.svg";
4+
import DiscoSVG from "./icons/disco-ball.svg";
35

46
export function MicrophoneSelector() {
57
const { selectedMicrophoneIndex, microphones, selectMicrophone } =
68
useMicrophone();
79

10+
const sineWaveIndex = useMemo(
11+
() => microphones.findIndex((m) => m.id === "sine-wave"),
12+
[microphones]
13+
);
14+
15+
const discoIndex = useMemo(
16+
() => microphones.findIndex((m) => m.id === "audio-file"),
17+
[microphones]
18+
);
19+
820
return (
9-
<div>
10-
<select
11-
onChange={(e) => {
12-
selectMicrophone(Number(e.currentTarget.value));
13-
}}
14-
value={selectedMicrophoneIndex}
15-
className="select w-full max-w-xs"
16-
>
17-
<option value={-1} disabled>
18-
Choose your microphone
19-
</option>
20-
{microphones.map((m, idx) => (
21-
<option value={idx} key={m.id}>
22-
{m.name}
21+
<div className="px-2">
22+
<div className="flex items-center">
23+
<select
24+
onChange={(e) => {
25+
selectMicrophone(Number(e.currentTarget.value));
26+
}}
27+
value={selectedMicrophoneIndex}
28+
className="select select-sm w-full max-w-[200px] m-2"
29+
>
30+
<option value={-1} disabled>
31+
Choose your microphone
2332
</option>
24-
))}
25-
</select>
33+
{microphones.map((m, idx) => (
34+
<option value={idx} key={m.id}>
35+
{m.name}
36+
</option>
37+
))}
38+
</select>
39+
<button
40+
className="text-white mr-1 h-[40px]"
41+
onClick={() => {
42+
selectMicrophone(sineWaveIndex);
43+
}}
44+
>
45+
<div
46+
className={`w-[40px] h-full relative text-white py-2 ${
47+
selectedMicrophoneIndex === sineWaveIndex
48+
? "text-accent-focus"
49+
: "text-white"
50+
}`}
51+
>
52+
<div className="tooltip" data-tip="Select sine wave microphone">
53+
<SineWaveSvg className="h-full w-full" />
54+
</div>
55+
</div>
56+
</button>
57+
<button
58+
className="text-white"
59+
onClick={() => {
60+
selectMicrophone(discoIndex);
61+
}}
62+
>
63+
<div
64+
className={`w-[40px] h-full relative text-white py-2 ${
65+
selectedMicrophoneIndex === discoIndex
66+
? "text-accent-focus"
67+
: "text-white"
68+
}`}
69+
>
70+
<div className="tooltip" data-tip="Select disco mode microphone">
71+
<DiscoSVG className="h-full w-full" />
72+
</div>
73+
</div>
74+
</button>
75+
</div>
2676
</div>
2777
);
2878
}

‎src/components/PoweredByLiveKit.tsx

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1+
import Image from "next/image";
12
import React from "react";
23

34
export const PoweredByLiveKit = () => {
45
return (
5-
<div className="h-full flex justify-center items-center text-secondary-focus">
6-
<a target="_blank" rel="noreferrer" href="https://livekit.io">
7-
Powered by LiveKit
6+
<div className="h-full">
7+
<a
8+
target="_blank"
9+
className="flex items-center h-full"
10+
rel="noreferrer"
11+
href="https://livekit.io"
12+
>
13+
<div className="text-xs text-primary mr-2">Powered by</div>
14+
<div className="h-full grow w-[60px] relative">
15+
<Image
16+
alt="livekit logo"
17+
style={{ objectFit: "contain" }}
18+
fill={true}
19+
src="/livekit/logo.svg"
20+
/>
21+
</div>
822
</a>
923
</div>
1024
);

‎src/components/icons/disco-ball.svg

+2
Loading

‎src/components/icons/sine-wave.svg

+1
Loading

‎src/providers/audio/microphone.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ export function MicrophoneProvider({ children }: Props) {
139139
const publishTrack = useCallback(
140140
async (mediaStreamTrack: MediaStreamTrack) => {
141141
if (publishingStream.current === mediaStreamTrack) return;
142+
if (publishingStream.current) {
143+
await localParticipant?.unpublishTrack(publishingStream.current);
144+
}
142145
publishingStream.current = mediaStreamTrack;
143146
try {
144147
const track = new LocalAudioTrack(mediaStreamTrack);
@@ -185,6 +188,15 @@ export function MicrophoneProvider({ children }: Props) {
185188
});
186189
}, [microphones]);
187190

191+
// if the user changes the microphone while unmuted, publish the new track
192+
useEffect(() => {
193+
if (!_muted) {
194+
getTrack().then((track) => {
195+
if (track) publishTrack(track);
196+
});
197+
}
198+
}, [_muted, getTrack, publishTrack]);
199+
188200
return (
189201
<MicrophoneContext.Provider
190202
value={{

‎yarn.lock

+1,514-9
Large diffs are not rendered by default.

1 commit comments

Comments
 (1)

vercel[bot] commented on Feb 10, 2023

@vercel[bot]
Please sign in to comment.