从 url (AVURLAsset) 加载后,我的肖像视频会旋转
Posted
技术标签:
【中文标题】从 url (AVURLAsset) 加载后,我的肖像视频会旋转【英文标题】:my portraits videos gets rotated after load from url (AVURLAsset) 【发布时间】:2018-08-05 21:08:17 【问题描述】:我有一个可以访问照片/视频库的选择器,但我的问题是当视频是纵向时,视频的宽度和高度会反转。 我写了一个补丁来检查视频的大小,当宽度大于高度时,它会旋转它。但显然它不适用于肖像以外的其他视频。
有没有办法访问视频的方向?或者欢迎任何其他解决此问题的方法。
这是我的 adPicker 方法、imagePicker(didFinishPickingMediaWithInfo:) 委托方法和 getFramesFromVideo(fileUrl:) 方法的代码:
@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage
editableView.drawnImage.image = image
initialVC.updateState(newState: .photoAdded)
initialVC.viewUpdater.updateContainerHeight()
else if let videoUrl = info[UIImagePickerControllerMediaURL] as? URL
imageManager.getFramesFromVideo(fileURL: videoUrl)
initialVC.dismiss(animated: true, completion: nil)
func addPicker()->UIAlertController
let myAlert = UIAlertController()
guard let imagePicker = self.initialVC.imagePicker else
fatalError()
return myAlert
for type in alertTypes
let alertText = type == .photoGallery ? AlertText.typeGalery : type == .camera ? AlertText.typeCamera : type == .video ? AlertText.typeVideo : AlertText.typeCancel
myAlert.title = AlertText.title
myAlert.message = ""
let cameraAction = UIAlertAction(title : alertText, style : .default) (action) in
imagePicker.delegate = self
imagePicker.allowsEditing = false
//type photo gallery
if type == .photoGallery && UIImagePickerController.isSourceTypeAvailable(.photoLibrary)
imagePicker.sourceType = .photoLibrary
self.initialVC.present(imagePicker, animated: true, completion: nil)
//type camera
if type == .camera && UIImagePickerController.isSourceTypeAvailable(.camera)
imagePicker.sourceType = .camera
self.initialVC.present(imagePicker, animated: true, completion: nil)
if type == .video
imagePicker.mediaTypes = [String(kUTTypeMovie)]
imagePicker.videoQuality = .typeHigh
imagePicker.videoMaximumDuration = VideoTime.maxDuration
self.initialVC.present(imagePicker, animated: true, completion: nil)
if type == .cancel
self.initialVC.dismiss(animated: true, completion: nil)
myAlert.addAction(cameraAction)
return myAlert
func getFramesFromVideo(fileURL: URL)
let asset = AVURLAsset(url: fileURL, options: nil)
let videoDuration = asset.duration
print(asset.metadata)
let generator = AVAssetImageGenerator(asset: asset)
generator.requestedTimeToleranceAfter = kCMTimeZero
generator.requestedTimeToleranceBefore = kCMTimeZero
var imageError : Error?
frameForTimes = [NSValue]()
let totalTimeLength = Int(videoDuration.seconds * Double(videoDuration.timescale))
let step = totalTimeLength / VideoTime.maxSampleCounts
for i in 0 ..< VideoTime.maxSampleCounts
let cmTime = CMTimeMake(Int64(i * step), Int32(videoDuration.timescale))
frameForTimes.append(NSValue(time: cmTime))
generator.generateCGImagesAsynchronously(forTimes: frameForTimes, completionHandler: requestedTime, image, actualTime, result, error in
DispatchQueue.main.async
guard imageError == nil else return
if let image = image
if self.tempImages.count != self.frameForTimes.count //avoid crash
self.videoFrameDelegate?.fillFramesFromVideo(frame: UIImage(cgImage: image))
self.tempImages.updateValue(self.frameForTimes[self.tempImages.count] as! CMTime, forKey: UIImage(cgImage: image))
print("image \(actualTime.seconds) loaded")
else if (error != nil)
imageError = error
//TODO: Error handler
generator.cancelAllCGImageGeneration()
self.tempImages.removeAll()
self.videoFrameDelegate?.removeFrames()
print(error as Any)
// Completion handler
if self.tempImages.count == self.frameForTimes.count
print("frames ended loading")
self.tempImages.removeAll()
self.frameForTimes.removeAll()
self.videoFrameDelegate?.loadFrames()
)
【问题讨论】:
【参考方案1】:找到具有此属性的解决方案:videoTrack.preferredTransform
▿ CGAffineTransform
- a : 0.0
- b : 1.0
- c : -1.0
- d : 0.0
- tx : 360.0
- ty : 0.0
当 tx 带有一个值时,表示视频已经旋转。使用简单的if else
旋转视频的图像,如果它已被旋转,将解决问题:
extension UIImage
func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage
//Calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))
let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi / 180)
rotatedViewBox.transform = t
let rotatedSize: CGSize = rotatedViewBox.frame.size
//Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap: CGContext = UIGraphicsGetCurrentContext()!
//Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
//Rotate the image context
bitmap.rotate(by: (degrees * CGFloat.pi / 180))
//Now, draw the rotated/scaled image into the context
bitmap.scaleBy(x: 1.0, y: -1.0)
bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
希望对某人有所帮助
【讨论】:
以上是关于从 url (AVURLAsset) 加载后,我的肖像视频会旋转的主要内容,如果未能解决你的问题,请参考以下文章