NodeJS 无效的挂钩调用

zlhcx6iw  于 2022-12-18  发布在  Node.js
关注(0)|答案(1)|浏览(130)

我正在特灵创建一个视频流应用程序,我得到了一个错误日志:当我设置“{ ready,tracks } = useMicrophoneAndCameraTracks();“和客户端= useClient();
我试着不调用钩子useMicrophoneAndCameraTracks和useClient,错误没有出现,但是视频不会流。
Settings.js

import { createClient, createMicrophoneAndCameraTracks } from "agora-rtc-react";  

const appId = "d13f5075f00d417092285bc8a52f17f2";  
const token = "007eJxTYOjZ/X7lClbPsGXOv7vW/egUYDx+N+WSl9Bzddlf2fyLD5orMKQYGqeZGpibphkYpJgYmhtYGhlZmCYlWySaGqUZmqcZKT+bk9wQyMiwSdaKkZEBAkF8FobcxMw8BgYAbJIfFw=="  

export const config = { mode: "rtc", codec: "vp8", appId: appId, token: token };  
export const useClient = createClient(config);  
export const useMicrophoneAndCameraTracks = createMicrophoneAndCameraTracks();  
export const channelName = "main";

VideoCall.js

import { useState, useEffect } from "react";  
import {  
  config,  
  useClient,  
  useMicrophoneAndCameraTracks,  
  channelName,  
} from "./settings.js";  
import { Grid } from "@material-ui/core";  
import Video from "./Video";  
import Controls from "./Controls";  

export default function VideoCall(props) {  
  const { setInCall } = props;  
  const [users, setUsers] = useState([]);  
  const [start, setStart] = useState(false);  
  const client = useClient();  
  const { ready, tracks } = useMicrophoneAndCameraTracks();  

  useEffect(() => {  
    let init = async (name) => {  
      client.on("user-published", async (user, mediaType) => {  
        await client.subscribe(user, mediaType);  
        if (mediaType === "video") {  
          setUsers((prevUsers) => {  
            return [...prevUsers, user];  
          });  
        }  
        if (mediaType === "audio") {  
          user.audioTrack.play();  
        }  
      });  

      client.on("user-unpublished", (user, mediaType) => {  
        if (mediaType === "audio") {  
          if (user.audioTrack) user.audioTrack.stop();  
        }  
        if (mediaType === "video") {  
          setUsers((prevUsers) => {  
            return prevUsers.filter((User) => User.uid !== user.uid);  
          });  
        }  
      });  

      client.on("user-left", (user) => {  
        setUsers((prevUsers) => {  
          return prevUsers.filter((User) => User.uid !== user.uid);  
        });  
      });  

      try {  
        await client.join(config.appId, name, config.token, null);  
      } catch (error) {  
        console.log("error");  
      }  

      if (tracks) await client.publish([tracks[0], tracks[1]]);  
      setStart(true);  
    };  

    if (ready && tracks) {  
      try {  
        init(channelName);  
      } catch (error) {  
        console.log(error);  
      }  
    }  
  }, [channelName, client, ready, tracks]);  
  
  return (  
    <Grid container direction="column" style={{ height: "100%" }}>  
      <Grid item style={{ height: "5%" }}>  
        {ready && tracks && (  
          <Controls tracks={tracks} setStart={setStart} setInCall={setInCall} />  
        )}  
      </Grid>  
      <Grid item style={{ height: "95%" }}>  
        {start && tracks && <Video tracks={tracks} users={users} />}  
      </Grid>  
    </Grid>  
  );  
}

App.js

import { useState } from "react";  
import { Button } from "@material-ui/core";  
import VideoCall from "./VideoCall";  

function App() {  
  const [inCall, setInCall] = useState(false);  

  return (  
    <div className="App" style={{ height: "100%" }}>  
      {inCall ? (  
        <VideoCall setInCall={setInCall} />  
      ) : (  
        <Button  
          variant="contained"  
          color="primary"  
          onClick={() => setInCall(true)}  
        >  
          Join Call  
        </Button>  
      )}  
    </div>  
  );  
}  
  
export default App;


Controls.js

import { useState } from 'react';    
import { useClient } from './settings';  
import { Grid, Button } from '@material-ui/core';  
import MicIcon from '@material-ui/icons/Mic';  
import MicOffIcon from '@material-ui/icons/MicOff';  
import VideocamIcon from '@material-ui/icons/Videocam';  
import VideocamOffIcon from '@material-ui/icons/VideocamOff';  
import ExitToAppIcon from '@material-ui/icons/ExitToApp';  
  
export default function Controls(props) {  
   const client = useClient();  
   const {tracks, setStart, setInCall} = props;  
   const [trackState, setTrackState] = useState({video: true, audio:   true});  
  
   const mute = async(type)=> {  
      if(type === "audio") {  
         await tracks[0].setEnabled(!trackState.audio);  
         setTrackState((ps) => {  
            return {...ps, audio: !ps.audio}  
         })  
      }  
      else if(type === "video") {  
         await tracks[1].setEnabled(!trackState.video);  
         setTrackState((ps) => {  
            return {...ps, video: !ps.video}  
         })  
      }  
   }  
  
   const leaveChannel = async() => {  
      await client.leave();  
      client.removeAllListeners();  
      tracks[0].close();  
      tracks[1].close();  
      setStart(false);  
      setInCall(false);  
   }  
  
   return (  
      <Grid container spacing={2} alignItems='center'>  
         <Grid item>  
            <Button variant="contained" color={trackState.audio ?   "primary" : "secondary"} onclick={() => mute("audio")}>  
            {trackState.audio ? <MicIcon/> : <MicOffIcon/>}  
            </Button>  
         </Grid>  
         <Grid item>  
         <Button variant="contained" color={trackState.video ?   "primary" : "secondary"} onclick={() => mute("video")}>  
            {trackState.video ? <VideocamIcon/> : <VideocamOffIcon/>}  
            </Button>  
         </Grid>  
         <Grid item>  
         <Button variant="contained" color="default" onclick={() =>   leaveChannel()}>  
            Leave <ExitToAppIcon/>  
            </Button>  
         </Grid>  
      </Grid>  
   )  
}

Video.js

import { AgoraVideoPlayer } from "agora-rtc-react";  
import { Grid } from "@material-ui/core";  
import { useState, useEffect } from "react";  
  
export default function Video(props) {  
  const { users, tracks } = props;  
  const [gridSpacing, setGridSpacing] = useState(12);  
  
  useEffect(() => {  
    setGridSpacing(Math.max(Math.floor(12 / (users.length + 1)), 4));  
  }, [users, tracks]);  
  
  return (  
    <Grid container style={{ height: "100%" }}>  
      <Grid item xs={gridSpacing}>  
        <AgoraVideoPlayer  
          videoTrack={tracks[1]}  
          style={{ height: "100%", width: "100%" }}  
        />  
      </Grid>  
      {users.length > 0 &&  
        users.map((user) => {  
          if (user.videoTrack) {  
            return (  
              <Grid item xs={gridSpacing}>  
                <AgoraVideoPlayer  
                  videoTrack={user.videoTrack}  
                  key={user.uid}  
                  style={{ height: "100%", width: "100%" }}  
                />  
              </Grid>  
            );  
          } else return null;  
        })}  
    </Grid>  
  );  
}
k2arahey

k2arahey1#

没有更详细的代码,我们无法帮助您。您可能违反了有关react钩子的规则。
官方文件声明如下:
有三个常见的原因可能会让您看到它:
1.您可能有不匹配的React和React DOM版本。
1.你可能违反了胡克的规则。
1.您可能在同一个应用程序中有多个React副本。
在此阅读更多信息:https://reactjs.org/warnings/invalid-hook-call-warning.html

相关问题