xcode 在不显示 UIVideoEditorController 的情况下修剪视频?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12714938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 15:53:03  来源:igfitidea点击:

Trim video without displaying UIVideoEditorController?

iosxcodevideouivideoeditorcontroller

提问by Midhun MP

Currently I'm working on a application which deals with the videos. In my application user can trim the video, I have a custom control for selecting the start time and end time. I need to trim the video by these two values. I tried with UIVideoEditorControllerlike follows.

目前我正在开发一个处理视频的应用程序。在我的应用程序中,用户可以修剪视频,我有一个用于选择开始时间和结束时间的自定义控件。我需要通过这两个值来修剪视频。我试过UIVideoEditorController如下。

    UIVideoEditorController* videoEditor = [[[UIVideoEditorController alloc] init] autorelease];
    videoEditor.delegate = self;
    NSString* videoPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"MOV"];
    if ( [UIVideoEditorController canEditVideoAtPath:videoPath] )
    {
      videoEditor.videoPath = videoPath;
      [self presentModalViewController:videoEditor animated:YES];
    }
    else
    {
      NSLog( @"can't edit video at %@", videoPath );
    }

But the issue is the above code will display apple's video editor control and user can do some operations on that view. I don't want to display this view, because I have already displayed the video on MPMoviePlayerand received the user input (start timeand end time) for trimming the video on a custom control. How can I trim a video without displaying UIVideoEditorController?

但问题是上面的代码将显示苹果的视频编辑器控件,用户可以对该视图进行一些操作。我不想显示此视图,因为我已经在自定义控件上显示视频MPMoviePlayer并收到用户输入(开始时间结束时间)以修剪视频。如何在不显示的情况下修剪视频UIVideoEditorController

回答by Midhun MP

Finally I found the solution.

最后我找到了解决方案。

We can use AVAssetExportSessionfor trimming video without displaying UIVideoEditorController.

我们可以AVAssetExportSession在不显示的情况下用于修剪视频UIVideoEditorController

My code is like:

我的代码是这样的:

- (void)splitVideo:(NSString *)outputURL
{

    @try
    {
        NSString *videoBundleURL = [[NSBundle mainBundle] pathForResource:@"Video_Album" ofType:@"mp4"];

        AVAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:videoBundleURL] options:nil];

        NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset];

        if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
        {

            [self trimVideo:outputURL assetObject:asset];

        }
        videoBundleURL = nil;

        [asset release];
        asset = nil;

        compatiblePresets = nil;
    }
    @catch (NSException * e)
    {
        NSLog(@"Exception Name:%@ Reason:%@",[e name],[e reason]);
    }
}

This method trims the video

此方法修剪视频

- (void)trimVideo:(NSString *)outputURL assetObject:(AVAsset *)asset
  {

    @try
    {

        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:asset presetName:AVAssetExportPresetLowQuality];

        exportSession.outputURL = [NSURL fileURLWithPath:outputURL];

        exportSession.outputFileType = AVFileTypeQuickTimeMovie;

        CMTime start = CMTimeMakeWithSeconds(splitedDetails.startTime, 1);

        CMTime duration = CMTimeMakeWithSeconds((splitedDetails.stopTime - splitedDetails.startTime), 1);

        CMTimeRange range = CMTimeRangeMake(start, duration);

        exportSession.timeRange = range;

        exportSession.outputFileType = AVFileTypeQuickTimeMovie;

        [self checkExportSessionStatus:exportSession];

        [exportSession release];
        exportSession = nil;

    }
    @catch (NSException * e)
    {
        NSLog(@"Exception Name:%@ Reason:%@",[e name],[e reason]);
    }
}

This method checks the status of trimming:

此方法检查修剪的状态:

- (void)checkExportSessionStatus:(AVAssetExportSession *)exportSession
  {

    [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
    {

        switch ([exportSession status])
            {

            case AVAssetExportSessionStatusCompleted:

                NSLog(@"Export Completed");
                break;

            case AVAssetExportSessionStatusFailed:

                NSLog(@"Error in exporting");
                break;

            default:
                break;

        }
    }];
}

I'm calling the splitVideomethod from the export button action method and passes the output URLas argument.

我正在splitVideo从导出按钮操作方法调用该方法并将输出 URL作为参数传递。

回答by Vaibhav Sharma

We can import AVFoundation/AVFoundation.h

我们可以导入 AVFoundation/AVFoundation.h

-(BOOL)trimVideofile
{

    float videoStartTime;//define start time of video
    float videoEndTime;//define end time of video
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *libraryCachesDirectory = [paths objectAtIndex:0];
    libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:@"Caches"];
    NSString *OutputFilePath = [libraryCachesDirectory stringByAppendingFormat:@"/output_%@.mov", [dateFormatter stringFromDate:[NSDate date]]];
    NSURL *videoFileOutput = [NSURL fileURLWithPath:OutputFilePath];
    NSURL *videoFileInput;//<Path of orignal Video file>

    if (!videoFileInput || !videoFileOutput)
    {
        return NO;
    }

    [[NSFileManager defaultManager] removeItemAtURL:videoFileOutput error:NULL];
    AVAsset *asset = [AVAsset assetWithURL:videoFileInput];

    AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
                                                                            presetName:AVAssetExportPresetLowQuality];
    if (exportSession == nil)
    {
        return NO;
    }
    CMTime startTime = CMTimeMake((int)(floor(videoStartTime * 100)), 100);
    CMTime stopTime = CMTimeMake((int)(ceil(videoEndTime * 100)), 100);
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);

    exportSession.outputURL = videoFileOutput;
    exportSession.timeRange = exportTimeRange;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;

    [exportSession exportAsynchronouslyWithCompletionHandler:^
     {
         if (AVAssetExportSessionStatusCompleted == exportSession.status)
         {
            NSLog(@"Export OK");
         }
         else if (AVAssetExportSessionStatusFailed == exportSession.status)
         {
             NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
         }
     }];
    return YES;
}