从网址(AVURLAsset)加载后,我的肖像视频会旋转

时间:2018-08-05 21:08:18

标签: ios swift swift3 avurlasset

我有一个选择器,可以访问照片/视频库,但是我的问题是,当视频为人像时,视频的宽度和高度会颠倒。 我写了一个补丁来检查视频的大小,当宽度大于高度时,它会旋转它。但是很明显,它不能用于肖像以外的其他视频。

是否可以访问视频的方向?或其他任何解决此问题的方法将受到欢迎。

这是我的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 个答案:

答案 0 :(得分:0)

找到了具有以下属性的解决方案: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
    }
}

希望它将对某人有所帮助

相关问题