如何使用委托方法从捕获会话中提取视频?
how to extract the video from the capture session using the delegate method?
我正在尝试了解相机在 swift 中的工作原理,所以我创建了一个简单的 viewController 设置会话、输入和输出实例,然后我开始录制,但是长度视频始终为零,AVCaptureOutput.isRunning 始终为假...这是我的代码
class cameraViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {
let recordButton: UIButton = {
let button = UIButton()
button.layer.cornerRadius = 30
button.backgroundColor = UIColor.black
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(startRecording), for: UIControl.Event.touchUpInside)
return button
}()
let session = AVCaptureSession()
lazy var previewLayer = AVCaptureVideoPreviewLayer(session: session)
override func viewDidLoad() {
super.viewDidLoad()
previewLayer.frame = view.frame
view.layer.addSublayer(previewLayer)
setUpSession()
setUpViewsAndConstraints()
}
func setUpViewsAndConstraints(){
view.addSubview(recordButton)
recordButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
recordButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -80).isActive = true
recordButton.widthAnchor.constraint(equalToConstant: 60).isActive = true
recordButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
}
@objc func startRecording(button: UIButton){
let url = Bundle.main.bundleURL
let output = (session.outputs[0] as! AVCaptureMovieFileOutput)
print(output.isRecording)
if output.isRecording == false {
print("recording is about to start")
output.startRecording(to: url, recordingDelegate: self)
} else {
print("recording is about to stop")
output.stopRecording()
}
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print("recorded duration:",output.recordedDuration)
}
func setUpSession(){
session.beginConfiguration()
// setting devices and inputs
guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInDualCamera, for: AVMediaType.video, position: AVCaptureDevice.Position.unspecified) else {return}
guard let input = try? AVCaptureDeviceInput(device: device) else {print("input failed");return}
session.addInput(input)
// setting outputs...
let videoOutput = AVCaptureMovieFileOutput()
session.sessionPreset = AVCaptureSession.Preset.high
session.addOutput(videoOutput)
session.commitConfiguration()
session.startRunning()
}
}
我可以在我的视图层上正常看到来自摄像头的输入视频,但是当我点击录制按钮时似乎没有任何效果,委托方法立即打印出录制的持续时间为零,并且 @objc func startRecording(button: UIButton)
永远不会打印出 "recording is about to stop" 但总是 "recording is about to start"..
我应该把哪个 url 放在方法 output.startRecording(to: url, recordingDelegate: self)
上?一旦数据进入委托方法,我有点困惑为什么我需要指定这个URL我应该放在那里什么?
我在这里错过了什么?
提前谢谢你的回答!!
这里
output.startRecording(to: url, recordingDelegate: self)
你应该放 url 的输出视频,因为你将它设置为
let url = Bundle.main.bundleURL
无法写入主包,因此无法开始记录,您可以通过检查打印的错误来验证
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print(error)
}
您需要在文档中创建一个 url say 并提供它
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let completeMovie = URL(fileURLWithPath: documentsURL.path).appendingPathComponent("video.mp4")
我正在尝试了解相机在 swift 中的工作原理,所以我创建了一个简单的 viewController 设置会话、输入和输出实例,然后我开始录制,但是长度视频始终为零,AVCaptureOutput.isRunning 始终为假...这是我的代码
class cameraViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {
let recordButton: UIButton = {
let button = UIButton()
button.layer.cornerRadius = 30
button.backgroundColor = UIColor.black
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(startRecording), for: UIControl.Event.touchUpInside)
return button
}()
let session = AVCaptureSession()
lazy var previewLayer = AVCaptureVideoPreviewLayer(session: session)
override func viewDidLoad() {
super.viewDidLoad()
previewLayer.frame = view.frame
view.layer.addSublayer(previewLayer)
setUpSession()
setUpViewsAndConstraints()
}
func setUpViewsAndConstraints(){
view.addSubview(recordButton)
recordButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
recordButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -80).isActive = true
recordButton.widthAnchor.constraint(equalToConstant: 60).isActive = true
recordButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
}
@objc func startRecording(button: UIButton){
let url = Bundle.main.bundleURL
let output = (session.outputs[0] as! AVCaptureMovieFileOutput)
print(output.isRecording)
if output.isRecording == false {
print("recording is about to start")
output.startRecording(to: url, recordingDelegate: self)
} else {
print("recording is about to stop")
output.stopRecording()
}
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print("recorded duration:",output.recordedDuration)
}
func setUpSession(){
session.beginConfiguration()
// setting devices and inputs
guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInDualCamera, for: AVMediaType.video, position: AVCaptureDevice.Position.unspecified) else {return}
guard let input = try? AVCaptureDeviceInput(device: device) else {print("input failed");return}
session.addInput(input)
// setting outputs...
let videoOutput = AVCaptureMovieFileOutput()
session.sessionPreset = AVCaptureSession.Preset.high
session.addOutput(videoOutput)
session.commitConfiguration()
session.startRunning()
}
}
我可以在我的视图层上正常看到来自摄像头的输入视频,但是当我点击录制按钮时似乎没有任何效果,委托方法立即打印出录制的持续时间为零,并且 @objc func startRecording(button: UIButton)
永远不会打印出 "recording is about to stop" 但总是 "recording is about to start"..
我应该把哪个 url 放在方法 output.startRecording(to: url, recordingDelegate: self)
上?一旦数据进入委托方法,我有点困惑为什么我需要指定这个URL我应该放在那里什么?
我在这里错过了什么?
提前谢谢你的回答!!
这里
output.startRecording(to: url, recordingDelegate: self)
你应该放 url 的输出视频,因为你将它设置为
let url = Bundle.main.bundleURL
无法写入主包,因此无法开始记录,您可以通过检查打印的错误来验证
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print(error)
}
您需要在文档中创建一个 url say 并提供它
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let completeMovie = URL(fileURLWithPath: documentsURL.path).appendingPathComponent("video.mp4")