- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我收到一个错误,我的 TwilioVideo 模块需要一个捕获器(相机或麦克风),但没有接收到该输入。在我们切换到 Cocoapods 安装 SDK 和 PureLayout UI 库后,这个错误开始发生。之前我们手动将所有这些依赖项安装到 XCode 中。
我正在开发 React Native iOS 0.40.0 版本,react-native-cli 版本为 1.0.0。我正在使用 XCode 版本 8.2.1 (8C1002),iPhone 6 模拟器在 iOS 10.2 上运行。我正在使用 Cocoapods 1.2.0 版。我使用的是 TwilioVideo SDK 版本 1.0.0-beta5。还有一个 1.0.0-beta6 版本,我也试过了(结果相同)。恢复到版本 1.0.0-beta4 确实消除了错误,这对我来说表明我实现注册音频和视频轨道的方式存在问题。
这是我的 Pod 文件:
source 'https://github.com/CocoaPods/Specs'
source 'https://github.com/twilio/cocoapod-specs'
target 'MyApp' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for MyApp
pod 'TwilioVideo', '1.0.0-beta5'
pod 'PureLayout', '~> 3.0'
target 'MapleNativeProviderTests' do
inherit! :search_paths
# Pods for testing
end
end
我已经基于这个存储库在 XCode 中实现了一个 TwilioVideo 模块:react-native-twilio-video-webrtc .他最近更新了存储库以适用于 React Native 0.40.0,它更改了 XCode 的导入语法。我已经尝试使用旧的导入语法和新的导入语法,但当我尝试装载我的视频组件时,我继续收到以下错误:
这是 TwilioVideo SDK 的文档.这是 TVIVideoCapturer .
我对 react-native-twilio-video-webrtc 进行了修改,它本质上只是 TwilioVideo SDK 的一个薄包装器,使用 RCT_EXPORT_METHOD
来公开关键的 API 方法。该库在 init 方法中初始化音频和视频轨道,这会导致一些令人讨厌的行为,这些行为与应用程序启动时事件监听器不接收回调有关。因此,我将这些轨道移至名为 initialize
的自定义、公开的 RCT_EXPORT_METHOD
。这是我从应用程序中的特定 View 调用的,它安装视频并初始化相机/麦克风输入。
我对 TWVideoModule.m
的实现是:
#import "TWVideoModule.h"
static NSString* roomDidConnect = @"roomDidConnect";
static NSString* roomDidDisconnect = @"roomDidDisconnect";
static NSString* roomDidFailToConnect = @"roomDidFailToConnect";
static NSString* roomParticipantDidConnect = @"roomParticipantDidConnect";
static NSString* roomParticipantDidDisconnect = @"roomParticipantDidDisconnect";
static NSString* participantAddedVideoTrack = @"participantAddedVideoTrack";
static NSString* participantRemovedVideoTrack = @"participantRemovedVideoTrack";
static NSString* participantAddedAudioTrack = @"participantAddedAudioTrack";
static NSString* participantRemovedAudioTrack = @"participantRemovedAudioTrack";
static NSString* participantEnabledTrack = @"participantEnabledTrack";
static NSString* participantDisabledTrack = @"participantDisabledTrack";
static NSString* cameraDidStart = @"cameraDidStart";
static NSString* cameraWasInterrupted = @"cameraWasInterrupted";
static NSString* cameraDidStopRunning = @"cameraDidStopRunning";
@interface TWVideoModule () <TVIParticipantDelegate, TVIRoomDelegate, TVIVideoTrackDelegate, TVICameraCapturerDelegate>
@end
@implementation TWVideoModule
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
- (NSArray<NSString *> *)supportedEvents
{
return @[roomDidConnect,
roomDidDisconnect,
roomDidFailToConnect,
roomParticipantDidConnect,
roomParticipantDidDisconnect,
participantAddedVideoTrack,
participantRemovedVideoTrack,
participantAddedAudioTrack,
participantRemovedAudioTrack,
participantEnabledTrack,
participantDisabledTrack,
cameraDidStopRunning,
cameraDidStart,
cameraWasInterrupted];
}
- (instancetype)init
{
self = [super init];
if (self) {
UIView* remoteMediaView = [[UIView alloc] init];
//remoteMediaView.backgroundColor = [UIColor blueColor];
//remoteMediaView.translatesAutoresizingMaskIntoConstraints = NO;
self.remoteMediaView = remoteMediaView;
UIView* previewView = [[UIView alloc] init];
//previewView.backgroundColor = [UIColor yellowColor];
//previewView.translatesAutoresizingMaskIntoConstraints = NO;
self.previewView = previewView;
}
return self;
}
- (void)dealloc
{
[self.remoteMediaView removeFromSuperview];
self.remoteMediaView = nil;
[self.previewView removeFromSuperview];
self.previewView = nil;
self.participant = nil;
self.localMedia = nil;
self.camera = nil;
self.localVideoTrack = nil;
self.videoClient = nil;
self.room = nil;
}
RCT_EXPORT_METHOD(initialize) {
self.localMedia = [[TVILocalMedia alloc] init];
self.camera = [[TVICameraCapturer alloc] init];
NSLog(@"Camera %@", self.camera);
self.camera.delegate = self;
self.localVideoTrack = [self.localMedia addVideoTrack:YES
capturer:self.camera
constraints:[self videoConstraints]
error:nil];
self.localAudioTrack = [self.localMedia addAudioTrack:YES];
if (!self.localVideoTrack) {
NSLog(@"Failed to add video track");
} else {
// Attach view to video track for local preview
[self.localVideoTrack attach:self.previewView];
}
}
此文件的其余部分与添加和删除轨道以及加入/断开 Twilio channel 有关,因此我没有包含它。我还有 TWVideoPreviewManager
和 TWRemotePreviewManager
,它们只是为本地和远程视频流的媒体对象提供 UIView。
我的 TwilioVideoComponent.js
组件是:
import React, { Component, PropTypes } from 'react'
import {
NativeModules,
NativeEventEmitter
} from 'react-native';
import {
View,
} from 'native-base';
const {TWVideoModule} = NativeModules;
class TwilioVideoComponent extends Component {
state = {};
static propTypes = {
onRoomDidConnect: PropTypes.func,
onRoomDidDisconnect: PropTypes.func,
onRoomDidFailToConnect: PropTypes.func,
onRoomParticipantDidConnect: PropTypes.func,
onRoomParticipantDidDisconnect: PropTypes.func,
onParticipantAddedVideoTrack: PropTypes.func,
onParticipantRemovedVideoTrack: PropTypes.func,
onParticipantAddedAudioTrack: PropTypes.func,
onParticipantRemovedAudioTrack: PropTypes.func,
onParticipantEnabledTrack: PropTypes.func,
onParticipantDisabledTrack: PropTypes.func,
onCameraDidStart: PropTypes.func,
onCameraWasInterrupted: PropTypes.func,
onCameraDidStopRunning: PropTypes.func,
...View.propTypes,
};
_subscriptions = [];
constructor(props) {
super(props);
this.flipCamera = this.flipCamera.bind(this);
this.startCall = this.startCall.bind(this);
this.endCall = this.endCall.bind(this);
this._eventEmitter = new NativeEventEmitter(TWVideoModule)
}
//
// Methods
/**
* Initializes camera and microphone tracks
*/
initializeVideo() {
TWVideoModule.initialize();
}
flipCamera() {
TWVideoModule.flipCamera();
}
startCall({roomName, accessToken}) {
TWVideoModule.startCallWithAccessToken(accessToken, roomName);
}
endCall() {
TWVideoModule.disconnect();
}
toggleVideo() {
TWVideoModule.toggleVideo();
}
toggleAudio() {
TWVideoModule.toggleAudio();
}
_unregisterEvents() {
this._subscriptions.forEach(e => e.remove());
this._subscriptions = []
}
_registerEvents() {
this._subscriptions = [
this._eventEmitter.addListener('roomDidConnect', (data) => {
if (this.props.onRoomDidConnect) {
this.props.onRoomDidConnect(data)
}
}),
this._eventEmitter.addListener('roomDidDisconnect', (data) => {
if (this.props.onRoomDidDisconnect) {
this.props.onRoomDidDisconnect(data)
}
}),
this._eventEmitter.addListener('roomDidFailToConnect', (data) => {
if (this.props.onRoomDidFailToConnect) {
this.props.onRoomDidFailToConnect(data)
}
}),
this._eventEmitter.addListener('roomParticipantDidConnect', (data) => {
if (this.props.onRoomParticipantDidConnect) {
this.props.onRoomParticipantDidConnect(data)
}
}),
this._eventEmitter.addListener('roomParticipantDidDisconnect', (data) => {
if (this.props.onRoomParticipantDidDisconnect) {
this.props.onRoomParticipantDidDisconnect(data)
}
}),
this._eventEmitter.addListener('participantAddedVideoTrack', (data) => {
if (this.props.onParticipantAddedVideoTrack) {
this.props.onParticipantAddedVideoTrack(data)
}
}),
this._eventEmitter.addListener('participantRemovedVideoTrack', (data) => {
if (this.props.onParticipantRemovedVideoTrack) {
this.props.onParticipantRemovedVideoTrack(data)
}
}),
this._eventEmitter.addListener('participantAddedAudioTrack', (data) => {
if (this.props.onParticipantAddedAudioTrack) {
this.props.onParticipantAddedAudioTrack(data)
}
}),
this._eventEmitter.addListener('participantRemovedAudioTrack', (data) => {
if (this.props.onParticipantRemovedAudioTrack) {
this.props.onParticipantRemovedAudioTrack(data)
}
}),
this._eventEmitter.addListener('participantEnabledTrack', (data) => {
if (this.props.onParticipantEnabledTrack) {
this.props.onParticipantEnabledTrack(data)
}
}),
this._eventEmitter.addListener('participantDisabledTrack', (data) => {
if (this.props.onParticipantDisabledTrack) {
this.props.onParticipantDisabledTrack(data)
}
}),
this._eventEmitter.addListener('cameraDidStart', (data) => {
if (this.props.onCameraDidStart) {
this.props.onCameraDidStart(data)
}
}),
this._eventEmitter.addListener('cameraWasInterrupted', (data) => {
if (this.props.onCameraWasInterrupted) {
this.props.onCameraWasInterrupted(data)
}
}),
this._eventEmitter.addListener('cameraDidStopRunning', (data) => {
if (this.props.onCameraDidStopRunning) {
this.props.onCameraDidStopRunning(data)
}
})
]
}
componentWillMount() {
this._eventEmitter.addListener('cameraDidStart', (data) => {
if (this.props.onCameraDidStart) {
this.props.onCameraDidStart(data)
}
});
this._registerEvents()
}
componentWillUnmount() {
this._unregisterEvents()
}
render() {
return this.props.children || null
}
}
export default TwilioVideoComponent;
我不确定如何修改 XCode 以兼容 TwilioVideo beta5 API。任何帮助将不胜感激。
最佳答案
在您的 podfile 中,查找 # use_frameworks!
并删除 #。
关于ios - Capturer(iPhone 摄像头)未提供给 TVIVideoCapturer for TwilioVideo iOS SDK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42075289/
我正在细读 http://www.khronos.org/网站,只找到了 OpenCL 的头文件(不是我不关心的 OpenGL)。如何获取 OpenCL SDK? 最佳答案 AMD 的 ATI Str
Android 项目中最低(最低 sdk)和最高(目标 sdk)级别是否有任何影响。这些东西是否会影响项目的可靠性和效率。 最佳答案 没有影响,如果您以 SDK 级别 8 为目标,那么您的应用将以 9
“min sdk version/target sdk version”和“compile sdk version”有什么区别?我知道 min 和 target sdk 是什么意思,但是 compil
我正在尝试运行 Dji Mobile-Sdk-Android:https://github.com/dji-sdk/Mobile-SDK-Android使用 dji 网站上的说明:https://de
我目前正在向我的 iPhone 应用程序添加新的 Facebook iOS sdk 3.1.1。我看到 sdk 有重大变化。例如。我的旧 sdk 创建一个 Facebook 对象并从 FBReques
我最近刚刚下载了 Xcode 4.6 with mac 10.8.4 with iOS 6.0 SDK package,我立即注意到我无法使用我的 iPhone 3Gs with iOS 4.6 进行
我尝试下载 OpenCL SDK。但是没办法。我有一个 AMD GPU,所以我在谷歌上搜索了 AMD SDK,但是来自谷歌的所有链接和一些教程都被破坏了,不可能通过 AMD 开发者网站找到 sdk。
安装 Google Cloud SDK 后,当我运行时 gcloud 授权登录 我收到一条错误消息: Your browser has been opened to visit: https://a
我一直在 nvidia 网站上搜索 GPU 计算 SDK,因为我正在尝试构建具有 cuda 支持的点云库 (PCL)。但是,在 nvidia 网站上,我只能找到工具包的链接,而不是 SDK 的单个下载
Closed. This question needs to be more focused。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅关注editing this post一个问题。 2
当我打开 Android SDK 管理器时,会出现一个屏幕“选择要安装的包”。它列出了一堆带有绿色复选标记(已经安装)的软件包,还有一些带有 x's 的软件包,它们没有安装。如果我选择“全部接受”,它
在开发过程中,我发布了 SDK 21 Lollipop,但我无法在我的 KitKat 设备上使用它。应用程序非常简单,我只将 SDK 用于动画和 Material 设计,但是当我尝试对 Play 商店
enter image description here friend 们好 在使用 Linux、jenkins 和 docker 探索 dotnet 核心时,我遇到了构建问题,该问题在标题“/usr
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我创建了一个flutter项目,运行flutter packages get,输出如下:【二】flutter包搞定等待另一个 flutter 命令释放启动锁...第二次运行“flutter packa
这个问题在这里已经有了答案: What are the Android SDK build-tools, platform-tools and tools? And which version sh
我使用 Corona SDK 已经快一年了,并且开发了几个简单的游戏。我现在正在寻找的是在 Corona SDK 中创建 3D 幻觉的某种方法。如果有人有 Corona 3D 方面的经验,我将不胜感激
我有一个CLDC 1.1 / MIDP 2.0项目,可以使用Java ME SDK 3.2很好地进行编译。 最近,我已将Java SE升级到8,结果Java ME SDK开始在Windows启动时显示
有没有办法以编程方式控制连接到华擎主板的 RGB 照明?我知道华硕有一个 Aura SDK,但华擎是否也有一个用于他们的硬件? 如果是,我在哪里可以找到它? 最佳答案 没有用于华擎多彩的 sdk。但是
如何使用 crm 2011 sdk 和 XrmServiceContext 创建事务? 在下一个示例中,'new_brand' 是一些自定义实体。我想创建三个品牌。第三个拥有错误的 OwnerID g
我是一名优秀的程序员,十分优秀!