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

标签 ios crop video-processing swift2

我想修剪视频文件。我只想从图库中选择视频并将其转换为 15 秒的视频。我正在关注 this link for Objective C。它对我来说很好用,但我是 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 :)");
        }

    }];


}

最佳答案

对于swift,您可以使用以下代码来修剪视频。

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/31070941/

相关文章:

iphone - 如何将文档文件夹隐藏到 PhoneView 等 3rd 方应用程序?

ios - swift 3 : Grid of table views

android - 居中裁剪图像以适当的尺寸设置在 ImageView 上

audio - 如何使用 ffmpeg 删除长时间无声且未更改的视频部分?

python - 是否可以将提取的 'img%d.jpg' 图像从 ffmpeg 传输到另一个软件而不将图像保存在任何地方?

ios - 如何在不插入模型对象的情况下使用它?

ios - 使用 ScrollView 时状态栏的背景颜色变为白色

c#当裁剪图像出现黑色边框时

Swift:用于 UIImageView 的 CropView

linux - 从 Linux 图形工具制作图像幻灯片