1

I'm developing iOS App in objective C.

As per my requirement, I want to split video in multiple parts.

Suppose I have a video of 50 seconds and I want to divide it in 5 parts of 10 seconds each.

Please advice me if you guys have any idea about it.

Atur
  • 1,712
  • 6
  • 32
  • 42
Sonu
  • 937
  • 1
  • 10
  • 39
  • May be [this][1] help you for splitting video in multiple parts. [1]: http://stackoverflow.com/questions/13987357/split-a-movie-into-two-parts-an-then-concatenate-one-of-the-movie-with-another-m – Raj Jun 16 '14 at 12:41

2 Answers2

2

Swift 5 version of @MilanPatel answer, that i found very useful :

func splitSecondVideo() {
   
        guard did<splitdivide else {return}
        guard let videourl = URL(string: "YOUR_VIDEO_URL_HERE") else {return}
        let asset = AVURLAsset(url: videourl, options: nil)

        let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)

        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).map(\.path)
        let documentsDirectory = paths[0]
        var myPathDocs: String?
        var starttime: CMTime
        var duration: CMTime

        myPathDocs = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("SplitFinalVideo\(did).mov").path
        let endt = CMTimeGetSeconds(asset.duration)
        print("All Duration : \(endt)")
        let divide = CMTimeGetSeconds(asset.duration) / splitdivide
        print("All Duration : \(divide)")

        starttime = CMTimeMakeWithSeconds(Float64(divide * did), preferredTimescale: 1)
        duration = CMTimeMakeWithSeconds(Float64(divide), preferredTimescale: 1)

        let fileManager = FileManager()
        var error: Error?
        if fileManager.fileExists(atPath: myPathDocs ?? "") == true {
            do {
                try fileManager.removeItem(atPath: myPathDocs ?? "")
            } catch {
            }
        }

        exportSession?.outputURL = URL(fileURLWithPath: myPathDocs ?? "")
        exportSession?.shouldOptimizeForNetworkUse = true
        exportSession?.outputFileType = .mov
        // Trim to half duration

        let secondrange = CMTimeRangeMake(start: starttime, duration: duration)

        exportSession?.timeRange = secondrange
        exportSession?.exportAsynchronously(completionHandler: { [self] in
            exportDidFinish(exportSession)
            did += 1
            self.splitSecondVideo()

        })
  
}

func exportDidFinish(_ session: AVAssetExportSession?) {
    if session?.status == .completed {
        let outputURL = session?.outputURL
        print("Before Exported")
        saveVideoAtPath(with: outputURL)
    }
}

Another update: session?.status was always coming failed. To solve this issue, I added:

 asset.resourceLoader.setDelegate(self, queue: .main)

and conform to AVAssetResourceLoaderDelegate protocol and it start working. Thanks to this answer by @panychyk.dima

Vikas saini
  • 648
  • 1
  • 17
1

Nice Question.The solution is here...

-(void)splitSecondVideo
{
if (did<splitdivide){

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:_videourl options:nil];

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

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs;
CMTime starttime;
CMTime duration;

    myPathDocs =  [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"SplitFinalVideo%d.mov",did]];
    double endt=CMTimeGetSeconds([asset duration]);
    NSLog(@"All Duration : %f",endt);
    double divide=CMTimeGetSeconds([asset duration])/splitdivide;
    NSLog(@"All Duration : %f",divide);

    starttime = CMTimeMakeWithSeconds(divide*did, 1);
    duration = CMTimeMakeWithSeconds(divide, 1);

NSFileManager *fileManager=[[NSFileManager alloc]init];
NSError *error;
if ([fileManager fileExistsAtPath:myPathDocs] == YES) {
    [fileManager removeItemAtPath:myPathDocs error:&error];
}

exportSession.outputURL = [NSURL fileURLWithPath:myPathDocs];
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
// Trim to half duration

CMTimeRange secondrange = CMTimeRangeMake(starttime, duration);

exportSession.timeRange = secondrange;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
 {
     [self exportDidFinish:exportSession];
     did++;

     [self splitSecondVideo];

 }];

}} 

- (void)exportDidFinish:(AVAssetExportSession*)session {
if (session.status == AVAssetExportSessionStatusCompleted) {
    NSURL *outputURL = session.outputURL;
    NSLog(@"Before Exported");
    [self SaveVideoAtPathWithURL:outputURL];
}} 

Where did=0.0 in viewDidLoad method.& splitdivide is the value that you want to create the part of the video.In your question splitdivide=5; Note : The did & split divide are both the Integer Value.

Hope this is helpful....Enjoy...

Milan patel
  • 223
  • 2
  • 15