ios - 如何使用 Swift 修剪视频文件并转换为 20 秒视频?

标签 ios crop video-processing swift2

我想修剪视频文件。我只想从图库中选择视频并将其转换为 15 秒的视频。我正在关注 Objective C 的 this link 。它对我来说效果很好,但我是 Swift 语言的初学者。任何人都可以帮我在 Swift 中转换这段代码吗?

下面是我在 Objective C 中的代码:

-(void)cropVideo:(NSURL*)videoToTrimURL{
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoToTrimURL options:nil];
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *outputURL = paths[0];
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager createDirectoryAtPath:outputURL withIntermediateDirectories:YES attributes:nil error:nil];
    outputURL = [outputURL stringByAppendingPathComponent:@"output.mp4"];
    // Remove Existing File
    [manager removeItemAtPath:outputURL error:nil];

    //
    exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;
    CMTime start = CMTimeMakeWithSeconds(1.0, 600); // you will modify time range here
    CMTime duration = CMTimeMakeWithSeconds(19.0, 600);
    CMTimeRange range = CMTimeRangeMake(start, duration);
    exportSession.timeRange = range;
    [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
     {
         switch (exportSession.status) {
             case AVAssetExportSessionStatusCompleted:
                 [self writeVideoToPhotoLibrary:[NSURL fileURLWithPath:outputURL]];
                 NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error);
                 break;
             case AVAssetExportSessionStatusFailed:
                 NSLog(@"Failed:%@",exportSession.error);
                 break;
             case AVAssetExportSessionStatusCancelled:
                 NSLog(@"Canceled:%@",exportSession.error);
                 break;
             default:
                 break;
         }

         //[exportSession release];
     }];
}
-(void)writeVideoToPhotoLibrary:(NSURL*)aURL
{
    NSURL *url = aURL;
    NSData *data = [NSData dataWithContentsOfURL:url];

    // Write it to cache directory
    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"file.mov"];
    [data writeToFile:path atomically:YES];


    // After that use this path to save it to PhotoLibrary

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:path] completionBlock:^(NSURL *assetURL, NSError *error) {

        if (error) {
            NSLog(@"%@", error.description);
        }else {
            NSLog(@"Done :)");
        }

    }];


}

最佳答案

为了快速,您可以使用以下代码来修剪视频。

func trimVideo(sourceURL: NSURL, destinationURL: NSURL, trimPoints: TrimPoints, completion: TrimCompletion?) {
    assert(sourceURL.fileURL)
    assert(destinationURL.fileURL)

    let options = [ AVURLAssetPreferPreciseDurationAndTimingKey: true ]
    let asset = AVURLAsset(URL: sourceURL, options: options)
    let preferredPreset = AVAssetExportPresetPassthrough
    if verifyPresetForAsset(preferredPreset, asset) {
        let composition = AVMutableComposition()
        let videoCompTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
        let audioCompTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())

        let assetVideoTrack: AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first as! AVAssetTrack
        let assetAudioTrack: AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first as! AVAssetTrack

        var compError: NSError?

        var accumulatedTime = kCMTimeZero
        for (startTimeForCurrentSlice, endTimeForCurrentSlice) in trimPoints {
            let durationOfCurrentSlice = CMTimeSubtract(endTimeForCurrentSlice, startTimeForCurrentSlice)
            let timeRangeForCurrentSlice = CMTimeRangeMake(startTimeForCurrentSlice, durationOfCurrentSlice)

            videoCompTrack.insertTimeRange(timeRangeForCurrentSlice, ofTrack: assetVideoTrack, atTime: accumulatedTime, error: &compError)
            audioCompTrack.insertTimeRange(timeRangeForCurrentSlice, ofTrack: assetAudioTrack, atTime: accumulatedTime, error: &compError)

            if compError != nil {
                NSLog("error during composition: \(compError)")
                if let completion = completion {
                    completion(compError)
                }
            }

            accumulatedTime = CMTimeAdd(accumulatedTime, durationOfCurrentSlice)
        }

        let exportSession = AVAssetExportSession(asset: composition, presetName: preferredPreset)
        exportSession.outputURL = destinationURL
        exportSession.outputFileType = AVFileTypeAppleM4V
        exportSession.shouldOptimizeForNetworkUse = true

        removeFileAtURLIfExists(destinationURL)

        exportSession.exportAsynchronouslyWithCompletionHandler({ () -> Void in
            if let completion = completion {
                completion(exportSession.error)
            }
        })
    } else {
        NSLog("Could not find a suitable export preset for the input video")
        let error = NSError(domain: "org.linuxguy.VideoLab", code: -1, userInfo: nil)
        if let completion = completion {
            completion(error)
        }
    }
}

TrimPoints 是一个 CMTime。

关于ios - 如何使用 Swift 修剪视频文件并转换为 20 秒视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55425910/

相关文章:

ios - 裁剪图像与更新版本的 Instagram 相同

objective-c - 自动释放,没有池 - 只是泄漏

ios - 核心数据sectionNameKeyPath与关系属性性能问题

ios - 我可以在滚动位置停止 UIScrollView 吗?

c# - 剪辑区域不起作用

crop - 在同一命令中进行 graphicsmagick 合成和裁剪

asp.net-mvc-5 - ASP.NET MVC上传视频文件并将其从HttpPostedFileBase转换为图像文件(帧)

opencv - ffmpeg FPS 信息与视频不匹配

ios - 选项卡栏确实选择了委托(delegate)方法在 ios 中给出了先前选择的选项卡索引,swift 3

c++ - LIBAV MJPEG编码和霍夫曼表