你的代码结构基本上是正确的,但需要进行一些小的调整来确保它可以正常工作。具体来说,你的 ContentView
应该符合 UIViewControllerRepresentable
协议,而不是直接继承自 UIViewController
。下面是一个更正后的代码示例:
import SwiftUI
import UIKit
import AVFoundation
struct ContentView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> CameraViewController {
return CameraViewController()
}
func updateUIViewController(_ uiViewController: CameraViewController, context: Context) {}
}
class CameraViewController: UIViewController {
var captureSession: AVCaptureSession!
var videoOutput: AVCaptureVideoDataOutput!
var videoFrames: [CMSampleBuffer] = []
override func viewDidLoad() {
super.viewDidLoad()
setupCamera()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 停止会话
captureSession?.stopRunning()
}
func setupCamera() {
captureSession = AVCaptureSession()
// 获取前置摄像头设备
guard let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) else {
print("无法找到前置摄像头")
return
}
do {
let input = try AVCaptureDeviceInput(device: camera)
if captureSession.canAddInput(input) {
captureSession.addInput(input)
}
// 创建视频输出,并设置代理
videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
if captureSession.canAddOutput(videoOutput) {
captureSession.addOutput(videoOutput)
}
// 启动会话
captureSession.startRunning()
} catch {
print("Error setting up camera input: \(error)")
}
}
}
extension CameraViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// 将每一帧样本缓冲区存储到数组中
videoFrames.append(sampleBuffer)
// 可以选择打印或处理视频帧,例如:
// print("Captured frame with timestamp \(CMSampleBufferGetPresentationTimeStamp(sampleBuffer))")
}
}
@main
struct myHelloWorldApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.edgesIgnoringSafeArea(.all) // Optional to cover the entire screen.
}
}
}
更改说明:
将
ContentView
改为实现UIViewControllerRepresentable
:- 这允许你在 SwiftUI 中使用 UIKit 的视图控制器。
创建新的
CameraViewController
类:- 将原来的逻辑移动到这个新的类中,以便它可以作为一个视图控制器来使用。
实现
makeUIViewController
和updateUIViewController
方法:- 这些方法是在 SwiftUI 中管理视图生命周期所需的方法。
通过以上修改,你的代码应该能够正常编译和运行,启动前置摄像头并捕获视频帧。
内容由零声教学AI助手提供,问题来源于学员提问