سؤال

أعمل حاليًا على تطبيق يتعامل مع مقاطع الفيديو.في التطبيق الخاص بي، يمكن للمستخدم قص الفيديو، ولدي تحكم مخصص لتحديد وقت البدء ووقت الانتهاء.أحتاج إلى قص الفيديو بهاتين القيمتين.حاولت مع 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 );
    }

لكن المشكلة هي أن الكود أعلاه سيعرض التحكم في محرر فيديو Apple ويمكن للمستخدم إجراء بعض العمليات على هذا العرض.لا أريد عرض هذا العرض، لأنني عرضت الفيديو بالفعل MPMoviePlayer وتلقى إدخال المستخدم (وقت البدء و وقت النهاية) لقص الفيديو على عنصر تحكم مخصص.كيف يمكنني قص مقطع فيديو دون عرضه UIVideoEditorController ?

هل كانت مفيدة؟

المحلول

وأخيرا وجدت الحل.

يمكننا ان نستخدم AVAssetExportSession لتقليم الفيديو دون عرض UIVideoEditorController.

الكود الخاص بي هو مثل:

- (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]);
    }
}

هذه الطريقة تقطع الفيديو

- (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]);
    }
}

تتحقق هذه الطريقة من حالة التشذيب:

- (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;

        }
    }];
}

أنا أتصل بـ splitVideo الطريقة من طريقة إجراء زر التصدير وتمرير عنوان URL للإخراج كحجة.

نصائح أخرى

يمكننا استيراد 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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top