使用相同的按钮拍照和录制视频 / avfoundation swift



目前,当我点击捕获照片按钮时,它会拍照并弹出预览,我可以将照片保存到相机胶卷中。

我想对视频做同样的事情,但我在录制视频甚至不知道如何开始时遇到问题。

我用过button.addTarget(self, action: #selector(handleCaptureVideo), for: .touchDown),它打印"视频正在录制..."所以我看到它可以工作,但我不知道放什么才能让视频真正开始录制。

import UIKit
import AVFoundation
class cameraController: UIViewController, AVCapturePhotoCaptureDelegate {
let capturePhotoButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(#imageLiteral(resourceName: "capture_photo"), for: .normal)
button.addTarget(self, action: #selector(handleCapturePhoto), for: .touchUpInside)
button.addTarget(self, action: #selector(handleCaptureVideo), for: .touchDown)
return button
}()
let settingsButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(#imageLiteral(resourceName: "gear"), for: .normal)
button.addTarget(self, action: #selector(handleSettings), for: .touchUpInside)
return button
}()
let cameraFlipButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(#imageLiteral(resourceName: "right_arrow_shadow"), for: .normal)
button.addTarget(self, action: #selector(handleReversingCamera), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
setupCameraSession()
setupHUD()
handleSettings()
handleReversingCamera()
}
override var prefersStatusBarHidden: Bool {
return true
}
fileprivate func setupHUD() {
view.addSubview(capturePhotoButton)
capturePhotoButton.anchor(top: nil, left: nil, bottom: view.bottomAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 24, paddingRight: 0, width: 80, height: 80)
capturePhotoButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
@objc func handleCaptureVideo() {
print("Video is recording...")
}
@objc func handleCapturePhoto() {
print("Capturing Photo...")
let settings = AVCapturePhotoSettings()
guard let previewFormatType = settings.availablePreviewPhotoPixelFormatTypes.first else { return }
settings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewFormatType]
output.capturePhoto(with: settings, delegate: self)
}
@objc func handleReversingCamera() {
view.addSubview(cameraFlipButton)
cameraFlipButton.anchor(top: nil, left: nil, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 48, paddingRight: 24, width: 50, height: 50)
print("Camera just flipped...")
}
@objc func handleSettings() {
view.addSubview(settingsButton)
settingsButton.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: nil, right: nil, paddingTop: 12, paddingLeft: 12, paddingBottom: 0, paddingRight: 0, width: 50, height: 50)
let goToSettings = settingsViewController()
let settingsController = UINavigationController(rootViewController: goToSettings)
present(settingsController, animated: true, completion: nil)
print("Settings Opened Up...")
}

func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer:
CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer!, previewPhotoSampleBuffer: previewPhotoSampleBuffer!)
let previewImage = UIImage(data: imageData!)
let containerView = PreviewPhotoContainerView()
containerView.previewImageView.image = previewImage
view.addSubview(containerView)
containerView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
/* let previewImageView = UIImageView(image: previewImage)
view.addSubview(previewImageView)
previewImageView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

print("Did finish processing sample image buffer") */
}

// Capture Photo
let output = AVCapturePhotoOutput()
fileprivate func setupCameraSession() {
let captureSession = AVCaptureSession()
// 1. Setup Inputs
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
do {
let input = try AVCaptureDeviceInput(device: captureDevice!)
if captureSession.canAddInput(input) {
captureSession.addInput(input)
}
} catch let err {
print("Could not print camera input:", err)
}
// 2. Setup Output
if captureSession.canAddOutput(output) {
captureSession.addOutput(output)
}
// 3. Setup Output Preview
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.frame
view.layer.addSublayer(previewLayer)
previewLayer.videoGravity = .resizeAspectFill
captureSession.startRunning()


}

您需要使用AVCaptureMovieFileOutput并将其添加到捕获会话中。要使用相同的按钮 - 您可以在按钮上安装长按手势识别器,并在长按时开始录制,在释放长按时停止录制。有点像Instagram的故事。

步骤 1

添加动画文件输出

var movieFileOutput = AVCaptureMovieFileOutput()
captureSession?.addOutput(movieFileOutput)

步骤 2

向按钮添加长按手势

let longPressGesture = UILongPressGestureRecognizer.init(target: self, action: #selector(handleLongPress))
self.capturePhotoButton.addGestureRecognizer(longPressGesture);

步骤 3

长按开始和停止录制视频

func handleLongPress(gestureRecognizer: UILongPressGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began {
debugPrint("long press started")
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
let filePath = documentsURL.appendingPathComponent("tempMovie.mp4")
if FileManager.default.fileExists(atPath: filePath.absoluteString) {
do {
try FileManager.default.removeItem(at: filePath)
}
catch {
// exception while deleting old cached file
// ignore error if any
}
}
movieFileOutput?.startRecording(toOutputFileURL: filePath, recordingDelegate: self)
}
else if gestureRecognizer.state == UIGestureRecognizerState.ended {
debugPrint("longpress ended")
movieFileOutput?.stopRecording()
}
}

最新更新