ios - 使用 UIImagePickerController 为 Dashcam 应用程序保存视频
问题描述
我正在尝试弹出警报以保存来自CoreMotion
数据触发器的视频。
我无法从“是”提示保存视频。
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
imagePicker.sourceType = .camera;
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
imagePicker.showsCameraControls = false
imagePicker.perform(#selector(UIImagePickerController.startVideoCapture), with: nil, afterDelay: 1)
// shows camera onto screen
self.present(imagePicker, animated: true)
do {
motion.accelerometerUpdateInterval = 0.25
motion.startAccelerometerUpdates(to: OperationQueue.current!) { (data, error) in
print(data as Any)
if let trueData = data {
//self.view.reloadInputViews()
let x = trueData.acceleration.x
let y = trueData.acceleration.y
let z = trueData.acceleration.z
let totalAcceleration = calculateMagnitude (no1:Float (x), no2: Float (y),no3: Float (z))
if (Float(totalAcceleration) > 2.00){
self.dismiss(animated: true, completion : nil)
let alert = UIAlertController (title: "Sudden acceleration detected", message: "Are you in an accident?", preferredStyle: .alert)
self.present(alert, animated: true, completion: nil)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in
print("User has selected Yes")//Here is where I want to save the video
}))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in
print("User has selected No")
imagePicker.perform(#selector(UIImagePickerController.startVideoCapture), with: nil, afterDelay: 1)
// shows camera onto screen
self.present(imagePicker, animated: true)
}))
}
我找到的所有答案都没有真正帮助我:[
TLDR:运行应用程序。电话记录了它前面的内容。数据变化CoreMotion
。弹出是或否提示。否继续录制。是的,保存视频。
解决方案
不要忘记点击屏幕开始捕捉
import UIKit
import Photos
import MobileCoreServices
import CoreMotion
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
lazy var imagePicker: UIImagePickerController = {
let ip = UIImagePickerController()
ip.delegate = self
ip.sourceType = .camera
ip.mediaTypes = [kUTTypeMovie as String]
ip.allowsEditing = false
ip.showsCameraControls = false
return ip
}()
let motion: CMMotionManager = {
let motion = CMMotionManager()
motion.accelerometerUpdateInterval = 0.25
return motion
}()
var videoUrl: URL?
override func viewDidLoad() {
super.viewDidLoad()
// First Check for photo library permission
checkPhotoLibraryPermission()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
startCapture()
}
func checkPhotoLibraryPermission() {
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized:
//handle authorized status
break
case .denied, .restricted :
//handle denied status
break
case .notDetermined:
// ask for permissions
PHPhotoLibrary.requestAuthorization { status in
switch status {
case .authorized:
// as above
break
case .denied, .restricted:
// as above
break
case .notDetermined:
// won't happen but still
break
}
}
}
}
func startCapture() {
self.present(imagePicker, animated: true) {
self.imagePicker.perform(#selector(self.imagePicker.startVideoCapture), with: nil, afterDelay: 1)
}
motion.startAccelerometerUpdates(to: .main) { (data, error) in
if let error = error {
print(error)
return
}
guard let data = data else { return }
let x = data.acceleration.x
let y = data.acceleration.y
let z = data.acceleration.z
let totalAcceleration = sqrt(x*x + y*y + z*z)
if totalAcceleration > 2 {
self.imagePicker.stopVideoCapture()
self.imagePicker.dismiss(animated: true, completion: nil)
self.showAlert()
}
}
}
func showAlert() {
let alert = UIAlertController (title: "Sudden acceleration detected", message: "Are you in an accident?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in
print("User has selected Yes") // Here is where I want to save the video
if let videoUrl = self.videoUrl {
self.saveVideoToPhotos(videoUrl)
}
}))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in
print("User has selected No")
self.present(self.imagePicker, animated: true) {
self.imagePicker.perform(#selector(self.imagePicker.startVideoCapture), with: nil, afterDelay: 1)
}
}))
self.present(alert, animated: true, completion: nil)
}
func saveVideoToPhotos(_ videoUrl: URL) {
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoUrl)
}) { saved, error in
if saved {
let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let videoUrl = info[.mediaURL] as? URL {
self.videoUrl = videoUrl
}
}
}
推荐阅读
- flask - 如何在 HTML 中将烧瓶表单字段值转换为 Jijnja2 URL
- c# - 如何使用 Selenium 和 C# 点击按钮类型“提交”
- mysql - MySQL - 选择同一列导致 2 个不同的输出
- c# - 有没有办法让字符串默认为继承列表中的类名
- angular - 如何在离子4中单击按钮时更改按钮颜色
- java - 具有方面注释方法时的Spring Autowired空字段
- python - 如何优化 pysapark 代码以按用户计算距离?
- python - 使用数据框和 matplotlib 的这段代码有什么错误
- spring - Spring Data JDBC 自定义查询参数转换器
- python-3.x - 我想显示每个栏的数量