186 lines
7.2 KiB
Swift
186 lines
7.2 KiB
Swift
//
|
||
// PlayContoller11.swift
|
||
// tdvideo
|
||
//
|
||
// Created by mac on 2024/2/22.
|
||
//
|
||
|
||
|
||
import UIKit
|
||
import AVFoundation
|
||
|
||
class PlayContoller11: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
|
||
|
||
var session = AVCaptureMultiCamSession()
|
||
var backCameraDeviceInput: AVCaptureDeviceInput?
|
||
var frontCameraDeviceInput: AVCaptureDeviceInput?
|
||
var backCameraVideoPreviewLayer: AVCaptureVideoPreviewLayer?
|
||
var frontCameraVideoPreviewLayer: AVCaptureVideoPreviewLayer?
|
||
var backCameraVideoDataOutput: AVCaptureVideoDataOutput?
|
||
var frontCameraVideoDataOutput: AVCaptureVideoDataOutput?
|
||
var movieOutput: AVCaptureMovieFileOutput?
|
||
var isRecording = false
|
||
var recordButton:UIButton?
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
view.backgroundColor = .white
|
||
|
||
self.configureSession()
|
||
self.addRecordButton()
|
||
}
|
||
|
||
private func configureSession() {
|
||
session.beginConfiguration()
|
||
defer {
|
||
session.commitConfiguration()
|
||
}
|
||
|
||
// 配置后置摄像头
|
||
guard let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
|
||
print("Could not find the back camera")
|
||
return
|
||
}
|
||
|
||
do {
|
||
backCameraDeviceInput = try AVCaptureDeviceInput(device: backCamera)
|
||
|
||
guard let backCameraDeviceInput = backCameraDeviceInput,
|
||
session.canAddInput(backCameraDeviceInput) else {
|
||
print("Could not add back camera input")
|
||
return
|
||
}
|
||
session.addInput(backCameraDeviceInput)
|
||
} catch {
|
||
print("Could not create back camera device input: \(error)")
|
||
return
|
||
}
|
||
|
||
// 配置前置摄像头
|
||
guard let frontCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) else {
|
||
print("Could not find the front camera")
|
||
return
|
||
}
|
||
|
||
do {
|
||
frontCameraDeviceInput = try AVCaptureDeviceInput(device: frontCamera)
|
||
|
||
guard let frontCameraDeviceInput = frontCameraDeviceInput,
|
||
session.canAddInput(frontCameraDeviceInput) else {
|
||
print("Could not add front camera input")
|
||
return
|
||
}
|
||
session.addInput(frontCameraDeviceInput)
|
||
} catch {
|
||
print("Could not create front camera device input: \(error)")
|
||
return
|
||
}
|
||
|
||
// 配置预览图层
|
||
backCameraVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
|
||
backCameraVideoPreviewLayer?.frame = CGRect(x: 0, y: 0, width: view.frame.size.width / 2, height: view.frame.size.height / 2)
|
||
if let backCameraVideoPreviewLayer = backCameraVideoPreviewLayer {
|
||
view.layer.addSublayer(backCameraVideoPreviewLayer)
|
||
}
|
||
|
||
frontCameraVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
|
||
frontCameraVideoPreviewLayer?.frame = CGRect(x: view.frame.size.width / 2, y: 0, width: view.frame.size.width / 2, height: view.frame.size.height / 2)
|
||
if let frontCameraVideoPreviewLayer = frontCameraVideoPreviewLayer {
|
||
view.layer.addSublayer(frontCameraVideoPreviewLayer)
|
||
}
|
||
|
||
// 配置后置摄像头视频数据输出
|
||
backCameraVideoDataOutput = AVCaptureVideoDataOutput()
|
||
backCameraVideoDataOutput?.setSampleBufferDelegate(self, queue: DispatchQueue(label: "backCameraVideoDataOutputQueue"))
|
||
if let backCameraVideoDataOutput = backCameraVideoDataOutput,
|
||
session.canAddOutput(backCameraVideoDataOutput) {
|
||
session.addOutput(backCameraVideoDataOutput)
|
||
}
|
||
|
||
// 配置前置摄像头视频数据输出
|
||
frontCameraVideoDataOutput = AVCaptureVideoDataOutput()
|
||
frontCameraVideoDataOutput?.setSampleBufferDelegate(self, queue: DispatchQueue(label: "frontCameraVideoDataOutputQueue"))
|
||
if let frontCameraVideoDataOutput = frontCameraVideoDataOutput,
|
||
session.canAddOutput(frontCameraVideoDataOutput) {
|
||
session.addOutput(frontCameraVideoDataOutput)
|
||
}
|
||
|
||
// 配置电影输出
|
||
movieOutput = AVCaptureMovieFileOutput()
|
||
if let movieOutput = movieOutput, session.canAddOutput(movieOutput) {
|
||
session.addOutput(movieOutput)
|
||
}
|
||
|
||
DispatchQueue.global().async {
|
||
self.session.startRunning()
|
||
}
|
||
}
|
||
|
||
private func addRecordButton() {
|
||
recordButton = UIButton(type: .system)
|
||
recordButton!.setTitle("开始录制", for: .normal)
|
||
recordButton!.addTarget(self, action: #selector(toggleRecording), for: .touchUpInside)
|
||
recordButton!.frame = CGRect(x: 50, y: view.frame.height - 200, width: 200, height: 50)
|
||
view.addSubview(recordButton!)
|
||
}
|
||
|
||
@objc private func toggleRecording() {
|
||
if isRecording {
|
||
stopRecording()
|
||
} else {
|
||
startRecording()
|
||
}
|
||
}
|
||
|
||
private func startRecording() {
|
||
guard let movieOutput = movieOutput else { return }
|
||
|
||
let outputURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("output.mov")
|
||
movieOutput.startRecording(to: outputURL, recordingDelegate: self)
|
||
isRecording = true
|
||
recordButton!.setTitle("停止录制", for: .normal)
|
||
}
|
||
|
||
private func stopRecording() {
|
||
guard let movieOutput = movieOutput else { return }
|
||
|
||
movieOutput.stopRecording()
|
||
isRecording = false
|
||
recordButton!.setTitle("开始录制", for: .normal)
|
||
}
|
||
|
||
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
||
// 获取视频数据
|
||
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
|
||
return
|
||
}
|
||
|
||
// 判断是前置摄像头还是后置摄像头
|
||
if isRecording {
|
||
if connection.inputPorts.contains(where: { $0.mediaType == .video && $0.sourceDeviceType == .builtInWideAngleCamera && $0.sourceDevicePosition == .back }) {
|
||
print("后置摄像头视频数据")
|
||
} else if connection.inputPorts.contains(where: { $0.mediaType == .video && $0.sourceDeviceType == .builtInWideAngleCamera && $0.sourceDevicePosition == .front }) {
|
||
print("前置摄像头视频数据")
|
||
}
|
||
}
|
||
|
||
// 在这里进行视频数据的处理,例如打印像素数据等
|
||
// 注意:在这里处理视频数据会影响性能,请谨慎使用
|
||
}
|
||
|
||
}
|
||
|
||
extension PlayContoller11: AVCaptureFileOutputRecordingDelegate {
|
||
func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
|
||
print("开始录制")
|
||
}
|
||
|
||
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
|
||
if let error = error {
|
||
print("录制出错:\(error.localizedDescription)")
|
||
} else {
|
||
print("录制完成:\(outputFileURL)")
|
||
}
|
||
}
|
||
}
|