react-native-twilio-video-webrtc: TwilioVideoLocalView , TwilioVideo is not working on iOS after PR #347

Steps to reproduce

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  TextInput,
  View,
  Button,
  PermissionsAndroid,
  Platform,
  TouchableOpacity,
  Dimensions
} from 'react-native';

import {
  TwilioVideoLocalView,
  TwilioVideoParticipantView,
  TwilioVideo
} from 'react-native-twilio-video-webrtc'

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white'
  },
  callContainer: {
    flex: 1,
    position: "absolute",
    bottom: 0,
    top: 0,
    left: 0,
    right: 0
  },
  welcome: {
    fontSize: 30,
    textAlign: 'center',
    paddingTop: 40
  },
  input: {
    height: 50,
    borderWidth: 1,
    marginRight: 70,
    marginLeft: 70,
    marginTop: 50,
    textAlign: 'center',
    backgroundColor: 'white'
  },
  button: {
    marginTop: 100
  },
  localVideo: {
    flex: 1,
    width: 150,
    height: 250,
    position: "absolute",
    right: 10,
    bottom: 10
  },
  remoteGrid: {
    flex: 1,
    flexDirection: "row",
    flexWrap: 'wrap'
  },
  remoteVideo: {
    marginTop: 20,
    marginLeft: 10,
    marginRight: 10,
    width: 100,
    height: 120,
  },
  optionsContainer: {
    position: "absolute",
    left: 0,
    bottom: 0,
    right: 0,
    height: 100,
    backgroundColor: 'blue',
    flexDirection: "row",
    alignItems: "center"
  },
  optionButton: {
    width: 60,
    height: 60,
    marginLeft: 10,
    marginRight: 10,
    borderRadius: 100 / 2,
    backgroundColor: 'grey',
    justifyContent: 'center',
    alignItems: "center"
  }
});

export default class VideoConference extends Component {
  state = {
    isAudioEnabled: true,
    isVideoEnabled: true,
    status: 'disconnected',
    participants: new Map(),
    videoTracks: new Map(),
    token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTSzA1OGYxYWU3YTMxOGYzNjY0NjFmZTlkNTUzZTk0MTI5LTE2MDAwOTE4OTkiLCJncmFudHMiOnsiaWRlbnRpdHkiOiI1ZjQ4YTI4MWJkZThiZDU4YjcyYzU3YmIjVGFudS5EaG9vdCIsInZpZGVvIjp7InJvb20iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcFpDSTZJalZtTkRoaE1qZ3hZbVJsT0dKa05UaGlOekpqTlRkaVlpSXNJbWxoZENJNk1UWXdNREE1TVRnMU5pd2laWGh3SWpveE5qQTFNamMxT0RVMmZRLldUUmd4OC1FY1cxVS1UaW1NR24tVHJFcU0wMjllaU5sYVJmWlRuck1RNEUifX0sImlhdCI6MTYwMDA5MTg5OSwiZXhwIjoxNjAwMDk1NDk5LCJpc3MiOiJTSzA1OGYxYWU3YTMxOGYzNjY0NjFmZTlkNTUzZTk0MTI5Iiwic3ViIjoiQUNiMGNhZDI1Nzk2NjQ5ZDJkZGFjMjE2MGZhOTQ5ODI0MiJ9.V4MRubMKcZ9Jt5pkgekYZs8V-SoY2mKXV4gAWaeQD-U'
  }

  _onConnectButtonPress = async () => {
    if (Platform.OS === 'android') {
      await this._requestAudioPermission()
      await this._requestCameraPermission()
    }
    this.refs.twilioVideo.connect({ accessToken: this.state.token })
    this.setState({status: 'connecting'})
  }

  _onEndButtonPress = () => {
    this.refs.twilioVideo.disconnect()
  }

  _onMuteButtonPress = () => {
    this.refs.twilioVideo.setLocalAudioEnabled(!this.state.isAudioEnabled)
      .then(isEnabled => this.setState({isAudioEnabled: isEnabled}))
  }

  _onFlipButtonPress = () => {
    this.refs.twilioVideo.flipCamera()
  }

  _onRoomDidConnect = () => {
    this.setState({status: 'connected'})
  }

  _onRoomDidDisconnect = ({error}) => {
    console.log("ERROR: ", error)

    this.setState({status: 'disconnected'})
  }

  _onRoomDidFailToConnect = (error) => {
    console.log("ERROR: ", error)

    this.setState({status: 'disconnected'})
  }

  _onParticipantAddedVideoTrack = ({participant, track}) => {
    console.log("onParticipantAddedVideoTrack: ", participant, track)

    this.setState({
      videoTracks: new Map([
        ...this.state.videoTracks,
        [track.trackSid, { participantSid: participant.sid, videoTrackSid: track.trackSid }]
      ]),
    });
  }

  _onParticipantRemovedVideoTrack = ({participant, track}) => {
    console.log("onParticipantRemovedVideoTrack: ", participant, track)

    const videoTracks = this.state.videoTracks
    videoTracks.delete(track.trackSid)

    this.setState({ videoTracks: new Map([ ...videoTracks ]) });
  }

  _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"
      }
    );
  }

  _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"
      }
    );
  }

  render() {
    return (
      <View style={styles.container}>
        {
          this.state.status === 'disconnected' &&
          <View>
            <Text style={styles.welcome}>
              React Native Twilio Video
            </Text>
            <TextInput
              style={styles.input}
              autoCapitalize='none'
              value={this.state.token}
              onChangeText={(text) => this.setState({token: text})}>
            </TextInput>
            <Button
              title="Connect"
              style={styles.button}
              onPress={this._onConnectButtonPress}>
            </Button>
          </View>
        }

        {
          (this.state.status === 'connected' || this.state.status === 'connecting') &&
            <View style={styles.callContainer}>
            {
              this.state.status === 'connected' &&
              <View style={styles.remoteGrid}>
                {
                  Array.from(this.state.videoTracks, ([trackSid, trackIdentifier]) => {
                    return (
                      <TwilioVideoParticipantView
                        style={styles.remoteVideo}
                        key={trackSid}
                        trackIdentifier={trackIdentifier}
                      />
                    )
                  })
                }
              </View>
            }
          <View
              style={styles.optionsContainer}>
              <TouchableOpacity
                style={styles.optionButton}
                onPress={this._onEndButtonPress}>
                <Text style={{fontSize: 12}}>End</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.optionButton}
                onPress={this._onMuteButtonPress}>
                <Text style={{fontSize: 12}}>{ this.state.isAudioEnabled ? "Mute" : "Unmute" }</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.optionButton}
                onPress={this._onFlipButtonPress}>
                <Text style={{fontSize: 12}}>Flip</Text>
              </TouchableOpacity>
              <TwilioVideoLocalView
                enabled={true}
                style={styles.localVideo}
              />
            </View>
          </View>
        }

        <TwilioVideo
          ref="twilioVideo"
          onRoomDidConnect={ this._onRoomDidConnect }
          onRoomDidDisconnect={ this._onRoomDidDisconnect }
          onRoomDidFailToConnect= { this._onRoomDidFailToConnect }
          onParticipantAddedVideoTrack={ this._onParticipantAddedVideoTrack }
          onParticipantRemovedVideoTrack= { this._onParticipantRemovedVideoTrack }
        />
      </View>
    );
  }
}

Expected behaviour

TwilioVideoLocalView should be visible with camera screen.

Actual behaviour

It is showing background image of view.

Environment

  • Node.js version:
  • React Native version:
  • React Native platform + platform version: iOS 9.0

react-native-twilio-video-webrtc

Version: npm version or “master”

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 18

Most upvoted comments

same here TwilioVideoLocalView not working in ios,

- react-native-twilio-video-webrtc (1.0.2-1): - React - TwilioVideo (~> 3.7)

Sorry, cannot say about Android, but, yes, iOS was working. Before update I had the following versions inside Podfile.lock:

 - react-native-twilio-video-webrtc (1.0.2):	
    - React	    - React
    - TwilioVideo (~> 2.10.1)

- TwilioVideo (2.10.2)

After the update the versions are:

- react-native-twilio-video-webrtc (1.0.2-1):
    - React	    
    - TwilioVideo (~> 3.7)

- TwilioVideo (3.7.0)

My code in react-native is almost complete copy of README

Hi, if anyone was experiencing this issue on master, would they mind being a guinea pig and trying #403 to see if it fixes the problem?

Just found a workaround. Downgrade the react-native-twilio-video-webrtc package:

  1. yarn add blackuy/react-native-twilio-video-webrtc#pull/346/head
  2. cd ios && pod install

Same issue on iOS.

Versions:

- react-native-twilio-video-webrtc (1.0.2-1):
    - React	    
    - TwilioVideo (~> 3.7)

- TwilioVideo (3.7.0)

Any updates on this? TwilioVideoLocalView is not working for me on the latest TwilioVideo, react-native-twilio-video-webrtc and iOS 14.0