0

所以,我正在创建一个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',
        })
      );
    }
  });
});

4

0 回答 0