Swift IOS 使用 AVFoundation 录制视频和音频

PJ3*_*PJ3 1 avfoundation ios swift

我能够通过在此处解决此问题来成功获取录制的视频

基本上

  1. AVCaptureFileOutputRecordingDelegate原型继承
  2. 循环访问可用设备
  3. 使用相机创建会话
  4. 开始录音
  5. 停止录音
  6. 通过实现上述原型的方法获取录制视频

但该文件不附带音频。

根据这个问题,我必须单独录制音频并使用提到的类合并视频和音频

但我不知道如何同时实现视频和音频录制。

for device in devices {
    // Make sure this particular device supports video
    if (device.hasMediaType(AVMediaTypeVideo)) {
        // Finally check the position and confirm we've got the back camera
        if(device.position == AVCaptureDevicePosition.Back) {
            captureDevice = device as? AVCaptureDevice
            if captureDevice != nil {
                print("Capture device found")

                beginSession()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个循环中,只有可用的设备类型是 .Front 和 .Back

mum*_*umu 10

以下是使用 AVFoundation 框架录制带音频视频的方法。步骤是:

1. 准备会议:

self.captureSession = AVCaptureSession()
Run Code Online (Sandbox Code Playgroud)

2. 准备可用的视频和音频设备:

let session = AVCaptureDevice.DiscoverySession.init(deviceTypes:[.builtInWideAngleCamera, .builtInMicrophone], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
        
let cameras = (session.devices.compactMap{$0})
        
for camera in cameras {
    if camera.position == .front {
        self.frontCamera = camera
    }
    if camera.position == .back {
        self.rearCamera = camera

        try camera.lockForConfiguration()
        camera.focusMode = .continuousAutoFocus
        camera.unlockForConfiguration()
    }
}
Run Code Online (Sandbox Code Playgroud)

3. 准备会话输入:

guard let captureSession = self.captureSession else {
    throw CameraControllerError.captureSessionIsMissing
}

if let rearCamera = self.rearCamera {
    self.rearCameraInput = try AVCaptureDeviceInput(device: rearCamera)
    if captureSession.canAddInput(self.rearCameraInput!) {
        captureSession.addInput(self.rearCameraInput!)
        self.currentCameraPosition = .rear
    } else {
        throw CameraControllerError.inputsAreInvalid
    }
} else if let frontCamera = self.frontCamera {
    self.frontCameraInput = try AVCaptureDeviceInput(device: frontCamera)
    if captureSession.canAddInput(self.frontCameraInput!) {
        captureSession.addInput(self.frontCameraInput!)
        self.currentCameraPosition = .front
    } else {
        throw CameraControllerError.inputsAreInvalid
    }
} else {
    throw CameraControllerError.noCamerasAvailable
}

// Add audio input
if let audioDevice = self.audioDevice {
    self.audioInput = try AVCaptureDeviceInput(device: audioDevice)
    if captureSession.canAddInput(self.audioInput!) {
        captureSession.addInput(self.audioInput!)
    } else {
        throw CameraControllerError.inputsAreInvalid
    }
}
Run Code Online (Sandbox Code Playgroud)

4. 准备输出:

self.videoOutput = AVCaptureMovieFileOutput()
if captureSession.canAddOutput(self.videoOutput!) {
    captureSession.addOutput(self.videoOutput!)
}
captureSession.startRunning()
Run Code Online (Sandbox Code Playgroud)

5. 开始录音:

func recordVideo(completion: @escaping (URL?, Error?) -> Void) {
    guard let captureSession = self.captureSession, captureSession.isRunning else {
        completion(nil, CameraControllerError.captureSessionIsMissing)
        return
    }
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let fileUrl = paths[0].appendingPathComponent("output.mp4")
    try? FileManager.default.removeItem(at: fileUrl)
    videoOutput!.startRecording(to: fileUrl, recordingDelegate: self)
    self.videoRecordCompletionBlock = completion
}
Run Code Online (Sandbox Code Playgroud)

6.停止录音:

func stopRecording(completion: @escaping (Error?) -> Void) {
    guard let captureSession = self.captureSession, captureSession.isRunning else {
        completion(CameraControllerError.captureSessionIsMissing)
        return
    }
    self.videoOutput?.stopRecording()
}
Run Code Online (Sandbox Code Playgroud)

7. 实现委托:

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    if error == nil {
        //do something
    } else {
        //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

我从这里得到了想法:https : //www.appcoda.com/avfoundation-swift-guide/

这是完整的项目https://github.com/rubaiyat6370/iOS-Tutorial/

  • 值得一提的是,您必须将“隐私 - 相机使用说明”和“隐私 - 麦克风使用说明”的权限添加到您的 info.plist 中。 (3认同)

PJ3*_*PJ3 3

找到答案,这个答案与代码一致

它可以简单地通过

  1. 声明另一个捕获设备变量
  2. 循环设备并初始化相机和音频捕获设备变量
  3. 将音频输入添加到会话

代码

var captureDevice : AVCaptureDevice?
var captureAudio :AVCaptureDevice?
Run Code Online (Sandbox Code Playgroud)

循环设备并初始化捕获设备

var captureDeviceVideoFound: Bool = false
var captureDeviceAudioFound:Bool = false

// Loop through all the capture devices on this phone
for device in devices {
// Make sure this particular device supports video
    if (device.hasMediaType(AVMediaTypeVideo)) {
// Finally check the position and confirm we've got the front camera
        if(device.position == AVCaptureDevicePosition.Front) {

            captureDevice = device as? AVCaptureDevice //initialize video
            if captureDevice != nil {
                print("Capture device found")
                captureDeviceVideoFound = true; 
            }
        }
    }
    if(device.hasMediaType(AVMediaTypeAudio)){
        print("Capture device audio init")
        captureAudio = device as? AVCaptureDevice //initialize audio
        captureDeviceAudioFound = true
    }
}
if(captureDeviceAudioFound && captureDeviceVideoFound){
    beginSession() 
}
Run Code Online (Sandbox Code Playgroud)

内部会议

try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
try captureSession.addInput(AVCaptureDeviceInput(device: captureAudio))
Run Code Online (Sandbox Code Playgroud)

这将输出带有音频的视频文件。无需合并音频或执行任何操作。

这个苹果文档有帮助