как обрезать видео в swift на определенное время

Я работаю над задачей, в которой я должен обрезать записанное видео от определенной начальной точки до определенной конечной точки, введенной или выбранной пользователем. Как мне это сделать? Как я использовал UIVideoEditorController раньше, но я не хочу использовать представление по умолчанию, и я хочу обрезать видео напрямую.

let FinalUrlTosave = NSURL(string: "(newURL)")
    exportSession!.outputURL=FinalUrlTosave
    exportSession!.shouldOptimizeForNetworkUse = true
    // exportSession.outputFileType = AVFileTypeQuickTimeMovie
    exportSession!.outputFileType = AVFileTypeQuickTimeMovie;
    let start:CMTime
    let duration:CMTime
    var st = starttime.doubleValue
    var ed = endTime.doubleValue
    start = CMTimeMakeWithSeconds(st, 600)
    duration = CMTimeMakeWithSeconds(ed, 600)
    // let timeRangeForCurrentSlice = CMTimeRangeMake(start, duration)
    let range = CMTimeRangeMake(start, duration);
    exportSession!.timeRange = range

       exportSession!.exportAsynchronouslyWithCompletionHandler({
        switch exportSession!.status{
        case  AVAssetExportSessionStatus.Failed:

            print("failed (exportSession!.error)")
        case AVAssetExportSessionStatus.Cancelled:
            print("cancelled (exportSession!.error)")
        default:
            print("complete....complete")
            //                self.SaveVideoToPhotoLibrary(destinationURL1!)

        }
    })

Я пытаюсь достичь своей цели, используя это, но не получается.

сообщение об ошибке:

ошибка необязательная (домен ошибки=NSURLErrorDomain Код=-1100 "В запрошенный url не найден на этом сервере." UserInfo={NSErrorFailingURLStringKey=file:///var/mobile/Containers/Data/Application/E68D3BFD-6923-4EA6-9FB3-C020CE4AA9D4/Documents/moment/jGq_9AUFa47s2ZiiPP4x.mp4, NSErrorFailingURLKey=file:///var/mobile/Containers/Data/Application/E68D3BFD-6923-4EA6-9FB3-C020CE4AA9D4/Documents/moment/jGq_9AUFa47s2ZiiPP4x.mp4, NSLocalizedDescription=запрошенный URL-адрес не найден сервер., NSUnderlyingError=0x1553c220 {ошибка Домен=N

ошибка произошла во второй раз:

Не дополнительно(ошибка Domain=NSURLErrorDomain код=-3000 "не может создать файл " UserInfo={NSUnderlyingError=0x14e00000 {ошибка Домен=Nsosstatuserrordomain код=-12124 "(null)"}, NSLocalizedDescription=не удается создать файл})

3 ответов


Я нашел свое решение с помощью этого метода, и он работает как шарм....

func cropVideo(sourceURL1: NSURL, statTime:Float, endTime:Float)
{
    let manager = NSFileManager.defaultManager()

    guard let documentDirectory = try? manager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) else {return}
    guard let mediaType = "mp4" as? String else {return}
    guard let url = sourceURL1 as? NSURL else {return}

    if mediaType == kUTTypeMovie as String || mediaType == "mp4" as String {
        let asset = AVAsset(URL: url)
        let length = Float(asset.duration.value) / Float(asset.duration.timescale)
        print("video length: \(length) seconds")

        let start = statTime
        let end = endTime

        var outputURL = documentDirectory.URLByAppendingPathComponent("output")
        do {
            try manager.createDirectoryAtURL(outputURL, withIntermediateDirectories: true, attributes: nil)
            let name = Moment.newName()
            outputURL = outputURL.URLByAppendingPathComponent("\(name).mp4")
        }catch let error {
            print(error)
        }

        //Remove existing file
        _ = try? manager.removeItemAtURL(outputURL)


        guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {return}
        exportSession.outputURL = outputURL
        exportSession.outputFileType = AVFileTypeMPEG4

        let startTime = CMTime(seconds: Double(start ?? 0), preferredTimescale: 1000)
        let endTime = CMTime(seconds: Double(end ?? length), preferredTimescale: 1000)
        let timeRange = CMTimeRange(start: startTime, end: endTime)

        exportSession.timeRange = timeRange
        exportSession.exportAsynchronouslyWithCompletionHandler{
            switch exportSession.status {
            case .Completed:
                print("exported at \(outputURL)")
               self.saveVideoTimeline(outputURL)
            case .Failed:
                print("failed \(exportSession.error)")

            case .Cancelled:
                print("cancelled \(exportSession.error)")

            default: break
            }
        }
    }
}

версия swift4 для этого.

static func cropVideo(sourceURL: URL, startTime: Double, endTime: Double, completion: ((_ outputUrl: URL) -> Void)? = nil)
{
    let fileManager = FileManager.default
    let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]

    let asset = AVAsset(url: sourceURL)
    let length = Float(asset.duration.value) / Float(asset.duration.timescale)
    print("video length: \(length) seconds")

    var outputURL = documentDirectory.appendingPathComponent("output")
    do {
        try fileManager.createDirectory(at: outputURL, withIntermediateDirectories: true, attributes: nil)
        outputURL = outputURL.appendingPathComponent("\(sourceURL.lastPathComponent).mp4")
    }catch let error {
        print(error)
    }

    //Remove existing file
    try? fileManager.removeItem(at: outputURL)

    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else { return }
    exportSession.outputURL = outputURL
    exportSession.outputFileType = .mp4

    let timeRange = CMTimeRange(start: CMTime(seconds: startTime, preferredTimescale: 1000),
                                end: CMTime(seconds: endTime, preferredTimescale: 1000))

    exportSession.timeRange = timeRange
    exportSession.exportAsynchronously {
        switch exportSession.status {
        case .completed:
            print("exported at \(outputURL)")
            completion?(outputURL)
        case .failed:
            print("failed \(exportSession.error.debugDescription)")
        case .cancelled:
            print("cancelled \(exportSession.error.debugDescription)")
        default: break
        }
    }
}

func cropVideo1 (_sourceURL1: URL, statTime:Float, endTime:Float)

{

    let videoAsset: AVAsset = AVAsset(url: sourceURL1) as AVAsset
    let composition = AVMutableComposition()
    composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())

    let videoComposition = AVMutableVideoComposition()
    videoComposition.renderSize = CGSize(width: 1280, height: 768)
    videoComposition.frameDuration = CMTimeMake(8, 15)

    let instruction = AVMutableVideoCompositionInstruction()
    let length = Float(videoAsset.duration.value)
    print(length)

    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))

    let start = statTime
    let end = endTime

    let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
    exportSession.outputFileType = AVFileTypeMPEG4

    let startTime = CMTime(seconds: Double(start ), preferredTimescale: 1000)
    let endTime = CMTime(seconds: Double(end ), preferredTimescale: 1000)
    let timeRange = CMTimeRange(start: startTime, end: endTime)

    exportSession.timeRange = timeRange

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"

    let date = Date()

    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
    let outputPath = "\(documentsPath)/\(formatter.string(from: date)).mp4"
    let outputURL = URL(fileURLWithPath: outputPath)

    exportSession.outputURL = outputURL
    exportSession.outputFileType = AVFileTypeQuickTimeMovie
    print("sucess")


    exportSession.exportAsynchronously(completionHandler: { () -> Void in
        DispatchQueue.main.async(execute: {

            self.exportDidFinish(exportSession)
            print("sucess")

            DispatchQueue.main.async(execute: {



            });
        })
    })
}

func exportDidFinish (_session: AVAssetExportSession) {

    if session.status == AVAssetExportSessionStatus.completed {
        let outputURL = session.outputURL
        let library = ALAssetsLibrary()
        if library.videoAtPathIs(compatibleWithSavedPhotosAlbum: outputURL) {
            library.writeVideoAtPath(toSavedPhotosAlbum: outputURL) { alAssetURL, error in


                if error != nil {
                    DispatchQueue.main.async(execute: {


                        print("Failed to save video")


                    })
                } else {
                    DispatchQueue.main.async(execute: {


                      Print("Sucessfully saved Video")



                    })

                }
                self.activityIndicator.stopAnimating()
            }
        }
    }


}