ios - 来自 iPhone X 和 iPhone 8 的 WebRTC 视频伪像

标签 ios objective-c video webrtc iphone-x

我有一个 iOS WebRTC 应用程序(带有 EasyRTC 包装器)。它适用于所有 iOS 设备,直到 iPhone X 问世。
问题是在其他设备上 iPhone X 的视频看起来像这样:

iphoneX broken video

iPhone X 的哪些变化导致了这种伪像?以及如何解决?

要开始播放我使用以下代码的视频:

@implementation WebRTCModule (RTCMediaStream)

- (RTCMediaConstraints *)defaultMediaStreamConstraints {
    NSDictionary *mandatoryConstraints
            = @{ kRTCMediaConstraintsMinWidth     : @"1280",
                 kRTCMediaConstraintsMinHeight    : @"720",
                 kRTCMediaConstraintsMinFrameRate : @"30" };
    RTCMediaConstraints* constraints =
    [[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints optionalConstraints:nil];
    return constraints;
}
typedef void (^NavigatorUserMediaErrorCallback)(NSString *errorType, NSString *errorMessage);
typedef void (^NavigatorUserMediaSuccessCallback)(RTCMediaStream *mediaStream);

- (void)getUserVideo:(NSDictionary *)constraints
    successCallback:(NavigatorUserMediaSuccessCallback)successCallback
      errorCallback:(NavigatorUserMediaErrorCallback)errorCallback
        mediaStream:(RTCMediaStream *)mediaStream {
    id videoConstraints = constraints[@"video"];
    AVCaptureDevice *videoDevice;
    if ([videoConstraints isKindOfClass:[NSDictionary class]]) {
        for (AVCaptureDevice *aVideoDevice in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
            if (aVideoDevice.position == AVCaptureDevicePositionFront) {
                videoDevice = aVideoDevice;
                break;
            }
        }
        if (!videoDevice) {
            videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        }
    }
    if (videoDevice) {
        RTCMediaConstraints* constraints = [self defaultMediaStreamConstraints];
        RTCAVFoundationVideoSource *videoSource = [self.peerConnectionFactory avFoundationVideoSourceWithConstraints:constraints];

        dispatch_queue_t backgroundQueue = dispatch_queue_create("com.app.videoquality", 0);
        dispatch_async(backgroundQueue, ^{
            videoSource.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
            switch (videoDevice.position) {
                case AVCaptureDevicePositionBack:
                    if (videoSource.canUseBackCamera) {
                        videoSource.useBackCamera = YES;
                    }
                break;
                    case AVCaptureDevicePositionFront:
                    videoSource.useBackCamera = NO;
                break;
            }
            NSString *trackUUID = [[NSUUID UUID] UUIDString];
            RTCVideoTrack *videoTrack = [self.peerConnectionFactory videoTrackWithSource:videoSource trackId:trackUUID];
            [mediaStream addVideoTrack:videoTrack];

            dispatch_async(dispatch_get_main_queue(), ^{
                successCallback(mediaStream);
            });
        });
    } else {
        errorCallback(@"OverconstrainedError", /* errorMessage */ nil);
    }
}
@end

我的猜测是 sessionPreset = AVCaptureSessionPresetHigh 在 iPhone X 中无法正常工作。但不幸的是我目前无法检查它。


更新。

从 iPhone 8 传输视频时观察到相同的行为。 但在装有 iOS 11.2.1 的 iPhone 7 上一切正常。


更新。 2

我已禁用此设置质量的自定义代码,但问题仍然存在。


更新。 3

这发生在 WebRTC 版本 58 上。

最佳答案

我在创建视频源后通过在 iPhone X 端设置这些代码解决了同样的问题

VideoSource.adaptOutputFormat(toWidth: 1280, height: 720, fps: 30);
VideoSource.captureSession.canSetSessionPreset(AVCaptureSessionPreset1280x720);

我没有 2 个 iPhone X 来测试用例没有设置这些代码。

关于ios - 来自 iPhone X 和 iPhone 8 的 WebRTC 视频伪像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47728488/

相关文章:

ios - 使用 iOS/swift 对 OAuth2 和 Eventbrite 进行身份验证时出现 “Oops, something went wrong” 错误

ios - 用户界面测试 : Click on UIcollectionview then testing it get failed

objective-c - 如何将数字转换为指示性字符串

python - YouTube视频上传

java - 在 Linux 上自动转码 H.264 视频

ios - HTTP 加载失败(错误代码 : -1200 [3:-9802])

ios - 与 RestKit 的嵌套对多关系

c++ - 包含 C++ 文件时构建失败

objective-c - 等到 UI 更新后再删除 UIActivityIndi​​cator

php - 使用 PHP 自动检测并在 html 内容中嵌入 MP4/MP3 链接