iOS SWIFT - WebRTC从前置摄像头更改为后置摄像头

时间:2017-03-10 07:34:54

标签: ios swift3 webrtc

WebRTC视频默认使用前置摄像头,工作正常。但是,我需要将其切换到后置摄像头,我无法找到任何代码来执行此操作。 我需要编辑哪个部分? 是localView还是localVideoTrack或capturer?

6 个答案:

答案 0 :(得分:2)

Swift 3.0

对等连接只能有一个'RTCVideoTrack'用于发送视频流。

首先,要更改相机前/后,您必须删除对等连接上的当前视频轨道。 之后,您需要在相机上创建新的“RTCVideoTrack”,并将其设置为对等连接。

我用过这种方法。

func swapCameraToFront() {
    let localStream: RTCMediaStream? = peerConnection?.localStreams.first as? RTCMediaStream
    localStream?.removeVideoTrack(localStream?.videoTracks.first as! RTCVideoTrack)
    let localVideoTrack: RTCVideoTrack? = createLocalVideoTrack()
    if localVideoTrack != nil {
        localStream?.addVideoTrack(localVideoTrack)
        delegate?.appClient(self, didReceiveLocalVideoTrack: localVideoTrack!)
    }
    peerConnection?.remove(localStream)
    peerConnection?.add(localStream)
}

func swapCameraToBack() {
    let localStream: RTCMediaStream? = peerConnection?.localStreams.first as? RTCMediaStream
    localStream?.removeVideoTrack(localStream?.videoTracks.first as! RTCVideoTrack)
    let localVideoTrack: RTCVideoTrack? = createLocalVideoTrackBackCamera()
    if localVideoTrack != nil {
        localStream?.addVideoTrack(localVideoTrack)
        delegate?.appClient(self, didReceiveLocalVideoTrack: localVideoTrack!)
    }
    peerConnection?.remove(localStream)
    peerConnection?.add(localStream)
}

答案 1 :(得分:2)

到目前为止,我只能用Objective C语言获得有关 Ankit 评论的答案。我会在一段时间后将其转换为Swift

您可以查看以下代码

- (RTCVideoTrack *)createLocalVideoTrack {

    RTCVideoTrack *localVideoTrack = nil; 
    NSString *cameraID = nil; 
    for (AVCaptureDevice *captureDevice in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
       if (captureDevice.position == AVCaptureDevicePositionFront) { 
        cameraID = [captureDevice localizedName]; break;
       }
    }

    RTCVideoCapturer *capturer = [RTCVideoCapturer capturerWithDeviceName:cameraID]; 
    RTCMediaConstraints *mediaConstraints = [self defaultMediaStreamConstraints]; 
    RTCVideoSource *videoSource = [_factory videoSourceWithCapturer:capturer constraints:mediaConstraints]; 
    localVideoTrack = [_factory videoTrackWithID:@"ARDAMSv0" source:videoSource];

       return localVideoTrack; 
   }

- (RTCVideoTrack *)createLocalVideoTrackBackCamera {
    RTCVideoTrack *localVideoTrack = nil;
    //AVCaptureDevicePositionFront
    NSString *cameraID = nil;
    for (AVCaptureDevice *captureDevice in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
     if (captureDevice.position == AVCaptureDevicePositionBack) {
         cameraID = [captureDevice localizedName];
         break;
     }
    }

  RTCVideoCapturer *capturer = [RTCVideoCapturer capturerWithDeviceName:cameraID];
  RTCMediaConstraints *mediaConstraints = [self defaultMediaStreamConstraints];
  RTCVideoSource *videoSource = [_factory videoSourceWithCapturer:capturer constraints:mediaConstraints];
  localVideoTrack = [_factory videoTrackWithID:@"ARDAMSv0" source:videoSource];

  return localVideoTrack;
}

答案 2 :(得分:0)

我不确定你用于webrtc的是哪个chrome版本,但是对于v54及以上版本,有" bool"被称为" useBackCamera"在RTCAVFoundationVideoSource类中。您可以使用此属性在前/后相机之间切换。

答案 3 :(得分:0)

如果您决定在此使用官方Google版本,请说明:

首先,您必须在致电开始前配置您的相机,在方法ARDVideoCallViewDelegate

didCreateLocalCapturer执行此操作的最佳位置
- (void)startCapture:(void (^)(BOOL succeeded))completionHandler {
    AVCaptureDevicePosition position = _usingFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
    __weak AVCaptureDevice *device = [self findDeviceForPosition:position];
    if ([device lockForConfiguration:nil]) {
        if ([device isFocusPointOfInterestSupported]) {
            [device setFocusModeLockedWithLensPosition:0.9 completionHandler: nil];
        }
    }
    AVCaptureDeviceFormat *format = [self selectFormatForDevice:device];
    if (format == nil) {
        RTCLogError(@"No valid formats for device %@", device);
        NSAssert(NO, @"");
        return;
    }
    NSInteger fps = [self selectFpsForFormat:format];
    [_capturer startCaptureWithDevice: device
                               format: format
                                  fps:fps completionHandler:^(NSError *    error) {
                                      NSLog(@"%@",error);
                                      if (error == nil) {
                                          completionHandler(true);
                                      }
                                  }];
}

不要忘记启用捕获设备是异步的,有时更好地使用完成以确保按预期完成所有操作。

答案 4 :(得分:0)

Swift 4.0和“ GoogleWebRTC”:“ 1.1.20913”

RTCAVFoundationVideoSource 类具有名为 useBackCamera 的属性,该属性可用于切换使用的摄像机。

@interface RTCAVFoundationVideoSource : RTCVideoSource

- (instancetype)init NS_UNAVAILABLE;

/**
* Calling this function will cause frames to be scaled down to the
* requested resolution. Also, frames will be cropped to match the
* requested aspect ratio, and frames will be dropped to match the
* requested fps. The requested aspect ratio is orientation agnostic and
* will be adjusted to maintain the input orientation, so it doesn't
* matter if e.g. 1280x720 or 720x1280 is requested.
*/
- (void)adaptOutputFormatToWidth:(int)width height:(int)height fps:(int)fps;

/** Returns whether rear-facing camera is available for use. */
@property(nonatomic, readonly) BOOL canUseBackCamera;

/** Switches the camera being used (either front or back). */
@property(nonatomic, assign) BOOL useBackCamera;

/** Returns the active capture session. */
@property(nonatomic, readonly) AVCaptureSession *captureSession;

下面是切换摄像头的实现。

var useBackCamera: Bool = false

func switchCamera() {
    useBackCamera = !useBackCamera
    self.switchCamera(useBackCamera: useBackCamera)
}

private func switchCamera(useBackCamera: Bool) -> Void {

    let localStream = peerConnection?.localStreams.first

    if let videoTrack = localStream?.videoTracks.first {
        localStream?.removeVideoTrack(videoTrack)
    }

    let localVideoTrack = createLocalVideoTrack(useBackCamera: useBackCamera)
    localStream?.addVideoTrack(localVideoTrack)

    self.delegate?.webRTCClientDidAddLocal(videoTrack: localVideoTrack)

    if let ls = localStream {
        peerConnection?.remove(ls)
        peerConnection?.add(ls)
    }
}

func createLocalVideoTrack(useBackCamera: Bool) -> RTCVideoTrack {

    let videoSource = self.factory.avFoundationVideoSource(with: self.constraints)
    videoSource.useBackCamera = useBackCamera
    let videoTrack = self.factory.videoTrack(with: videoSource, trackId: "video")
    return videoTrack
}

答案 5 :(得分:0)

在当前版本的 WebRTC 中,RTCAVFoundationVideoSource已deprecated并替换为 通用RTCVideoSource与RTCVideoCapturer实现相结合。

为了切换相机,我正在这样做:

- (void)switchCameraToPosition:(AVCaptureDevicePosition)position completionHandler:(void (^)(void))completionHandler {
    if (self.cameraPosition != position) {
      RTCMediaStream *localStream = self.peerConnection.localStreams.firstObject;
      [localStream removeVideoTrack:self.localVideoTrack];
      //[self.peerConnection removeStream:localStream];
      self.localVideoTrack = [self createVideoTrack];

      [self startCaptureLocalVideoWithPosition:position completionHandler:^{
        [localStream addVideoTrack:self.localVideoTrack];
        //[self.peerConnection addStream:localStream];
        if (completionHandler) {
            completionHandler();
        }
      }];

      self.cameraPosition = position;
    }
}

看看注释行,如果您开始从对等连接中添加/删除流,则会导致视频连接延迟。

我正在使用GoogleWebRTC-1.1.25102