直播一:画面采集和声音采集

伟大的雷锋同志

画面采集

导入AVFoundation
1.在Main.storyboard上拖入3个按钮,一个是开始录制,一个是暂停录制,一个是旋转镜头.

main.storyBoard上的三个按钮

2.将按钮拉线到工程内,分别为startCapture,stopCapture,rotateCamera
3.采集画面

  // 创建一个录制会话对象
    fileprivate lazy var session : AVCaptureSession = AVCaptureSession()
  // 创建一个预览图层
    fileprivate lazy var preViewLayer : AVCaptureVideoPreviewLayer =          AVCaptureVideoPreviewLayer(session: self.session)
// 创建全局队列
    fileprivate lazy var queue  = DispatchQueue.global()
    fileprivate lazy var audioQueue  = DispatchQueue.global()
    // 创建视频输入源
    fileprivate var videoInput : AVCaptureDeviceInput?
    // 创建视频输出源
    fileprivate var videoOutPut : AVCaptureVideoDataOutput?
    // 创建音频输入源
    fileprivate var audioInput : AVCaptureDeviceInput?
    // 创建音频输出源
    fileprivate var audioOutPut : AVCaptureAudioDataOutput?

开始采集画面

fileprivate func setUpVideo(){
        // 会话输入源(获取摄像头)
        // 获取设备
        guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else {
            print("模拟器无效")
            
            return
        }
        // 获取前置摄像头
        guard let deviece = devices.filter({ $0.position == .front }).first else {
            return
        }
        // 获取AVCaptureDeviceInput 输入源
        guard let input : AVCaptureDeviceInput = try? AVCaptureDeviceInput(device: deviece) else {
            return
        }
        // 设置视频输入源 全局变量
        self.videoInput = input
        // 判断视频会话对象是否能添加输入源
        if self.session.canAddInput(input){
          self.session.addInput(input)
        }
        
        
        // 会话输出源
        let outPut : AVCaptureVideoDataOutput = AVCaptureVideoDataOutput()
        // 设置输出源的代理
        outPut.setSampleBufferDelegate(self, queue: self.queue)
        
        // 判断视频录制会话对象是否能添加输出源
        if self.session.canAddOutput(outPut){
            self.session.addOutput(outPut)
        }
        self.videoOutPut = outPut

旋转镜头

// 添加镜头旋转的动画
@IBAction func rotateCamera(_ sender: AnyObject) {
        // 添加旋转摄像头的动画
        let rotaionAnim = CATransition()
        rotaionAnim.type = "oglFlip"
        rotaionAnim.subtype = "fromLeft"
        rotaionAnim.duration = 0.5
        view.layer.add(rotaionAnim, forKey: nil)
        // 获取之前的镜头
        guard var position = self.videoInput?.device.position else {return}
        // 设置相反的位置的镜头
        position = position == .front ? .back : .front
        // 根据现在摄像头的位置创建新的device
        let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice]
        guard let device = devices?.filter({$0.position == position}).first else {return}
        // 创建新的输入源
        guard let input = try? AVCaptureDeviceInput(device: device) else {return}
        // 在session中切换input
        session.beginConfiguration()
        session.removeInput(self.videoInput)
        if session.canAddInput(self.videoInput) {
            session.addInput(input)

        }
        self.videoInput = input
        session.commitConfiguration()
}

4.采集音频


fileprivate func setUpAudio(){
        // 创建音频输入源(话筒)
        // 获取设备
        guard let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) else {return}
        // 创建输入源
        guard let input = try? AVCaptureDeviceInput(device: device) else {return}
        self.audioInput = input
        // 判断是否能添加输入源
        if session.canAddInput(input) {
            session.addInput(input)
        }
        // 创建输出源
        let outPut = AVCaptureAudioDataOutput()
        // 设置代理
        outPut.setSampleBufferDelegate(self, queue: self.audioQueue)
        self.audioOutPut = outPut
        // 判断是否能添加输出源
        if session.canAddOutput(outPut){
            session.addOutput(outPut)
        }
//        

遵守音频录制和视频录制的代理,两个代理方法是同一个

// 遵守录制视频输出会话的代理,sampleBuffer就是美颜所修改的东西
extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate{
    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
        if connection == self.videoOutPut?.connection(withMediaType: AVMediaTypeVideo) {
            print("输出视频画面")
        }else{
            print("获取音频!")
        }
    }
    
}

5.停止录制


// 停止录制
    @IBAction func stopCapture(_ sender: AnyObject) {
        self.session.stopRunning()
        self.preViewLayer.removeFromSuperlayer()
        self.fileOutPut?.stopRecording()
        // 移除输入源和舒楚媛
        self.session.removeInput(self.videoInput)
        self.session.removeOutput(self.videoOutPut)
        self.session.removeInput(self.audioInput)
        self.session.removeOutput(self.audioOutPut)
        self.session.removeOutput(self.fileOutPut)
    }

将程序跑到真机上,点击开始录制即可以录制成功!
Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,528评论 4 61
  • 10月26日,星期四,晴 今天早上,女儿上学前找我要十元钱,说中午要买面包和好朋友们吃。我问她怎么突然想中午吃面包...
    月儿贝贝阅读 1,576评论 0 1
  • 此生未完成应该是我近一个月读的最快的一本书,在看周国平序的时候我突然觉得于娟这个人我似曾相识,翻看目录才想起来,前...
    大梅子1990阅读 2,615评论 0 1
  • 【今日盘面】 今日沪深创分化开盘,同步以中阴收盘,该来的总会来,会迟到不会缺席,只需我们有点耐心,才能坦然相对。虽...
    股海苍穹阅读 1,553评论 0 0
  • 今天的小雨还是不停的下,阗阗按时起床虽然辛苦还是坚持。 由于感冒发烧阗阗吃的比较少,早上就出门到学校去,我五...
    丽萍在这阅读 1,364评论 0 1

友情链接更多精彩内容