所以,我正在创建一个walkie talkie
网站\应用程序,但问题是当我录制音频并将 bolb 转换为它时,objectUrl
它只能在发送者的设备中工作。我做了一些研究,发现createObjectURL
这只适用于本地环境。我如何发送它。
这是我的 index.js:
// index.js
import Head from 'next/head';
import { useEffect, useState } from 'react';
import style from '../../../styles/Talk.module.css';
import apiBaseUrl from '../../../components/apiBaseUrl';
const talk = ({ id }) => {
const [paused, setPaused] = useState(false);
const [copied, setCopied] = useState(false);
const [webScokect, setWebScokect] = useState();
const [participants, setParticipants] = useState(0);
const [userId, setUserId] = useState();
const [stream, setStream] = useState();
const [mediaRecorder, setMediaRecorder] = useState();
useEffect(() => {
const ws = new WebSocket(`ws://localhost:8080`);
setWebScokect(ws);
ws.onmessage = async (e) => {
const data = JSON.parse(e.data);
if (data.status === 'failure') {
return alert('technical error');
}
if (data.status === 'success') {
if (data.type === 'handShake') {
try {
const res = await fetch(
`${apiBaseUrl}/register?roomId=${id}&userId=${data.data.randomId}`
);
const mydata = await res.json();
if (mydata.status === 'failure') {
return alert('technical error');
}
setUserId(data.data.randomId);
setParticipants(mydata.data.participants);
} catch (error) {
return alert('technical error');
}
} else {
console.log(data.data.blob);
const audio = new Audio(data.data.blob);
audio.play();
}
}
};
}, []);
const sendBlobToServer = (audioUrl) => {
webScokect.send(
JSON.stringify({
roomId: id,
userId,
blob: audioUrl,
})
);
};
const handleClick = async () => {
if (paused) {
mediaRecorder.stop();
stream.getTracks().forEach(function (track) {
track.stop();
});
} else {
const userMedia = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const userRocrder = new MediaRecorder(userMedia);
userRocrder.start();
const audioChunks = [];
userRocrder.addEventListener('dataavailable', (event) => {
audioChunks.push(event.data);
});
userRocrder.addEventListener('stop', () => {
const audioBlob = new Blob(audioChunks);
const audioUrl = URL.createObjectURL(audioBlob);
sendBlobToServer(audioUrl);
});
setStream(userMedia);
setMediaRecorder(userRocrder);
}
setPaused(!paused);
};
const handleCopy = () => {
navigator.clipboard.writeText(`http://localhost:3000/talk/${id}`);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 1500);
};
return (
<div className={style.container}>
<Head>
<title>In room: {id}</title>
</Head>
<img
src="/walkietalkie-talk.png"
alt="walkie-talk"
className={style.walkieTalkieImage}
onClick={handleClick}
/>
<img
src="/record.png"
alt="record"
className={`${style.record} ${paused && style.show}`}
/>
<p className={style.getInviteLink} onClick={handleCopy}>
{copied ? 'Copied' : 'Copy invite link'}
</p>
<p className={style.memberCount}>{participants} members in room</p>
</div>
);
};
export async function getServerSideProps(context) {
const { id } = context.params;
return {
props: { id },
};
}
export default talk;
app.js ws 代码:
// app.js
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws, req) => {
const randomId = v4().substring(0, 15);
ws.id = randomId;
ws.send(
JSON.stringify({
status: 'success',
type: 'handShake',
data: {
randomId,
},
})
);
ws.on('message', (data) => {
try {
const jsonData = JSON.parse(data);
if (!jsonData.roomId || !jsonData.blob || !jsonData.userId) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
if (
typeof jsonData.roomId !== 'string' ||
typeof jsonData.userId !== 'string' ||
typeof jsonData.blob !== 'string'
) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
Room.findOne({ roomId: jsonData.roomId }, (err, result) => {
if (err) {
console.log(err);
} else {
if (!result) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
if (!result.users.includes(jsonData.userId)) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
wss.clients.forEach(function each(client) {
if (
client.id !== jsonData.userId &&
result.users.includes(client.id)
) {
client.send(
JSON.stringify({
status: 'success',
type: 'message',
data: {
blob: jsonData.blob,
},
})
);
}
});
}
});
} catch {
ws.send(
JSON.stringify({
status: 'failure',
})
);
}
});
});