У меня проблема с записью видео.
Поток, как: -
- Я открою экран моей камеры.
- запишет видео, затем перейдет к созданию экрана поста.
- Этот поток отлично работает в первый раз. Но когда я вернулся на камеру с экрана создания поста и снова попытался записать, он внезапно останавливает запись, как только я запускаю, и выдает ошибку «такого файла нет».
Любая помощь будет оценена.
Спасибо.
var captureSession: AVCaptureSession?
var capturePhotoOutput: AVCapturePhotoOutput?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var userSelectedFlashMode: AVCaptureDevice.FlashMode = .off
var movieFileOutput = AVCaptureMovieFileOutput()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
captureSession = AVCaptureSession()
captureSession?.beginConfiguration()
let microphone = AVCaptureDevice.default(for: AVMediaType.audio)
do {
let micInput = try AVCaptureDeviceInput(device: microphone!)
if (captureSession?.canAddInput(micInput))! {
captureSession?.addInput(micInput)
}
} catch {
print("SRL Error setting device audio input.")
}
guard let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back) else {
fatalError("No video device found")
}
do {
let input = try AVCaptureDeviceInput(device: captureDevice)
captureSession?.addInput(input)
capturePhotoOutput = AVCapturePhotoOutput()
capturePhotoOutput?.isHighResolutionCaptureEnabled = true
captureSession?.addOutput(capturePhotoOutput!)
captureSession?.sessionPreset = .high
movieFileOutput.maxRecordedDuration = CMTimeMake(value: Int64(59), timescale: 1)
if (captureSession?.canAddOutput(movieFileOutput))! {
captureSession?.addOutput(movieFileOutput)
}
self.captureSession?.commitConfiguration()
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
captureMetadataOutput.setMetadataObjectsDelegate(self as? AVCaptureMetadataOutputObjectsDelegate, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoPreviewLayer?.frame = previewLayer.layer.bounds
previewLayer.layer.addSublayer(videoPreviewLayer!)
captureSession?.startRunning()
self.btnCapture.isUserInteractionEnabled = true
} catch let error {
print(error.localizedDescription)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let captureSession = self.captureSession {
if captureSession.isRunning {
captureSession.stopRunning()
self.captureSession = nil
self.btnCapture.isUserInteractionEnabled = false
}
}
}
Расширение для AVCaptureFileOutputRecordingDelegate
extension MediaCaptureViewCotroller: AVCaptureFileOutputRecordingDelegate {
@objc func longPress(_ sender: UILongPressGestureRecognizer) {
var device : AVCaptureDevice!
let videoDeviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .unspecified)
let devices = videoDeviceDiscoverySession.devices
device = devices[0]
if sender.state == .began {
print("Started...")
self.hideControls()
let videoPreviewLayerOrientation = videoPreviewLayer?.connection?.videoOrientation
if !movieFileOutput.isRecording {
print("Recording...")
if UIDevice.current.isMultitaskingSupported {
self.backgroundRecordingID = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
}
let movieFileOutputConnection = movieFileOutput.connection(with: .video)
movieFileOutputConnection?.videoOrientation = videoPreviewLayerOrientation!
let availableVideoCodecTypes = movieFileOutput.availableVideoCodecTypes
if #available(iOS 11.0, *) {
if availableVideoCodecTypes.contains(.hevc) {
movieFileOutput.setOutputSettings([AVVideoCodecKey: AVVideoCodecType.hevc], for: movieFileOutputConnection!)
}
} else {
movieFileOutput.setOutputSettings([AVVideoCodecKey: AVVideoCodecH264], for: movieFileOutputConnection!)
}
if ((device as AnyObject).hasMediaType(AVMediaType.video)) {
if (device.hasTorch) {
self.captureSession?.beginConfiguration()
do {
if (device.hasTorch) {
try device.lockForConfiguration()
if userSelectedFlashMode == .on || userSelectedFlashMode == .auto {
device.torchMode = .on
}
device.unlockForConfiguration()
}
}catch{
print("Device tourch Flash Error ");
}
self.captureSession?.commitConfiguration()
}
}
let outputFileName = NSUUID().uuidString
let outputFilePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(("outputFileName" as NSString).appendingPathExtension("mp4")!)
print("RecordingStart PAth", outputFilePath)
self.cleanup(path: outputFilePath)
movieFileOutput.startRecording(to: URL(fileURLWithPath: outputFilePath), recordingDelegate: self)
}
} else if sender.state == .ended {
print("Ended...")
if movieFileOutput.isRecording {
print("Stopped")
movieFileOutput.stopRecording()
if ((device as AnyObject).hasMediaType(AVMediaType.video)) {
if (device.hasTorch) {
self.captureSession?.beginConfiguration()
do {
if (device.hasTorch){
try device.lockForConfiguration()
device.torchMode = .off
device.unlockForConfiguration()
}
}catch{
print("Device tourch Flash Error ");
}
self.captureSession?.commitConfiguration()
}
}
self.showControls()
}
} else { }
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print(outputFileURL.absoluteString)
do {
let data = try Data(contentsOf: outputFileURL)
print("Recorded File size", data.count)
//FIXME:- Navigate to create post screen
} catch {
print("error in decoding file", error.localizedDescription)
}
self.showControls()
}
func cleanup(path: String) {
if FileManager.default.fileExists(atPath: path) {
do {
try FileManager.default.removeItem(atPath: path)
} catch {
print("Could not remove file at url: \(path)")
}
}
if let currentBackgroundRecordingID = backgroundRecordingID {
backgroundRecordingID = UIBackgroundTaskIdentifier.invalid
if currentBackgroundRecordingID != UIBackgroundTaskIdentifier.invalid {
UIApplication.shared.endBackgroundTask(currentBackgroundRecordingID)
}
}
}
}