기본 화상 통화 앱 반응
9838 단어 reactreactnative
필요한 것:
Twiilio 계정
Twilio를 사용할 예정이므로 가입here하고 필수 키(API KEY SID, ACCOUNT SID, API KEY SECRET)를 검색해야 합니다.
그런 다음 설정 => API 키로 이동합니다.
새 API 키 추가를 클릭하고 유형으로 드롭다운을 선택하고 기본을 선택합니다.
API 비밀은 한 번만 표시됩니다. 서버 측 구현을 위해 모든 키가 필요하므로 안전한 곳에 복사하여 붙여넣어야 합니다.
서버 측 구현
여기서 단계는 매우 간단합니다. 일반 노드 익스프레스를 구현하고 다음 경로를 추가합니다.
import 'dotenv/config';
import express from 'express';
import twilio from 'twilio';
const AccessToken = twilio.jwt.AccessToken;
const VideoGrant = AccessToken.VideoGrant;
const app = express();
app.get('/getToken', (req, res) => {
if (!req.query || !req.query.room || !req.query.username) {
return res.status(400).send('username and room parameter is required');
}
const accessToken = new AccessToken(
process.env.ACCOUNT_SID,
process.env.API_KEY_SID,
process.env.API_KEY_SECRET
); // Set the Identity of this token
const grant = new VideoGrant();
accessToken.identity = req.query.username;// Grant access to Video
grant.room = req.query.room;
accessToken.addGrant(grant); // Serialize the token as a JWT
const jwt = accessToken.toJwt();
return res.send(jwt);
});
이 끝점의 경우 쿼리 본문에서 사용자 이름을 문자열로, 방을 문자열로 가져옵니다. 방을 만들고 다른 참가자를 기다리는 방에 사용자를 추가합니다.
클라이언트 측 구현
이제 프로젝트에 twilio 비디오 webrtc 모듈을 추가할 수 있습니다.
yarn add https://github.com/blackuy/react-native-twilio-video-webrtc
그런 다음 Android 및 iOS 모두에 대한 간단한 설치 지침here을 따릅니다.
import React, { useState, useRef } from "react";
import {
Alert,
AppRegistry,
StyleSheet,
Text,
TextInput,
View,
Button,
PermissionsAndroid,
Platform,
TouchableOpacity,
} from "react-native";
import {
TwilioVideoLocalView,
TwilioVideoParticipantView,
TwilioVideo,
} from "react-native-twilio-video-webrtc";
import styleSheet from "./styles";
const styles = StyleSheet.create(styleSheet);
const App = (props) => {
const [isAudioEnabled, setIsAudioEnabled] = useState(true);
const [isVideoEnabled, setIsVideoEnabled] = useState(true);
const [status, setStatus] = useState("disconnected");
const [participants, setParticipants] = useState(new Map());
const [videoTracks, setVideoTracks] = useState(new Map());
const [room, setRoom] = useState("");
const [username, setUsername] = useState("");
const twilioVideo = useRef(null);
const fetchToken = async () => {
try {
const res = await fetch(
`https://<your_base_url>/getToken?username=${username}&room=${room}`
);
if (!res.ok) {
console.log("error", error);
Alert.alert("API not available");
return null;
}
const jwt = await res.text();
return jwt;
} catch (error) {
console.log("error", error);
Alert.alert("An Error occurred");
return null;
}
};
const _onConnectButtonPress = async () => {
if (Platform.OS === "android") {
await _requestAudioPermission();
await _requestCameraPermission();
}
const token = await fetchToken();
if (!token) {
return;
}
twilioVideo.current.connect({
accessToken: token,
enableNetworkQualityReporting: true,
dominantSpeakerEnabled: true,
});
setStatus("connecting");
};
const _onEndButtonPress = () => {
twilioVideo.current.disconnect();
};
const _onMuteButtonPress = () => {
twilioVideo.current
.setLocalAudioEnabled(!isAudioEnabled)
.then((isEnabled) => setIsAudioEnabled(isEnabled));
};
const _onFlipButtonPress = () => {
twilioVideo.current.flipCamera();
};
const _onRoomDidConnect = () => {
setStatus("connected");
};
const _onRoomDidDisconnect = ({ error }) => {
console.log("ERROR: ", error);
setStatus("disconnected");
};
const _onRoomDidFailToConnect = (error) => {
console.log("ERROR: ", error);
setStatus("disconnected");
};
const _onParticipantAddedVideoTrack = ({ participant, track }) => {
console.log("onParticipantAddedVideoTrack: ", participant, track);
setVideoTracks(
new Map([
...videoTracks,
[
track.trackSid,
{ participantSid: participant.sid, videoTrackSid: track.trackSid },
],
])
);
};
const _onParticipantRemovedVideoTrack = ({ participant, track }) => {
console.log("onParticipantRemovedVideoTrack: ", participant, track);
const videoTracks = new Map(videoTracks);
videoTracks.delete(track.trackSid);
setVideoTracks(videoTracks);
};
const _onNetworkLevelChanged = ({ participant, isLocalUser, quality }) => {
console.log(
"Participant",
participant,
"isLocalUser",
isLocalUser,
"quality",
quality
);
};
const _onDominantSpeakerDidChange = ({ roomName, roomSid, participant }) => {
console.log(
"onDominantSpeakerDidChange",
`roomName: ${roomName}`,
`roomSid: ${roomSid}`,
"participant:",
participant
);
};
const _requestAudioPermission = () => {
return PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
{
title: "Need permission to access microphone",
message:
"To run this demo we need permission to access your microphone",
buttonNegative: "Cancel",
buttonPositive: "OK",
}
);
};
const _requestCameraPermission = () => {
return PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, {
title: "Need permission to access camera",
message: "To run this demo we need permission to access your camera",
buttonNegative: "Cancel",
buttonPositive: "OK",
});
};
return (
<View style={styles.container}>
{status === "disconnected" && (
<View>
<Text style={styles.welcome}>React Native Twilio Video</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
value={username}
onChangeText={(text) => setUsername(text)}
/>
<TextInput
style={styles.input}
autoCapitalize="none"
value={room}
onChangeText={(text) => setRoom(text)}
/>
<Button
title="Connect"
style={styles.button}
onPress={_onConnectButtonPress}
></Button>
</View>
)}
{(status === "connected" || status === "connecting") && (
<View style={styles.callContainer}>
{status === "connected" && (
<View style={styles.remoteGrid}>
{Array.from(videoTracks, ([trackSid, trackIdentifier]) => {
return (
<TwilioVideoParticipantView
style={styles.remoteVideo}
key={trackSid}
trackIdentifier={trackIdentifier}
/>
);
})}
</View>
)}
<View style={styles.optionsContainer}>
<TouchableOpacity
style={styles.optionButton}
onPress={_onEndButtonPress}
>
<Text style={{ fontSize: 12 }}>End</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.optionButton}
onPress={_onMuteButtonPress}
>
<Text style={{ fontSize: 12 }}>
{isAudioEnabled ? "Mute" : "Unmute"}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.optionButton}
onPress={_onFlipButtonPress}
>
<Text style={{ fontSize: 12 }}>Flip</Text>
</TouchableOpacity>
<TwilioVideoLocalView enabled={true} style={styles.localVideo} />
</View>
</View>
)}
<TwilioVideo
ref={twilioVideo}
onRoomDidConnect={_onRoomDidConnect}
onRoomDidDisconnect={_onRoomDidDisconnect}
onRoomDidFailToConnect={_onRoomDidFailToConnect}
onParticipantAddedVideoTrack={_onParticipantAddedVideoTrack}
onParticipantRemovedVideoTrack={_onParticipantRemovedVideoTrack}
onNetworkQualityLevelsChanged={_onNetworkLevelChanged}
onDominantSpeakerDidChange={_onDominantSpeakerDidChange}
/>
</View>
);
};
export default App;
위의 코드를 복사하여 ur react native 프로젝트에 붙여넣고 방과 사용자 이름을 입력하고 연결 버튼을 눌러 화상 통화를 시작하세요.
오. 테스트할 장치가 두 개 이상 있는지 확인하고 실제로 작동하는지 확인하십시오.
Twilio를 사용하여 반응 네이티브에서 기본 화상 통화를 구현하고 서버 측과 클라이언트 측을 모두 구현한 후 다음 단계는 고급 기능을 추가하고 다음과 같은 표준 통화 기능을 포함하는 WhatsApp 클론 구축과 같은 기술을 향상시키는 것입니다.
다른 참가자 또는 여러 참가자 화상 통화방, 그룹 통화 벨 울림, 통화 중, 통화 거부 또는 응답되지 않은 통화와 같은 참가자 상태 관리 및 표시.
이 모든 기능이 추가된 적절한 화상 통화 앱을 확인해야 합니다QuickComponent. 앞에서 언급한 React NativeWhatsApp Clone와 완전한 화상 통화 기능을 갖춘 Dating app , UberEats clone 등과 같은 더 많은 React Native 앱을 찾을 수 있습니다.
Reference
이 문제에 관하여(기본 화상 통화 앱 반응), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kyle_buntin/react-native-video-calling-app-cga텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)