在 react-native 中通过 WebRTC 访问摄像头的简单示例 (Android)
Simple example for accessing the camera via WebRTC in react-native (Android)
我正在尝试将我用 JS 编写的只能在 Firefox Android 上运行的增强现实应用程序改编为可以在 Android 或 iOS 上运行的 React 本机应用程序].因为我需要摄像头输入,所以我使用的是 react-native-webrtc(而不是导入我一直在使用的 html 和 js,因为我也在尝试减少帧率延迟)。我一直在尝试解析这里的演示:
https://github.com/oney/RCTWebRTCDemo/blob/master/main.js
但是演示应用程序非常复杂,因为它是一个视频聊天室(据我推测)。我只需要访问相机并将其保留为应用程序的背景即可。这是我目前所拥有的:
import React, { Component } from 'react';
import {
AppRegistry,
View,
} from 'react-native';
import {
RTCPeerConnection,
RTCMediaStream,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStreamTrack,
getUserMedia,
} from 'react-native-webrtc';
let localStream;
function getLocalStream(isFront, callback) {
MediaStreamTrack.getSources(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: false,
video: {
mandatory: {
minWidth: 500,
minHeight: 300,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: [{ sourceId: sourceInfos.id}]
}
}, function(stream) {
console.log("dddd", stream);
callback(stream);
}, logError);
});
}
function logError(error) {
console.log("logError: ", error);
}
let container;
var CanvasTest = React.createClass({
getInitialState: function() {
return {
isFront: true,
selfViewSrc: null};
},
componentDidMount: function() {
container = this;
},
render() {
return (
<View>
<RTCView streamURL={this.state.selfViewSrc} />
{console.log("this.state: ", this.state)}
{getLocalStream(true, function(stream) {
//localStream = stream;
//container.setState({selfViewSrc: stream.toURL()});
})
}
</View>
);
}
});
AppRegistry.registerComponent('CanvasTest', () => CanvasTest);
一切正常,直到我尝试调用 getLocalStream 函数。我收到该行的 "undefined is not an object" 错误。 (我已经注释掉回调中的行以查看它们是否导致了问题,但它们不是)。
这是我在 Android Studio 中从控制台得到的:
E/ReactNativeJS: undefined is not an object (evaluating 'WebRTCModule.mediaStreamTrackGetSources')
E/EGL_emulation: tid 3106: eglSurfaceAttrib(1165): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xa0899300, error=EGL_BAD_MATCH
我想我在错误的地方调用了函数。我希望视图在应用程序启动时加载相机流。我做错了什么?
有没有更简单的例子在 React Native 中使用 WebRTC?
关于undefined is not an object
可能是没有安装好。
我建议重新启动一个全新的构建:
- 删除 npm 模块:
rm -rf $YourProject/node_modules/react-native-webrtc
- 清理 npm 缓存:
npm cache clean
- 清除gradle构建中间文件或
通过 Product
-> clean
清除 xocde 项目
(这取决于你的环境)
npm install react-native-webrtc
- 仔细按照文档逐步操作(Android / iOS)
确保授予文档中提及的所有权限,然后重试。
在哪里执行getLocalStream()
对于你的情况,你可以在ComponentDidMount
中执行它
否则,在某些情况下,应用程序可能会警告您不能 setState()
in render()
(setState()会正常触发render(),warning是为了防止死循环。)
建议
对于需要访问大量硬件功能的库,我建议您尽可能不要在模拟器上对其进行测试。
我正在尝试将我用 JS 编写的只能在 Firefox Android 上运行的增强现实应用程序改编为可以在 Android 或 iOS 上运行的 React 本机应用程序].因为我需要摄像头输入,所以我使用的是 react-native-webrtc(而不是导入我一直在使用的 html 和 js,因为我也在尝试减少帧率延迟)。我一直在尝试解析这里的演示:
https://github.com/oney/RCTWebRTCDemo/blob/master/main.js
但是演示应用程序非常复杂,因为它是一个视频聊天室(据我推测)。我只需要访问相机并将其保留为应用程序的背景即可。这是我目前所拥有的:
import React, { Component } from 'react';
import {
AppRegistry,
View,
} from 'react-native';
import {
RTCPeerConnection,
RTCMediaStream,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStreamTrack,
getUserMedia,
} from 'react-native-webrtc';
let localStream;
function getLocalStream(isFront, callback) {
MediaStreamTrack.getSources(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: false,
video: {
mandatory: {
minWidth: 500,
minHeight: 300,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: [{ sourceId: sourceInfos.id}]
}
}, function(stream) {
console.log("dddd", stream);
callback(stream);
}, logError);
});
}
function logError(error) {
console.log("logError: ", error);
}
let container;
var CanvasTest = React.createClass({
getInitialState: function() {
return {
isFront: true,
selfViewSrc: null};
},
componentDidMount: function() {
container = this;
},
render() {
return (
<View>
<RTCView streamURL={this.state.selfViewSrc} />
{console.log("this.state: ", this.state)}
{getLocalStream(true, function(stream) {
//localStream = stream;
//container.setState({selfViewSrc: stream.toURL()});
})
}
</View>
);
}
});
AppRegistry.registerComponent('CanvasTest', () => CanvasTest);
一切正常,直到我尝试调用 getLocalStream 函数。我收到该行的 "undefined is not an object" 错误。 (我已经注释掉回调中的行以查看它们是否导致了问题,但它们不是)。
这是我在 Android Studio 中从控制台得到的:
E/ReactNativeJS: undefined is not an object (evaluating 'WebRTCModule.mediaStreamTrackGetSources')
E/EGL_emulation: tid 3106: eglSurfaceAttrib(1165): error 0x3009 (EGL_BAD_MATCH)
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xa0899300, error=EGL_BAD_MATCH
我想我在错误的地方调用了函数。我希望视图在应用程序启动时加载相机流。我做错了什么?
有没有更简单的例子在 React Native 中使用 WebRTC?
关于undefined is not an object
可能是没有安装好。
我建议重新启动一个全新的构建:
- 删除 npm 模块:
rm -rf $YourProject/node_modules/react-native-webrtc
- 清理 npm 缓存:
npm cache clean
- 清除gradle构建中间文件或
通过Product
->clean
清除 xocde 项目 (这取决于你的环境) npm install react-native-webrtc
- 仔细按照文档逐步操作(Android / iOS)
确保授予文档中提及的所有权限,然后重试。
在哪里执行getLocalStream()
对于你的情况,你可以在ComponentDidMount
中执行它
否则,在某些情况下,应用程序可能会警告您不能 setState()
in render()
(setState()会正常触发render(),warning是为了防止死循环。)
建议
对于需要访问大量硬件功能的库,我建议您尽可能不要在模拟器上对其进行测试。