Swift3 AVFoundation未在IOS 11.3上录制

Swift3 AVFoundation未在IOS 11.3上录制,swift3,avfoundation,ios11,video-capture,Swift3,Avfoundation,Ios11,Video Capture,我曾尝试使用AVFoundation录制视频,并在会话中分配音频输入。它在IOS 11.2.6上运行良好,但当我们尝试开始录制时,它在IOS 11.3上抛出错误 let videoCaptureSession = AVCaptureSession() var movieOutput = AVCaptureMovieFileOutput() var previewLayer = AVCaptureVideoPreviewLayer() var videoInput:AVCaptureDeviceI

我曾尝试使用AVFoundation录制视频,并在会话中分配音频输入。它在IOS 11.2.6上运行良好,但当我们尝试开始录制时,它在IOS 11.3上抛出错误

let videoCaptureSession = AVCaptureSession()
var movieOutput = AVCaptureMovieFileOutput()
var previewLayer = AVCaptureVideoPreviewLayer()
var videoInput:AVCaptureDeviceInput!
var micInput:AVCaptureDeviceInput!
var cameraDevice:AVCaptureDevice!
var outputURL: URL!
var videoUrl : NSURL!


override func viewWillAppear(_ animated: Bool) {

        if !videoCaptureSession.isRunning || hasPlaceCameraOpened {
            self.setCameraSession()
        }
}

func setCameraSession() {

        if !UIImagePickerController.isSourceTypeAvailable(.camera) {
            return
        }

        self.cameraPreview.isHidden = true
        videoCaptureSession.sessionPreset = CamResolution // set from MyConstant
        previewLayer = AVCaptureVideoPreviewLayer(session: videoCaptureSession)
        previewLayer.videoGravity = AVLayerVideoGravityResize//AVLayerVideoGravityResizeAspectFill
        previewLayer.frame = self.cameraPreview.bounds
        previewLayer.masksToBounds = true
        self.cameraPreview.layer.addSublayer(previewLayer)

        if videoCaptureSession.canSetSessionPreset(AVCaptureSessionPresetHigh) {
            videoCaptureSession.sessionPreset = AVCaptureSessionPresetHigh
        }





        cameraDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        let microphone = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)

        do {

            videoInput = try AVCaptureDeviceInput(device: cameraDevice)
            if videoCaptureSession.canAddInput(videoInput) {
                videoCaptureSession.addInput(videoInput)
            }

        }
        catch let error {
            print("\(error), \(error.localizedDescription)")
        }


        do {

            micInput = try AVCaptureDeviceInput(device: microphone)
            if videoCaptureSession.canAddInput(micInput) {
                videoCaptureSession.addInput(micInput)
            }

        }
        catch let error {
            print("\(error), \(error.localizedDescription)")
        }


        let movieOutput:AVCaptureMovieFileOutput = AVCaptureMovieFileOutput()
        if videoCaptureSession.canAddOutput(movieOutput) {
            videoCaptureSession.addOutput(movieOutput)

            let connection: AVCaptureConnection? = movieOutput.connection(withMediaType: AVMediaTypeVideo)

                connection!.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.cinematic
            }
            self.movieOutput = movieOutput
        }
    }

@IBAction func startRecording(sender:UIButton) {
        if !movieOutput.isRecording {
            outputURL = self.tempURL()
            do{
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryRecord)
            }catch let err {
                print(err.localizedDescription)
            }
            movieOutput.startRecording(toOutputFileURL: outputURL, recordingDelegate: self)
        }
    }

func tempURL() -> URL? {
        guard let docURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first else {
            return nil
        }
        return (docURL.appendingPathComponent("\(ProjectConstants.strTimestamp).mp4"))
    }
并最终实现了委托方法:

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
        DispatchQueue.global(qos: DispatchQoS.QoSClass.userInteractive).async {
            if (error != nil) {
                print("Error recording movie: \(error!.localizedDescription)")
            } else {
                _ = self.outputURL as URL
            }

            let pathString = outputFileURL.relativePath
            self.videoUrl = NSURL.fileURL(withPath: pathString) as NSURL
            self.videosUrlArray.append(self.videoUrl! as URL)

            do {
                let videoData = try Data.init(contentsOf: outputFileURL)
                self.saveVideoToDocumentDirectory(fileData: videoData)
            } catch let err {
                print(err.localizedDescription)
            }
        }
    }

在IOS 11.2之前,我面临的唯一问题是,尽管有摄像头屏幕,但有时在IOS 11.3上仍会出现白色屏幕,但每次视频未录制时,都会在代理方法上抛出错误。我不明白怎么了。任何帮助都将不胜感激。提前谢谢


注意:可能有一些编辑问题,我不习惯于这样。请原谅。

我也看到API中有一些变化。。。 也许你应该试试看

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)
而不是

func capture(_ output: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!)
我对这件事也有同样的看法,不再接到电话

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!)
必须由

 func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) 
文档混合使用了两种引用

   @method captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:
     @abstract
        Informs the delegate when all pending data has been written to an output file.

     @param output
        The capture file output that has finished writing the file.
     @param outputFileURL
        The file URL of the file that has been written.
     @param connections
        An array of AVCaptureConnection objects attached to the file output that provided the data that was written to the file.
     @param error
        An error describing what caused the file to stop recording, or nil if there was no error.

     @discussion
        This method is called when the file output has finished writing all data to a file whose recording was stopped, either because startRecordingToOutputFileURL:recordingDelegate: or stopRecording were called, or because an error, described by the error parameter, occurred (if no error occurred, the error parameter will be nil). This method will always be called for each recording request, even if no data is successfully written to the file.

        Clients should not assume that this method will be called on a specific thread.

        Delegates are required to implement this method.
     */
    public func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)

你能把错误贴在这里吗?现在没有问题,录音正常。。。如果出现任何奇怪的情况,我会发帖的。