iOS视频采集(四)

来源:互联网 发布:手机淘宝试用在哪里 编辑:程序博客网 时间:2024/06/11 00:42


本篇在前面三篇的基础上加入写入文件功能,代码见 MARK:-写到文件 注释(文中共有5处,一处设置 一处代理 三处写入步骤)

附:在真机设备中查看录制的音视频文件

Xcode windows -> devices ->左上角选择自己的设备后,看右下部分的installed Apps,找到自己的App Name ->点设置(齿轮图标)Download Container

如笔者下载到的文件是 net.targetcloud.videocapture 2016-11-12 21/36.16.254.xcappdata

右键显示包内容 ,就查看到本次录制音视频文件 AppData -> Documents -> videoAudioCapture.mp4(实际直播中是通过编码后推到服务器)


////  ViewController.swift//  videocapture////  Created by targetcloud on 2016/11/12.//  Copyright © 2016年 targetcloud. All rights reserved.//import UIKitimport AVFoundationclass ViewController: UIViewController {    fileprivate lazy var videoQueue = DispatchQueue.global()    fileprivate lazy var audioQueue = DispatchQueue.global()    fileprivate lazy var session : AVCaptureSession = AVCaptureSession()    fileprivate lazy var previewLayer : AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.session)//    fileprivate var connection : AVCaptureConnection?//三处替换(1)    fileprivate var videoOutput : AVCaptureVideoDataOutput?    //MARK:-1、用于切换视频采集时的前置或后置摄像头    fileprivate var videoInput : AVCaptureDeviceInput?    //MARK:-写到文件(1)    fileprivate var movieFileOutput : AVCaptureMovieFileOutput?        override func viewDidLoad() {        super.viewDidLoad()    }    @IBAction func startCapture(_ sender: Any) {        setupVideo()        setupAudio()        //MARK:-写到文件(设置)        let movieFileoutput = AVCaptureMovieFileOutput()        self.movieFileOutput = movieFileoutput        session.addOutput(movieFileoutput)        let connection = movieFileoutput.connection(withMediaType: AVMediaTypeVideo)        connection?.preferredVideoStabilizationMode = .auto                previewLayer.frame = view.bounds        view.layer.insertSublayer(previewLayer, at: 0)        session.startRunning()        //MARK:-写到文件(2)        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/videoAudioCapture.mp4"        let outputFileURL = URL(fileURLWithPath: path)        movieFileoutput.startRecording(toOutputFileURL: outputFileURL, recordingDelegate: self)    }    @IBAction func endCapture(_ sender: Any) {        //MARK:-写到文件(3)        self.movieFileOutput?.stopRecording()                session.stopRunning()        previewLayer.removeFromSuperlayer()    }        //MARK:-3、切换视频采集时的前置或后置摄像头    @IBAction func switchFrontOrBack(_ sender: Any) {        // CATransition        let rotaionAnim = CATransition()        rotaionAnim.type = "oglFlip"        rotaionAnim.subtype = "fromLeft"        rotaionAnim.duration = 0.5        view.layer.add(rotaionAnim, forKey: nil)                // Check Current videoInput        guard let videoInput = videoInput else { return }                // Change Position        let position : AVCaptureDevicePosition = videoInput.device.position == .front ? .back : .front                // New DeviceInput        guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { return }        guard let newDevice = devices.filter({$0.position == position}).first else { return }        guard let newVideoInput = try? AVCaptureDeviceInput(device: newDevice) else { return }                // Remove videoInput & Add newVideoInput        session.beginConfiguration()        session.removeInput(videoInput)        session.addInput(newVideoInput)        session.commitConfiguration()                // Save Current videoInput        self.videoInput = newVideoInput    }}extension ViewController {    fileprivate func setupVideo() {        //info.plist add Privacy - Camera Usage Description        guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else {return}        guard let device = devices.filter({$0.position == .front}).first else {return}//$0表示闭包的第一个参数        guard let videoInput = try? AVCaptureDeviceInput(device: device) else {return}        session.addInput(videoInput)        //MARK:-2、保存当前的视频输入设备,用于后面可以切换前置或后置摄像头        self.videoInput = videoInput                let videoOutput = AVCaptureVideoDataOutput()        videoOutput.setSampleBufferDelegate(self, queue:videoQueue)        session.addOutput(videoOutput)        //        connection = videoOutput.connection(withMediaType: AVMediaTypeVideo)//三处替换(2)        self.videoOutput = videoOutput    }        fileprivate func setupAudio() {        //info.plist add Privacy - Microphone Usage Description        guard let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) else {return}        guard let audioInput = try? AVCaptureDeviceInput(device: device) else {return}        session.addInput(audioInput)                let audioOutput = AVCaptureAudioDataOutput()        audioOutput.setSampleBufferDelegate(self, queue:audioQueue)        session.addOutput(audioOutput)    }}extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate{    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {//        if connection == self.connection {//三处替换(3)目的是为了切换后仍然有音视频采集,不然只有音频采集        if connection == self.videoOutput?.connection(withMediaType: AVMediaTypeVideo) {            print("-采集到视频画面");        }else{            print("采集到音频数据-");        }    }}//MARK:-写到文件(代理)extension ViewController : AVCaptureFileOutputRecordingDelegate{    func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {        print(">开始录制")    }    func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {        print("停止录制<")    }}




1 0
原创粉丝点击