Comments (8)
Most likely you have lost reference to the parent class. To fix this use this.yourFunction = this.yourFunction.bind(this);
from webrtc-video-room.
Even with these binds it still gives the same error, highlighting the line
" socket.on('create', () =>
this.props.media.setState({user: 'host', bridge: 'create'}));"
I'll attach the chat portions of the app again, as I do not see anything wrong with the binding between the parents and children. Let me know if you see anything glaring?
ChatRoomPage.js
import React, { Component } from 'react';
import MediaContainer from './MediaContainer'
import CommunicationContainer from './CommunicationContainer'
import { connect } from 'react-redux'
import store from '../store/configureStore'
import io from 'socket.io-client'
class ChatRoomPage extends React.Component {
constructor(props) {
super(props);
this.getUserMedia = navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).catch(e => alert('getUserMedia() error: ' + e.name))
this.socket = io.connect('https://localhost:8080');
}
componentDidMount() {
this.props.addRoom();
}
render() {
console.log(this.socket);
console.log(this.getUserMedia);
console.log(this.media);
return (
<div>
<MediaContainer media={media => this.media = media} socket={this.socket} getUserMedia={this.getUserMedia} />
<CommunicationContainer socket={this.socket} media={this.media} getUserMedia={this.getUserMedia} />
<h1>AppointmentSetup</h1>
</div>
);
}
}
//commented out
const mapStateToProps = store => ({rooms: new Set([...store.rooms])});
const mapDispatchToProps = (dispatch, ownProps) => (
{
addRoom: () => store.dispatch({ type: 'ADD_ROOM', room: ownProps.match.params.room })
}
);
export default connect(mapStateToProps, mapDispatchToProps)(ChatRoomPage);
Communication Container
import React from 'react'
import { PropTypes } from 'prop-types';
import Remarkable from 'remarkable-react'
import MediaContainer from './MediaContainer'
import Communication from '../components/Communication'
import store from '../store/configureStore'
import { connect } from 'react-redux'
class CommunicationContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
sid: '',
message: '',
audio: true,
video: true
};
this.handleInvitation = this.handleInvitation.bind(this);
this.handleHangup = this.handleHangup.bind(this);
this.handleInput = this.handleInput.bind(this);
this.toggleVideo = this.toggleVideo.bind(this);
this.toggleAudio = this.toggleAudio.bind(this);
this.send = this.send.bind(this);
}
hideAuth() {
this.props.media.setState({bridge: 'connecting'});
}
full() {
this.props.media.setState({bridge: 'full'});
}
componentDidMount() {
console.log('Comments componentDidMount: ');
console.log(this);
const socket = this.props.socket;
console.log('props', this.props)
this.setState({video: this.props.video, audio: this.props.audio});
socket.on('create', () =>
this.props.media.setState({user: 'host', bridge: 'create'}));
socket.on('full', this.full);
socket.on('bridge', role => this.props.media.init());
socket.on('join', () =>
this.props.media.setState({user: 'guest', bridge: 'join'}));
socket.on('approve', ({ message, sid }) => {
this.props.media.setState({bridge: 'approve'});
this.setState({ message, sid });
});
socket.emit('find');
this.props.getUserMedia
.then(stream => {
this.localStream = stream;
this.localStream.getVideoTracks()[0].enabled = this.state.video;
this.localStream.getAudioTracks()[0].enabled = this.state.audio;
});
}
handleInput(e) {
this.setState({[e.target.dataset.ref]: e.target.value});
}
send(e) {
e.preventDefault();
this.props.socket.emit('auth', this.state);
this.hideAuth();
}
handleInvitation(e) {
e.preventDefault();
this.props.socket.emit([e.target.dataset.ref], this.state.sid);
this.hideAuth();
}
getContent(content) {
return {__html: (new Remarkable()).render(content)};
}
toggleVideo() {
const video = this.localStream.getVideoTracks()[0].enabled = !this.state.video;
this.setState({video: video});
this.props.setVideo(video);
}
toggleAudio() {
const audio = this.localStream.getAudioTracks()[0].enabled = !this.state.audio;
this.setState({audio: audio});
this.props.setAudio(audio);
}
handleHangup() {
this.props.media.hangup();
}
render(){
console.log(this.media);
return (
<Communication
{...this.state}
toggleVideo={this.toggleVideo}
toggleAudio={this.toggleAudio}
getContent={this.getContent}
send={this.send}
handleHangup={this.handleHangup}
handleInput={this.handleInput}
handleInvitation={this.handleInvitation} />
);
}
}
const mapStateToProps = store => ({video: store.video, audio: store.audio});
const mapDispatchToProps = dispatch => (
{
setVideo: boo => store.dispatch({type: 'SET_VIDEO', video: boo}),
setAudio: boo => store.dispatch({type: 'SET_AUDIO', audio: boo})
}
);
CommunicationContainer.propTypes = {
socket: PropTypes.object.isRequired,
getUserMedia: PropTypes.object.isRequired,
audio: PropTypes.bool.isRequired,
video: PropTypes.bool.isRequired,
setVideo: PropTypes.func.isRequired,
setAudio: PropTypes.func.isRequired,
media: PropTypes.instanceOf(MediaContainer)
};
export default connect(mapStateToProps, mapDispatchToProps)(CommunicationContainer);
Media Container
import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
class MediaBridge extends Component {
constructor(props) {
super(props);
this.state = {
bridge: '',
user: ''
}
this.onRemoteHangup = this.onRemoteHangup.bind(this);
this.onMessage = this.onMessage.bind(this);
this.sendData = this.sendData.bind(this);
this.setupDataHandlers = this.setupDataHandlers.bind(this);
this.setDescription = this.setDescription.bind(this);
this.sendDescription = this.sendDescription.bind(this);
this.hangup = this.hangup.bind(this);
this.init = this.init.bind(this);
this.setDescription = this.setDescription.bind(this);
}
componentWillMount() {
// chrome polyfill for connection between the local device and a remote peer
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection;
this.props.media(this);
}
componentDidMount() {
this.props.getUserMedia
.then(stream => this.localVideo.srcObject = this.localStream = stream);
this.props.socket.on('message', this.onMessage);
this.props.socket.on('hangup', this.onRemoteHangup);
}
componentWillUnmount() {
this.props.media(null);
if (this.localStream !== undefined) {
this.localStream.getVideoTracks()[0].stop();
}
this.props.socket.emit('leave');
}
onRemoteHangup() {
this.setState({user: 'host', bridge: 'host-hangup'});
}
onMessage(message) {
if (message.type === 'offer') {
// set remote description and answer
this.pc.setRemoteDescription(new RTCSessionDescription(message));
this.pc.createAnswer()
.then(this.setDescription)
.then(this.sendDescription)
.catch(this.handleError); // An error occurred, so handle the failure to connect
} else if (message.type === 'answer') {
// set remote description
this.pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate') {
// add ice candidate
this.pc.addIceCandidate(
new RTCIceCandidate({
sdpMLineIndex: message.mlineindex,
candidate: message.candidate
})
);
}
}
sendData(msg) {
this.dc.send(JSON.stringify(msg))
}
// Set up the data channel message handler
setupDataHandlers() {
this.dc.onmessage = e => {
var msg = JSON.parse(e.data);
console.log('received message over data channel:' + msg);
};
this.dc.onclose = () => {
this.remoteStream.getVideoTracks()[0].stop();
console.log('The Data Channel is Closed');
};
}
setDescription(offer) {
this.pc.setLocalDescription(offer);
}
// send the offer to a server to be forwarded to the other peer
sendDescription() {
this.props.socket.send(this.pc.localDescription);
}
hangup() {
this.setState({user: 'guest', bridge: 'guest-hangup'});
this.pc.close();
this.props.socket.emit('leave');
}
handleError(e) {
console.log(e);
}
init() {
// wait for local media to be ready
const attachMediaIfReady = () => {
this.dc = this.pc.createDataChannel('chat');
this.setupDataHandlers();
console.log('attachMediaIfReady')
this.pc.createOffer()
.then(this.setDescription)
.then(this.sendDescription)
.catch(this.handleError); // An error occurred, so handle the failure to connect
}
// set up the peer connection
// this is one of Google's public STUN servers
// make sure your offer/answer role does not change. If user A does a SLD
// with type=offer initially, it must do that during the whole session
this.pc = new RTCPeerConnection({iceServers: [{url: 'stun:stun.l.google.com:19302'}]});
// when our browser gets a candidate, send it to the peer
this.pc.onicecandidate = e => {
console.log(e, 'onicecandidate');
if (e.candidate) {
this.props.socket.send({
type: 'candidate',
mlineindex: e.candidate.sdpMLineIndex,
candidate: e.candidate.candidate
});
}
};
// when the other side added a media stream, show it on screen
this.pc.onaddstream = e => {
console.log('onaddstream', e)
this.remoteStream = e.stream;
this.remoteVideo.srcObject = this.remoteStream = e.stream;
this.setState({bridge: 'established'});
};
this.pc.ondatachannel = e => {
// data channel
this.dc = e.channel;
this.setupDataHandlers();
this.sendData({
peerMediaStream: {
video: this.localStream.getVideoTracks()[0].enabled
}
});
//sendData('hello');
};
// attach local media to the peer connection
this.localStream.getTracks().forEach(track => this.pc.addTrack(track, this.localStream));
// call if we were the last to connect (to increase
// chances that everything is set up properly at both ends)
if (this.state.user === 'host') {
this.props.getUserMedia.then(attachMediaIfReady);
}
}
render(){
console.log(this.media);
console.log(this.getUserMedia)
return (
<div className={`media-bridge ${this.state.bridge}`}>
<video className="remote-video" ref={(ref) => this.remoteVideo = ref} autoPlay></video>
<video className="local-video" ref={(ref) => this.localVideo = ref} autoPlay muted></video>
</div>
);
}
}
MediaBridge.propTypes = {
socket: PropTypes.object.isRequired,
getUserMedia: PropTypes.object.isRequired,
media: PropTypes.func.isRequired
}
export default MediaBridge;
and the error being highlighted as
Any other thoughts would be appreciated as I do no know why it is losing a reference to the state across here.
Thanks.
from webrtc-video-room.
can you please help me to run this code directly from src folder. currently it is running from bundle.js
i want to modify some code and want to run
from webrtc-video-room.
@kwallace0906 how did you resolve this issue? any assistance please
from webrtc-video-room.
try accessing it with https
from webrtc-video-room.
@dondido I am
from webrtc-video-room.
ok just updated the branch.. can you pull in my changes and try again?
from webrtc-video-room.
same
from webrtc-video-room.
Related Issues (20)
- Want to change something in code
- Issue on Build
- Only works in chrome HOT 1
- Multi-user conference doesn't work properly HOT 1
- Node server not started HOT 1
- Recording Capability HOT 1
- The prop `getContent` is marked as required in `Communication`, but its value is `undefined`
- Starting but showing blank screen on hosting
- Can not get it to work. HOT 6
- Stucks after npm start or node server.js HOT 2
- Video Is Not Showing HOT 2
- Only Two Participants Can Join To The Meeting
- The prop marked as required in `CommunicationContainer`, but its value is `undefined` HOT 6
- Feature request: screen sharing
- Application Error HOT 1
- How to run this in dev with nodemon? HOT 1
- is this only work with same computer on different browsers. HOT 1
- Adding Multiple Users To Room? HOT 1
- Question for you Don HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from webrtc-video-room.