iOS:AVCaptureSession不会录制超过11秒的音频

时间:2018-06-05 11:12:38

标签: ios swift ipad audio video

我正在构建这个iPad应用程序以录制带有音频的视频。它会在视图出现时开始录制,然后您可以使用按钮停止录制,否则当计时器达到0时它将停止。

这是整个Controller类。

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)
  }

}

如果我将定时器设置为11秒或更低,视频将被录制,音频完全正常。但真正奇怪的是,如果我将计时器增加到超过11秒的时间,并且当计时器达到0时让录音停止,录音绝对没有声音。

任何可能导致这种情况的想法?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,并在以下SO帖子中找到了解决方案:https://stackoverflow.com/a/31089253/1117968

您应该可以通过设置以下问题来解决此问题:

videoFileOutput.movieFragmentInterval = kCMTimeInvalid

开始录制之前。