私はこのビデオをzindexで再生しています:-1ボタンとその上に浮かんだテキスト入力。問題は、テキストが変更されたとき、その状態オブジェクトを操作するはずであり、クリック可能なハイライトがクリック機能ではない場合です。機能したいときに機能します。私はこれをどのように修正すべきですか?
昨日の提案を使用すると、エラーが警告に変わります。入力ボックスに7つのランダムな文字を入力すると、「コンポーネントにメソッドをバインドしていることを警告します」という7つの警告が表示されます。これは、入力ボックスがタッチ可能なハイライトの機能を呼び出し続けていることを意味します。
私はこのライブラリをReact Nativeに使用して、ストリーミング機能を使用しています:https://github.com/oney/react-native-webrtc。それはかなり良いです!私は、テキストフィールドにテキストを入力すると
_renderTextRoom() {
return (
<View style={styles.listViewContainer}>
<ListView
dataSource={this.ds.cloneWithRows(this.state.textRoomData)}
enableEmptySections={true}
renderRow={rowData =>
<Text
style={styles.whiteOut}
>{`${rowData.user}: ${rowData.message}`}</Text>}
/>
<TextInput
style={[styles.whiteOut, styles.bgWhite]}
onChangeText={value => this.setState({ textRoomValue: value })}
value={this.state.textRoomValue}
/>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
</View>
);
},
、this._textRoomPress()関数はTouchableHighlight内にネスト:それの例の一つで
、https://github.com/oney/RCTWebRTCDemo/blob/master/main.js私はいじるいるコードのこれらの行があります発砲している。何!?私がコメントアウトすると、それは起動しません。
'use strict';
import React, { Component } from 'react';
import {
Dimensions,
StyleSheet,
Text,
TouchableHighlight,
View,
TextInput,
ListView,
ScrollView
} from 'react-native';
import { userData } from '../utils/Factory';
import io from 'socket.io-client';
var socket_one = 'https://xxxxxxxxxxxxxx.herokuapp.com';
const socket = io.connect(socket_one, { transports: ['websocket'] });
import {
RTCPeerConnection,
RTCMediaStream,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStreamTrack,
getUserMedia,
} from 'react-native-webrtc';
const configuration = { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] };
const pcPeers = {};
let localStream;
var width = Dimensions.get('window').width; //full width
var height = Dimensions.get('window').height; //full height
function getLocalStream(isFront, callback) {
MediaStreamTrack.getSources(sourceInfos => {
console.log(sourceInfos);
let videoSourceId;
for (const i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i];
if (sourceInfo.kind == "video" && sourceInfo.facing == (isFront ? "front" : "back")) {
videoSourceId = sourceInfo.id;
}
}
getUserMedia({
audio: true,
video: {
mandatory: {
minWidth: 700, // Provide your own width, height and frame rate here
minHeight: 700,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: [{ sourceId: sourceInfos.id }]
}
}, function(stream) {
console.log('dddd', stream);
callback(stream);
}, logError);
});
}
function join(roomID) {
socket.emit('join', roomID, function(socketIds) {
console.log('join', socketIds);
for (const i in socketIds) {
const socketId = socketIds[i];
createPC(socketId, true);
}
});
}
function createPC(socketId, isOffer) {
const pc = new RTCPeerConnection(configuration);
pcPeers[socketId] = pc;
pc.onicecandidate = function(event) {
// console.warn('onicecandidate', event.candidate);
if (event.candidate) {
socket.emit('exchange', { 'to': socketId, 'candidate': event.candidate });
}
};
function createOffer() {
pc.createOffer(function(desc) {
console.log('createOffer', desc);
pc.setLocalDescription(desc, function() {
console.log('setLocalDescription', pc.localDescription);
socket.emit('exchange', { 'to': socketId, 'sdp': pc.localDescription });
}, logError);
}, logError);
}
pc.onnegotiationneeded = function() {
console.log('onnegotiationneeded');
if (isOffer) {
createOffer();
}
}
pc.oniceconnectionstatechange = function(event) {
console.log('oniceconnectionstatechange', event.target.iceConnectionState);
if (event.target.iceConnectionState === 'completed') {
setTimeout(() => {
getStats();
}, 1000);
}
if (event.target.iceConnectionState === 'connected') {
createDataChannel();
}
};
pc.onsignalingstatechange = function(event) {
console.log('onsignalingstatechange', event.target.signalingState);
};
pc.onaddstream = function(event) {
console.log('onaddstream', event.stream);
// container.setState({ info: 'One peer join!' });
container.setState({ info: 'Connected!' });
const remoteList = container.state.remoteList;
remoteList[socketId] = event.stream.toURL();
container.setState({ remoteList: remoteList });
};
pc.onremovestream = function(event) {
console.log('onremovestream', event.stream);
};
pc.addStream(localStream);
function createDataChannel() {
if (pc.textDataChannel) {
return;
}
const dataChannel = pc.createDataChannel("text");
dataChannel.onerror = function(error) {
console.log("dataChannel.onerror", error);
};
dataChannel.onmessage = function(event) {
console.log("dataChannel.onmessage:", event.data);
container.receiveTextData({ user: socketId, message: event.data });
};
dataChannel.onopen = function() {
console.log('dataChannel.onopen');
container.setState({ textRoomConnected: true });
};
dataChannel.onclose = function() {
console.log("dataChannel.onclose");
};
pc.textDataChannel = dataChannel;
}
return pc;
}
function exchange(data) {
const fromId = data.from;
let pc;
if (fromId in pcPeers) {
pc = pcPeers[fromId];
} else {
pc = createPC(fromId, false);
}
if (data.sdp) {
console.log('exchange sdp', data);
pc.setRemoteDescription(new RTCSessionDescription(data.sdp), function() {
if (pc.remoteDescription.type == "offer")
pc.createAnswer(function(desc) {
console.log('createAnswer', desc);
pc.setLocalDescription(desc, function() {
console.log('setLocalDescription', pc.localDescription);
socket.emit('exchange', { 'to': fromId, 'sdp': pc.localDescription });
}, logError);
}, logError);
}, logError);
} else {
console.log('exchange candidate', data);
pc.addIceCandidate(new RTCIceCandidate(data.candidate));
}
}
function leave(socketId) {
console.log('leave', socketId);
const pc = pcPeers[socketId];
const viewIndex = pc.viewIndex;
pc.close();
delete pcPeers[socketId];
const remoteList = container.state.remoteList;
delete remoteList[socketId]
container.setState({ remoteList: remoteList });
container.setState({ info: 'One peer leave!' });
}
socket.on('exchange', function(data) {
exchange(data);
});
socket.on('leave', function(socketId) {
leave(socketId);
});
socket.on('connect', function(data) {
console.log('connected');
});
function initStream() {
getLocalStream(true, function(stream) {
localStream = stream;
container.setState({ selfViewSrc: stream.toURL() });
// container.setState({ status: 'ready', info: 'Please enter or create room ID' });
container.setState({ status: 'connect', info: 'Connecting' });
if (userData.inDanger) {
join(0);
} else {
join(userData.userName);
// join(userData.nowPlaying);
}
});
}
function logError(error) {
console.log("logError", error);
}
function mapHash(hash, func) {
const array = [];
for (const key in hash) {
const obj = hash[key];
array.push(func(obj, key));
}
return array;
}
function _textRoomPress() {
if (!container.textRoomValue) {
return
}
const textRoomData = container.textRoomData.slice();
textRoomData.push({ user: 'Me', message: container.textRoomValue });
for (const key in pcPeers) {
const pc = pcPeers[key];
pc.textDataChannel.send(container.textRoomValue);
}
container.setState({ textRoomData, textRoomValue: '' });
}
function getStats() {
const pc = pcPeers[Object.keys(pcPeers)[0]];
if (pc.getRemoteStreams()[0] && pc.getRemoteStreams()[0].getAudioTracks()[0]) {
const track = pc.getRemoteStreams()[0].getAudioTracks()[0];
console.log('track', track);
pc.getStats(track, function(report) {
console.log('getStats report', report);
}, logError);
}
}
let container;
const Stream = React.createClass({
getInitialState: function() {
this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => true });
return {
info: 'Initializing',
status: 'init',
roomID: '',
// isFront: true,
isFront: false,
selfViewSrc: null,
remoteList: {},
textRoomConnected: false,
textRoomData: [],
textRoomValue: '',
};
},
componentDidMount: function() {
container = this;
initStream();
},
_press(event) {
// this.refs.roomID.blur();
this.setState({ status: 'connect', info: 'Connecting' });
join(userData.userName);
// join(this.state.roomID);
},
_switchVideoType() {
const isFront = !this.state.isFront;
this.setState({ isFront });
getLocalStream(isFront, function(stream) {
if (localStream) {
for (const id in pcPeers) {
const pc = pcPeers[id];
pc && pc.removeStream(localStream);
}
localStream.release();
}
localStream = stream;
container.setState({ selfViewSrc: stream.toURL() });
for (const id in pcPeers) {
const pc = pcPeers[id];
pc && pc.addStream(localStream);
}
});
},
receiveTextData(data) {
const textRoomData = this.state.textRoomData.slice();
textRoomData.push(data);
this.setState({ textRoomData, textRoomValue: '' });
},
_textRoomPress() {
if (!this.state.textRoomValue) {
return
}
const textRoomData = this.state.textRoomData.slice();
textRoomData.push({ user: 'Me', message: this.state.textRoomValue });
for (const key in pcPeers) {
const pc = pcPeers[key];
pc.textDataChannel.send(this.state.textRoomValue);
}
this.setState({ textRoomData, textRoomValue: '' });
},
_renderTextRoom() {
return (
<View style={styles.listViewContainer}>
<ListView
dataSource={this.ds.cloneWithRows(this.state.textRoomData)}
enableEmptySections={true}
renderRow={rowData =>
<Text
style={styles.whiteOut}
>{`${rowData.user}: ${rowData.message}`}</Text>}
/>
<TextInput
style={[styles.whiteOut, styles.bgWhite]}
onChangeText={value => this.setState({ textRoomValue: value })}
value={this.state.textRoomValue}
/>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._textRoomPress()}>
<Text style={styles.bgWhite}>Send</Text>
</TouchableHighlight>
</View>
</View>
);
},
render() {
return (
<View style={styles.container}>
{
mapHash(this.state.remoteList, (remote, index) => {
return (
<ScrollView key={index}>
<RTCView key={index} streamURL={this.state.selfViewSrc} style={styles.remoteView}>
<View style={styles.buttonContainer}>
<TouchableHighlight
style={styles.button}
onPress={this._switchVideoType}>
<Text>Switch camera</Text>
</TouchableHighlight>
</View>
<View style={styles.bottomContainer}>
{this.state.textRoomConnected && this._renderTextRoom()}
</View>
</RTCView>
)
})
}
</View>
);
}
});
const styles = StyleSheet.create({
container: {
flex: 10,
// justifyContent: 'center',
backgroundColor: 'rgba(0,0,0, .0)',
},
topContainer: {
flex: 10,
backgroundColor: '#c7c7c7',
},
bottomContainer: {
flex: 1,
justifyContent: 'flex-end',
// backgroundColor: '#ffeeff',
'zIndex': 1,
backgroundColor: 'rgba(0,0,0, .0)',
},
selfView: {
width: 0,
height: 0
},
remoteView: {
flex: 1,
'zIndex': -1,
// backgroundColor: '#c7c7c7',
backgroundColor: '#f0f0f0',
width: width,
height: height - 25,
resizeMode: 'stretch', // or 'stretch'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
listViewContainer: {
height: 150,
},
buttonContainer: {
height: 50,
// backgroundColor: 'powderblue',
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginTop: 50,
marginBottom: 50,
padding: 10,
paddingLeft: 30,
paddingRight: 30,
borderWidth: 1,
borderColor: 'rgba(0, 0, 0, .75)',
},
whiteOut: {
// color: "#ffffff",
color: "#000",
},
bgWhite: {
// backgroundColor: "#ffffff"
},
listView: {
// backgroundColor: "#ffffff",
flex: 10,
// flexDirection: 'row',
// justifyContent: 'center',
// alignItems: 'center',
}
});
export default Stream;
自分自身を結合しないので、ES6矢印機能は、これが超簡単にします。推論は同じですが、関数を実行して戻り値に 'bind'を適用しています。あなたの関数は何も返さない可能性が高いので、 'undefined'を取得します。したがって、エラーです。 – martinarroyo
最後の質問ですが、なぜこのエラーが発生しますか?私はそれが拘束力のある問題だと確信しています。 undefinedは評価するオブジェクトではありません( 'pc.textDataChannel.send')。時にはそれが動作し、サーバーにデータを送信しますが、ほとんどの場合、データはサーバーに送信されません。ありがとうございます@martinarroyo – clxxxii
@clxxxiiそうかもしれないし、そうでないかもしれません。バインディングの問題は 'this'変数でアクセスする値にのみ影響します。そのような場合は、正しくバインドしていることを確認するか、コードを投稿して見てください。もう一つの可能性は、 'pc'か' textDataChannel'のどちらかが 'undefined'です。'undefined'値はプロパティを持たないため、アクセスできません。あなたがそれらの2つを更新している場所を確認してください(あなたは時にはそれが動作すると言いますから、あなたは何か値が変わっている可能性が高いと思います)。 – martinarroyo