引入AVFoundation 框架
fileprivate lazy var queue = DispatchQueue.global();
fileprivate lazy var audioqueue = DispatchQueue.global();
fileprivate lazy var session = AVCaptureSession();
fileprivate lazy var previewLayer = AVCaptureVideoPreviewLayer(session: session)
fileprivate var videoOutPut : AVCaptureVideoDataOutput?
fileprivate var videoInput:AVCaptureDeviceInput?
fileprivate var movieOutPut: AVCaptureMovieFileOutput?
extension ViewController {
//视频采集
func startCapture(){
let movieOutPut = AVCaptureMovieFileOutput();
self.movieOutPut = movieOutPut
session.addOutput( self.movieOutPut!)
//将input添加到会话中
// guard let devices:AVCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video) else{
// print("摄像头不可用")
// return;
// };
//
// AVCaptureDeviceDiscoverySession *devicesIOS10 = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position];
//
// NSArray *devicesIOS = devicesIOS10.devices;
// for (AVCaptureDevice *device in devicesIOS) {
// if ([device position] == position) {
// return device;
// }
// }
let discover = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.front)
let devices = discover.devices.filter { (device) -> Bool in
return device.position==AVCaptureDevice.Position.front
}.first
let input = (try? AVCaptureDeviceInput(device: devices!))
session.addInput(input!)
self.videoInput = input;
//设置捕捉会话输出源
let outPut = AVCaptureVideoDataOutput();
outPut.setSampleBufferDelegate(self, queue: queue)
session.addOutput(outPut)
//给用户看到一个预览图层
previewLayer.frame = view.bounds
// view.layer.addSublayer(previewLayer)
view.layer.insertSublayer(previewLayer, at: 0)
//开始采集
session.startRunning()
//获取视频的videoConnect
//将开始采集的画面,写入到文件中
let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/abc.mp4")
print("路径",path)
videoOutPut = outPut;
// videoConnect = outPut.connection(with: AVMediaType.video)
//添加写入文件的OutPut
//设置写入的稳定性
let connection = self.movieOutPut!.connection(with: AVMediaType.video)
connection?.preferredVideoStabilizationMode = .auto
self.movieOutPut!.startRecording(to: URL(fileURLWithPath: path), recordingDelegate: self)
}
@IBAction func stopCapture() {
self.movieOutPut?.stopRecording()
session.stopRunning()
previewLayer.removeFromSuperlayer()
}
//音频采集
func startAudio(){
guard let devices:AVCaptureDevice = AVCaptureDevice.default(for: AVMediaType.audio) else{
print("话筒不可用")
return;};
let input = (try? AVCaptureDeviceInput(device: devices))!
session.addInput(input)
//设置捕捉会话输出源
let outPut = AVCaptureAudioDataOutput();
outPut.setSampleBufferDelegate(self, queue: audioqueue)
session.addOutput(outPut)
}
//切换镜头
@IBAction func switchScene(){
//获取之前的镜头
guard var position = self.videoInput?.device.position else
{
return;
}
//
//
// //获取当前应该显示的镜头
//
position = ((position == AVCaptureDevice.Position.front) ? AVCaptureDevice.Position.back : AVCaptureDevice.Position.front)
//
// //根据当前镜头创建新的device
//
//
//
// guard let devices:AVCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video) else{
// print("摄像头不可用")
// return;
// };
//根据新的device创建新的input
let discover = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position:position)
let devices = discover.devices.filter { (device) -> Bool in
return device.position==position
}.first!
let input = (try? AVCaptureDeviceInput(device: devices))
//在session中切换input
session.beginConfiguration();
session.removeInput(self.videoInput!)
session.addInput(input!)
session.commitConfiguration()
self.videoInput = input;
}
}
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate{
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
if connection==self.videoOutPut!.connection(with: AVMediaType.video){
print("已经采集到视频画面")
}else
{
print("已经采集音频画面")
}
}
}
//写入文件到目录的方法
extension ViewController: AVCaptureFileOutputRecordingDelegate
{
func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection])
{
print("开始写入文件")
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)
{
print("结束写入文件",error?.localizedDescription ?? "")
}
}