订阅 RxSwift Observable<VideoCaptureOutput> 不触发 onNext()
Subscription to RxSwift Observable<VideoCaptureOutput> not triggering onNext()
我想使用 RxSwift 处理从 iPhone 相机捕获的视频帧。我正在使用一个社区维护的项目,https://github.com/RxSwiftCommunity/RxAVFoundation,它连接了 AVFoundation(用于捕获相机输出)和 RxSwift。
我正在尝试在新视频帧写入输出缓冲区时只打印一个虚拟日志语句。以下是我的ViewController。我配置 AVCaptureSession,设置 Rx 链,然后启动会话。但是,永远不会触发 .next 情况下的打印语句。我联系了项目所有者。下面的代码是否正确?这是来自社区维护项目的 AVCaptureSession class 的 Reactive 扩展:https://github.com/RxSwiftCommunity/RxAVFoundation/blob/master/RxAVFoundation/AVCaptureSession%2BRx.swift
// ViewController.swift
import UIKit
import AVFoundation
import RxSwift
class ViewController: UIViewController {
// capture session
private let session = AVCaptureSession()
private var videoDevice: AVCaptureDevice!
override func viewDidLoad() {
super.viewDidLoad()
self.videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
session
.rx
.configure(captureDevice: videoDevice)
let disposeBag = DisposeBag()
let videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_32BGRA)] as [String : Any]
session
.rx
.videoCaptureOutput(settings: videoSettings)
.observeOn(MainScheduler.instance)
.subscribe { [unowned self] (event) in
switch event {
case .next(let captureOutput):
print("got a frame")
case .error(let error):
print("error: %@", "\(error)")
case .completed:
break // never happens
}
}
.disposed(by: disposeBag)
session
.rx
.startRunning()
}
}
因为您已经在 viewDidLoad
中本地定义了 DisposeBag
,一旦 viewDidLoad
完成,所有添加到包中的订阅都会被处理掉。
将您的 DisposeBag
声明为要修复的 ViewController
的实例变量:
...
// capture session
private let session = AVCaptureSession()
private var videoDevice: AVCaptureDevice!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
...
使用 .debug()
是捕获此类事件的好方法,因为它会打印所有事件,包括处置,例如:
session
.rx
.videoCaptureOutput(settings: videoSettings)
.observeOn(MainScheduler.instance)
.debug("Video Capture Output Observable:")
.subscribe { [unowned self] (event) in
switch event {
case .next(let captureOutput):
print("got a frame")
case .error(let error):
print("error: %@", "\(error)")
case .completed:
break // never happens
}
}
.disposed(by: disposeBag)
我想使用 RxSwift 处理从 iPhone 相机捕获的视频帧。我正在使用一个社区维护的项目,https://github.com/RxSwiftCommunity/RxAVFoundation,它连接了 AVFoundation(用于捕获相机输出)和 RxSwift。
我正在尝试在新视频帧写入输出缓冲区时只打印一个虚拟日志语句。以下是我的ViewController。我配置 AVCaptureSession,设置 Rx 链,然后启动会话。但是,永远不会触发 .next 情况下的打印语句。我联系了项目所有者。下面的代码是否正确?这是来自社区维护项目的 AVCaptureSession class 的 Reactive 扩展:https://github.com/RxSwiftCommunity/RxAVFoundation/blob/master/RxAVFoundation/AVCaptureSession%2BRx.swift
// ViewController.swift
import UIKit
import AVFoundation
import RxSwift
class ViewController: UIViewController {
// capture session
private let session = AVCaptureSession()
private var videoDevice: AVCaptureDevice!
override func viewDidLoad() {
super.viewDidLoad()
self.videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
session
.rx
.configure(captureDevice: videoDevice)
let disposeBag = DisposeBag()
let videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_32BGRA)] as [String : Any]
session
.rx
.videoCaptureOutput(settings: videoSettings)
.observeOn(MainScheduler.instance)
.subscribe { [unowned self] (event) in
switch event {
case .next(let captureOutput):
print("got a frame")
case .error(let error):
print("error: %@", "\(error)")
case .completed:
break // never happens
}
}
.disposed(by: disposeBag)
session
.rx
.startRunning()
}
}
因为您已经在 viewDidLoad
中本地定义了 DisposeBag
,一旦 viewDidLoad
完成,所有添加到包中的订阅都会被处理掉。
将您的 DisposeBag
声明为要修复的 ViewController
的实例变量:
...
// capture session
private let session = AVCaptureSession()
private var videoDevice: AVCaptureDevice!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
...
使用 .debug()
是捕获此类事件的好方法,因为它会打印所有事件,包括处置,例如:
session
.rx
.videoCaptureOutput(settings: videoSettings)
.observeOn(MainScheduler.instance)
.debug("Video Capture Output Observable:")
.subscribe { [unowned self] (event) in
switch event {
case .next(let captureOutput):
print("got a frame")
case .error(let error):
print("error: %@", "\(error)")
case .completed:
break // never happens
}
}
.disposed(by: disposeBag)