I'm building this iPad app to record a video with audio. It starts to record when the view appears, and then you can either stop the recording with a button, else it will stopp when a timer hits 0.
This is the entire Controller class.
import UIKit
import AVKit
class RecorderController: UIViewController, AVCaptureFileOutputRecordingDelegate {
@IBOutlet weak var previewView: UIView!
@IBOutlet weak var countdownLabel: UILabel!
var videoUrl: URL?
var seconds = 11 // Works with 11 seconds, any thing longer audio disappears
var timer = Timer()
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var fileName: String = ""
var documentsURL: URL?
var filePath: URL?
let videoFileOutput = AVCaptureMovieFileOutput()
override func viewDidLoad() {
super.viewDidLoad()
previewView.layer.cornerRadius = 15
previewView.clipsToBounds = true
}
override func viewDidAppear(_ animated: Bool) {
startVideoRecording()
let recordingDelegate: AVCaptureFileOutputRecordingDelegate? = self
videoPreviewLayer!.frame.size = previewView.frame.size
videoFileOutput.startRecording(to: filePath!, recordingDelegate: recordingDelegate!)
runTimer()
}
func runTimer() {
countdownLabel.text = "\(seconds)"
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
seconds -= 1 //This will decrement(count down)the seconds.
countdownLabel.text = "\(seconds)" //This will update the label.
if (seconds == 0) {
timer.invalidate()
stopRecording()
}
}
func startVideoRecording() {
let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)
let captureAudio = AVCaptureDevice.default(for: .audio)
fileName = "mysavefile.mp4"
documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
filePath = documentsURL?.appendingPathComponent(fileName) //.URLByAppendingPathComponent(fileName)
do {
let input = try AVCaptureDeviceInput(device: captureDevice!)
let audio = try AVCaptureDeviceInput(device: captureAudio!)
captureSession = AVCaptureSession()
captureSession?.sessionPreset = .high
captureSession?.addInput(input)
captureSession?.addInput(audio)
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
videoPreviewLayer?.videoGravity = .resizeAspectFill
videoPreviewLayer?.frame.size = previewView.frame.size
previewView.layer.addSublayer(videoPreviewLayer!)
self.captureSession!.addOutput(videoFileOutput)
captureSession?.startRunning()
} catch {
print(error)
}
}
@IBAction func stopButton(_ sender: Any) {
stopRecording()
}
func stopRecording() {
videoFileOutput.stopRecording()
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
videoUrl = outputFileURL
captureSession?.stopRunning()
videoPreviewLayer?.removeFromSuperlayer()
self.performSegue(withIdentifier: "showViewer", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let transition = CATransition()
transition.duration = 0.5
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
self.view.window!.layer.add(transition, forKey: kCATransition)
guard let vc = segue.destination as? ViewerController else { return }
vc.videoUrl = self.videoUrl
self.present(vc, animated: false, completion: nil)
}
}
If I set the timer to 11 seconds or lower, the video is recorded with the audio perfectly fine. But the really weird thing is if I increase the timer to anything longer than 11 seconds, and let the recording stop when the timer hits 0, the recording has absolutely no sound.
Any ideas what might cause this?