openvidu-react-native: Added mute/unmute camera funcionality
This commit is contained in:
parent
915350e8e3
commit
e4f284f60a
@ -7,7 +7,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Platform,TextInput, ScrollView, Button, Alert, Linking, StyleSheet, Text, View, PermissionsAndroid } from 'react-native';
|
import {
|
||||||
|
Platform,
|
||||||
|
TextInput,
|
||||||
|
ScrollView,
|
||||||
|
Button,
|
||||||
|
Alert,
|
||||||
|
Linking,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
Image,
|
||||||
|
PermissionsAndroid,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
import { OpenVidu } from 'openvidu-browser';
|
import { OpenVidu } from 'openvidu-browser';
|
||||||
import { RTCView } from './node_modules/openvidu-browser/node_modules/react-native-webrtc';
|
import { RTCView } from './node_modules/openvidu-browser/node_modules/react-native-webrtc';
|
||||||
@ -16,6 +28,7 @@ import axios from 'axios';
|
|||||||
const OPENVIDU_SERVER_URL = 'https://demos.openvidu.io:4443';
|
const OPENVIDU_SERVER_URL = 'https://demos.openvidu.io:4443';
|
||||||
const OPENVIDU_SERVER_SECRET = 'MY_SECRET';
|
const OPENVIDU_SERVER_SECRET = 'MY_SECRET';
|
||||||
|
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
export default class App extends Component<Props> {
|
export default class App extends Component<Props> {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -30,11 +43,11 @@ export default class App extends Component<Props> {
|
|||||||
role: 'PUBLISHER',
|
role: 'PUBLISHER',
|
||||||
mirror: true,
|
mirror: true,
|
||||||
videoSource: undefined,
|
videoSource: undefined,
|
||||||
|
camera: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {}
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.leaveSession();
|
this.leaveSession();
|
||||||
@ -130,14 +143,12 @@ export default class App extends Component<Props> {
|
|||||||
mySession
|
mySession
|
||||||
.connect(token, { clientData: this.state.myUserName })
|
.connect(token, { clientData: this.state.myUserName })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
||||||
if (Platform.OS == 'android') {
|
if (Platform.OS == 'android') {
|
||||||
this.checkAndroidPermissions();
|
this.checkAndroidPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 5) Get your own camera stream ---
|
// --- 5) Get your own camera stream ---
|
||||||
if (this.state.role !== 'SUBSCRIBER') {
|
if (this.state.role !== 'SUBSCRIBER') {
|
||||||
|
|
||||||
const properties = {
|
const properties = {
|
||||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||||
videoSource: undefined, // The source of video. If undefined default webcam
|
videoSource: undefined, // The source of video. If undefined default webcam
|
||||||
@ -146,7 +157,7 @@ export default class App extends Component<Props> {
|
|||||||
resolution: '640x480', // The resolution of your video
|
resolution: '640x480', // The resolution of your video
|
||||||
frameRate: 30, // The frame rate of your video
|
frameRate: 30, // The frame rate of your video
|
||||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||||
}
|
};
|
||||||
// Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video
|
// Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video
|
||||||
// element: we will manage it on our own) and with the desired properties
|
// element: we will manage it on our own) and with the desired properties
|
||||||
let publisher = this.OV.initPublisher(undefined, properties);
|
let publisher = this.OV.initPublisher(undefined, properties);
|
||||||
@ -156,11 +167,10 @@ export default class App extends Component<Props> {
|
|||||||
// Set the main video in the page to display our webcam and store our Publisher
|
// Set the main video in the page to display our webcam and store our Publisher
|
||||||
this.setState({
|
this.setState({
|
||||||
mainStreamManager: publisher,
|
mainStreamManager: publisher,
|
||||||
videoSource: !properties.videoSource ? '1' : properties.videoSource // 0: back camera | 1: user camera |
|
videoSource: !properties.videoSource ? '1' : properties.videoSource, // 0: back camera | 1: user camera |
|
||||||
});
|
});
|
||||||
mySession.publish(publisher);
|
mySession.publish(publisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||||
@ -173,7 +183,7 @@ export default class App extends Component<Props> {
|
|||||||
|
|
||||||
getNicknameTag(stream) {
|
getNicknameTag(stream) {
|
||||||
// Gets the nickName of the user
|
// Gets the nickName of the user
|
||||||
if(stream.connection && JSON.parse(stream.connection.data) && JSON.parse(stream.connection.data).clientData) {
|
if (stream.connection && JSON.parse(stream.connection.data) && JSON.parse(stream.connection.data).clientData) {
|
||||||
return JSON.parse(stream.connection.data).clientData;
|
return JSON.parse(stream.connection.data).clientData;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
@ -212,18 +222,20 @@ export default class App extends Component<Props> {
|
|||||||
mainStreamManager: undefined,
|
mainStreamManager: undefined,
|
||||||
publisher: undefined,
|
publisher: undefined,
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCamera(){
|
toggleCamera() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _switchCamera() Method provided by react-native-webrtc:
|
* _switchCamera() Method provided by react-native-webrtc:
|
||||||
* This function allows to switch the front / back cameras in a video track on the fly, without the need for adding / removing tracks or renegotiating
|
* This function allows to switch the front / back cameras in a video track on the fly, without the need for adding / removing tracks or renegotiating
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.state.mainStreamManager.stream.getMediaStream().getVideoTracks()[0]._switchCamera();
|
this.state.mainStreamManager.stream
|
||||||
this.setState({mirror: !this.state.mirror});
|
.getMediaStream()
|
||||||
|
.getVideoTracks()[0]
|
||||||
|
._switchCamera();
|
||||||
|
this.setState({ mirror: !this.state.mirror });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traditional way:
|
* Traditional way:
|
||||||
@ -257,76 +269,105 @@ export default class App extends Component<Props> {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
muteUnmuteCamera() {
|
||||||
|
this.state.mainStreamManager.publishVideo(!this.state.camera);
|
||||||
|
this.setState({ camera: !this.state.camera });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
return (
|
return (
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
{this.state.mainStreamManager ? (
|
{this.state.mainStreamManager ? (
|
||||||
<View>
|
<View>
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text>Session: {this.state.mySessionId}</Text>
|
<Text>Session: {this.state.mySessionId}</Text>
|
||||||
<Text>{this.getNicknameTag(this.state.mainStreamManager.stream)}</Text>
|
<Text>{this.getNicknameTag(this.state.mainStreamManager.stream)}</Text>
|
||||||
<RTCView zOrder={0} objectFit="cover" mirror={this.state.mirror}
|
<RTCView
|
||||||
ref={(rtcVideo) => {
|
zOrder={0}
|
||||||
if (!!rtcVideo) {
|
objectFit="cover"
|
||||||
this.state.mainStreamManager.addVideoElement(rtcVideo);
|
mirror={this.state.mirror}
|
||||||
}
|
ref={(rtcVideo) => {
|
||||||
}}
|
if (!!rtcVideo) {
|
||||||
style={styles.selfView}
|
this.state.mainStreamManager.addVideoElement(rtcVideo);
|
||||||
/>
|
}
|
||||||
</View>
|
}}
|
||||||
<View>
|
style={styles.selfView}
|
||||||
<Button
|
|
||||||
onLongPress={() => this.toggleCamera()}
|
|
||||||
onPress={() => this.toggleCamera()}
|
|
||||||
title="Toggle Camera"
|
|
||||||
color="#841584"
|
|
||||||
/>
|
/>
|
||||||
<Button
|
</View>
|
||||||
onLongPress={() => this.leaveSession()}
|
<View>
|
||||||
onPress={() => this.leaveSession()}
|
<View style={styles.button}>
|
||||||
title="Leave Session"
|
<Button
|
||||||
color="#ff0000"
|
onLongPress={() => this.toggleCamera()}
|
||||||
/>
|
onPress={() => this.toggleCamera()}
|
||||||
</View>
|
title="Toggle Camera"
|
||||||
|
color="#841584"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Button
|
||||||
|
onLongPress={() => this.muteUnmuteCamera()}
|
||||||
|
onPress={() => this.muteUnmuteCamera()}
|
||||||
|
title={this.state.camera ? 'Mute Camera' : 'Unmute Camera'}
|
||||||
|
color="#00cbff"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Button
|
||||||
|
onLongPress={() => this.leaveSession()}
|
||||||
|
onPress={() => this.leaveSession()}
|
||||||
|
title="Leave Session"
|
||||||
|
color="#ff0000"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<View style={{
|
<View>
|
||||||
flex: 1,
|
<View style={{
|
||||||
flexDirection: 'column',
|
justifyContent: 'center',
|
||||||
justifyContent: 'center',
|
alignItems: 'center',
|
||||||
alignItems: 'stretch',
|
padding: 20}}>
|
||||||
height: '100%',
|
|
||||||
paddingTop: 100
|
<Image style={styles.img} source={require('./resources/images/openvidu_grey_bg_transp_cropped.png')} />
|
||||||
}}>
|
</View>
|
||||||
<TextInput
|
<View style={{ justifyContent: 'center', alignItems: 'center'}}>
|
||||||
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
|
<TextInput
|
||||||
onChangeText={(mySessionId) => this.setState({mySessionId})}
|
style={{ width: '90%', height: 40, borderColor: 'gray', borderWidth: 1 }}
|
||||||
value={this.state.mySessionId}
|
onChangeText={(mySessionId) => this.setState({ mySessionId })}
|
||||||
/>
|
value={this.state.mySessionId}
|
||||||
<Button
|
|
||||||
onLongPress={() => this.joinSession()}
|
|
||||||
onPress={() => this.joinSession()}
|
|
||||||
title="Join"
|
|
||||||
color="#841584"
|
|
||||||
style={{width: '100%'}}
|
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Button
|
||||||
|
onLongPress={() => this.joinSession()}
|
||||||
|
onPress={() => this.joinSession()}
|
||||||
|
title="Join"
|
||||||
|
color="#841584"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<View style={[styles.container, {flexDirection: 'row', flexWrap: 'wrap'}] }>
|
<View style={[styles.container, { flexDirection: 'row', flexWrap: 'wrap' }]}>
|
||||||
{this.state.subscribers.map((item, index) => {
|
{this.state.subscribers.map((item, index) => {
|
||||||
if(!!item){
|
if (!!item) {
|
||||||
return (
|
return (
|
||||||
<View key={index}>
|
<View key={index}>
|
||||||
<Text>{this.getNicknameTag(item.stream)}</Text>
|
<Text>{this.getNicknameTag(item.stream)}</Text>
|
||||||
<RTCView zOrder={0} objectFit="cover" style={styles.remoteView} ref={(rtcVideo) => {
|
<RTCView
|
||||||
if (!!rtcVideo){
|
zOrder={0}
|
||||||
item.addVideoElement(rtcVideo);
|
objectFit="cover"
|
||||||
}
|
style={styles.remoteView}
|
||||||
}} />
|
ref={(rtcVideo) => {
|
||||||
|
if (!!rtcVideo) {
|
||||||
|
item.addVideoElement(rtcVideo);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
@ -354,14 +395,13 @@ export default class App extends Component<Props> {
|
|||||||
|
|
||||||
createSession(sessionId) {
|
createSession(sessionId) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
|
||||||
var data = JSON.stringify({ customSessionId: sessionId });
|
var data = JSON.stringify({ customSessionId: sessionId });
|
||||||
axios
|
axios
|
||||||
.post(OPENVIDU_SERVER_URL + '/api/sessions', data, {
|
.post(OPENVIDU_SERVER_URL + '/api/sessions', data, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET),
|
Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET),
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept': 'application/json'
|
Accept: 'application/json',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@ -375,7 +415,9 @@ export default class App extends Component<Props> {
|
|||||||
console.log('RESOLVING WITH SESSIONID, 409');
|
console.log('RESOLVING WITH SESSIONID, 409');
|
||||||
resolve(sessionId);
|
resolve(sessionId);
|
||||||
} else {
|
} else {
|
||||||
console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL);
|
console.warn(
|
||||||
|
'No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL,
|
||||||
|
);
|
||||||
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
'No connection to OpenVidu Server.',
|
'No connection to OpenVidu Server.',
|
||||||
@ -430,14 +472,22 @@ const styles = StyleSheet.create({
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
paddingTop: Platform.OS == 'ios' ? 20 : 0
|
paddingTop: Platform.OS == 'ios' ? 20 : 0,
|
||||||
},
|
},
|
||||||
selfView: {
|
selfView: {
|
||||||
width: 200,
|
width: '100%',
|
||||||
height: 200,
|
height: 300,
|
||||||
},
|
},
|
||||||
remoteView: {
|
remoteView: {
|
||||||
width: 150,
|
width: 150,
|
||||||
height: 150,
|
height: 150,
|
||||||
},
|
},
|
||||||
|
button: {
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
img: {
|
||||||
|
flex: 1,
|
||||||
|
width: 400,
|
||||||
|
height: 200,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Loading…
x
Reference in New Issue
Block a user