Iphone UIImagePickerController allowsEditing=是,修剪后获取未修剪的视频

Iphone UIImagePickerController allowsEditing=是,修剪后获取未修剪的视频,iphone,ios,ipad,video,uiimagepickercontroller,Iphone,Ios,Ipad,Video,Uiimagepickercontroller,问题: - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType]; if (CFStringCompare ((__bridge CFStringRef)

问题:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];

    if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
        == kCFCompareEqualTo) {

        self.tempVideoPath = [[info objectForKey:
                                UIImagePickerControllerMediaURL] path];
    }
}
当我在我的
UIImagePickerController
中将allowsEditing设置为YES的情况下录制视频,然后使用视频捕获后的修剪界面修剪视频时,我会返回原始视频,而不是修剪后的视频

设置:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];

    if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
        == kCFCompareEqualTo) {

        self.tempVideoPath = [[info objectForKey:
                                UIImagePickerControllerMediaURL] path];
    }
}
我正在使用
UIImagePickerController
进行视频捕获,并将
allowsEditing
属性设置为YES。在委托方法中,我使用info
NSDictionary
中的
UIImagePickerControllerMediaURL
获取路径URL。不幸的是,不要提及任何编辑过的视频URL

代码:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];

    if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
        == kCFCompareEqualTo) {

        self.tempVideoPath = [[info objectForKey:
                                UIImagePickerControllerMediaURL] path];
    }
}
我意识到这个问题类似于在这里发布的SO,但没有明确的答案为什么它不起作用,或者为什么这个选项存在。如果打算这样做,我不明白为什么选择器有一个“allowsEditing”属性

编辑:在我得到的信息字典中有以下键:

info: {
    UIImagePickerControllerMediaType = "public.movie";
    UIImagePickerControllerMediaURL = "file://localhost/private/var/mobile/Applications/F12E4608-FE5A-4EE3-B4E2-8F7D2508C4C8/tmp/capture-T0x21d810.tmp.wabFCC/capturedvideo.MOV";
    "_UIImagePickerControllerVideoEditingEnd" = "5.498333333333333";
    "_UIImagePickerControllerVideoEditingStart" = "4.273402690887451";
}
这是否意味着我们必须用这些数据来修正它?那么苹果的文档对此不是很清楚。如果是的话,你知道这方面的好做法吗

为此,您需要使用。它指定了一个方法
videoEditorController:didSaveEditedVideoToPath:
,这似乎是您想要的。
有可用的示例代码,如中所述。

看看这篇文章中突出显示的答案:

我想这正是你想要的。答案也使用UIImagePickerController

希望有帮助,
Mário

下面是一个快速而肮脏的Swift 5示例,介绍如何从
UIImagePickerController

extension ViewController: UIImagePickerControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let mediaType = info[.mediaType] as! String

        dismiss(animated: true) { [weak self] in
            // Handle a movie capture
            if mediaType == kUTTypeMovie as String {
                guard let videoURL = info[.mediaURL] as? URL else {
                    SwiftyBeaver.error("Could not get URL for movie")
                    return
                }

                let editingEnd = UIImagePickerController.InfoKey(rawValue: "_UIImagePickerControllerVideoEditingEnd")
                let editingStart = UIImagePickerController.InfoKey(rawValue: "_UIImagePickerControllerVideoEditingStart")

                let startMilliseconds: Double?
                let endMilliseconds: Double?

                if let start = info[editingStart] as? Double, let end = info[editingEnd] as? Double {
                    startMilliseconds = start
                    endMilliseconds = end
                } else {
                    startMilliseconds = nil
                    endMilliseconds = nil
                }

                let alert = UIAlertController(title: "Creating", message: "File is being processed", preferredStyle: .alert)
                self?.present(alert, animated: true)
                self?.process(srcVideoURL: videoURL, startSeconds: startMilliseconds, endSeconds: endMilliseconds) { (error) in
                    DispatchQueue.main.async {
                        if let error = error {
                            alert.title = "Whoops"
                            alert.message = "\(error)"
                            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
                                self?.dismiss(animated: true, completion: nil)
                            }))
                            return
                        }
                        self?.dismiss(animated: true, completion: nil)
                    }
                }
            }
        }
    }
}

enum VideoError: Error {
    case error(message: String)
}

extension ViewController {
    func process(srcVideoURL: URL, startSeconds: Double?, endSeconds: Double?, completed: @escaping (_ error: Error?) -> ()) {
        DispatchQueue.global(qos: .userInitiated).async {
            let dstVideoURL: URL // some URL for the destination
            do {
                try self.handleNewVideo(srcVideoURL: srcVideoURL, dstVideoURL: dstVideoURL, startSeconds: startSeconds, endSeconds: endSeconds)
                completed(nil)
            } catch {
                completed(error)
            }
        }
    }

    func handleNewVideo(srcVideoURL: URL, dstVideoURL: URL, startSeconds: Double?, endSeconds: Double?) throws {
        guard let start = startSeconds, let end = endSeconds else {
            print("No video editing information. Copying file.")
            try FileManager.default.moveItem(at: srcVideoURL, to: dstVideoURL)
            return
        }

        print("Video editing information. Processing start \(start) end \(end).")
        let videoAsset = AVURLAsset(url: srcVideoURL)
        let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
        exportSession.outputURL = dstVideoURL
        exportSession.outputFileType = AVFileType.mov
        let timeRange = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 1000), duration: CMTime(seconds: end - start, preferredTimescale: 1000))
        exportSession.timeRange = timeRange

        var error: Error? = nil
        let dispatchGroup = DispatchGroup()
        dispatchGroup.enter()
        exportSession.exportAsynchronously(completionHandler: {
            switch exportSession.status {
            case .completed:
                break
            case .failed:
                error = exportSession.error ?? VideoError.error(message: "Unknown failed error")
            case .cancelled:
                error = exportSession.error ?? VideoError.error(message: "Video Cancelled")
            case .exporting:
                error = exportSession.error ?? VideoError.error(message: "Video still exporting")
            case .unknown:
                error = exportSession.error ?? VideoError.error(message: "Unknown unknown error")
            case .waiting:
                error = exportSession.error ?? VideoError.error(message: "Waiting error")
            @unknown default:
                error = exportSession.error ?? VideoError.error(message: "Future error")
            }
            dispatchGroup.leave()
        })
        dispatchGroup.wait()

        if let error = error {
            throw error
        }
    }
}

那么,这与
UIImagePickerController
结合使用会如何工作呢?如果您应该使用其他类,为什么首先会有
allowsditing
选项?任何方式startMillesons和endMillescies都会给出始终为零的值。