Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest Way to Compress Video Size Using Library or Algo

I'm trying to compress high quality video into less size and I'm able to reduce the size of video that I've compressed using the following objective-c code:

 - (BOOL)convertMovieToMP4:(NSString ) originalMovPath andStoragePath:(NSString ) compMovPath
        {
            NSURL *tmpSourceUrl = [NSURL fileURLWithPath:originalMovPath];

            compMovPath = [compMovPath stringByReplacingOccurrencesOfString:[compMovPath pathExtension] withString:@"mp4"];
            NSURL *tmpDestUrl = [NSURL fileURLWithPath:compMovPath];

            AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:tmpSourceUrl options:nil];
            AVMutableComposition* mixComposition = [AVMutableComposition composition];

            AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo  preferredTrackID:kCMPersistentTrackID_Invalid];

            AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
            [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                           ofTrack:clipVideoTrack
                                            atTime:kCMTimeZero error:nil];

            [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]];

            CGSize videoSize = [[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];

            CATextLayer *titleLayer = [CATextLayer layer];
            titleLayer.string = @"Ojatro";
            titleLayer.font = (_bridge CFTypeRef Nullable)(@"Helvetica");
            titleLayer.fontSize = videoSize.height / 8;
            titleLayer.shadowOpacity = 0.2;
            titleLayer.alignmentMode = kCAAlignmentCenter;
            titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height / 6);
            titleLayer.position=CGPointMake(videoSize.width/2, videoSize.height/2);

            CALayer *parentLayer = [CALayer layer];
            CALayer *videoLayer = [CALayer layer];
            parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
            videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
            [parentLayer addSublayer:videoLayer];
            [parentLayer addSublayer:titleLayer];

            AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition];
            videoComp.renderSize = videoSize;
            videoComp.frameDuration = CMTimeMake(1, 30);
            videoComp.animationTool = [AVVideoCompositionCoreAnimationTool      videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

            AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
            instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]);

            AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

            AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];

            instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
            videoComp.instructions = [NSArray arrayWithObject: instruction];

            AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality];//AVAssetExportPresetPasst
            _assetExport.videoComposition = videoComp;
            //NSString* videoName = @"mynewwatermarkedvideo.mov";
            NSString *tmpDirPath = [compMovPath stringByReplacingOccurrencesOfString:[compMovPath lastPathComponent] withString:@""];
            if ([Utility makeDirectoryAtPath:tmpDirPath])
            {
                NSLog(@"Directory Created");
            }
            //exportPath=[exportPath stringByAppendingString:videoName];
            NSURL    *exportUrl = tmpDestUrl;

            if ([[NSFileManager defaultManager] fileExistsAtPath:compMovPath])
            {
                [[NSFileManager defaultManager] removeItemAtPath:compMovPath error:nil];
            }

            _assetExport.outputURL = exportUrl;
            _assetExport.shouldOptimizeForNetworkUse = YES;
            _assetExport.outputFileType = AVFileTypeMPEG4;

            //[strRecordedFilename setString: exportPath];

            [_assetExport exportAsynchronouslyWithCompletionHandler:
             ^(void ) {
                 switch (_assetExport.status)
                 {
                     case AVAssetExportSessionStatusUnknown:
                         NSLog(@"Export Status Unknown");

                         break;
                     case AVAssetExportSessionStatusWaiting:
                         NSLog(@"Export Waiting");

                         break;
                     case AVAssetExportSessionStatusExporting:
                         NSLog(@"Export Status");

                         break;
                     case AVAssetExportSessionStatusCompleted:
                         NSLog(@"Export Completed");
                         totalFilesCopied++;
                         [self startProgressBar];

                         break;
                     case AVAssetExportSessionStatusFailed:
                         NSLog(@"Export failed");

                         break;
                     case AVAssetExportSessionStatusCancelled:
                         NSLog(@"Export canceled");

                         break;
                 }
             }
             ];
            return NO;
        }

But my main problem is that when I compress the 500MB video (i.e average video) file and it takes approximately 20 to 30+ minutes. It reduce the video size to approximately 130MB. I'm using the Native AVFoundation Library to compress the video to reduce its size.

I need to compress the video size very fast just like Apple Compressor application, it compresses the 500MB file within 30 seconds only...

https://itunes.apple.com/en/app/compressor/id424390742?mt=12

I've also used FFMPEG library for that, but that is also slow I did not found that library anymore useful.

I've also tried to find the solution using other languages like, java, python. but did not found any solution was found.

If anyone has the solution for this particular problem, or has some libraries (i.e Paid library or Open Source Library) that can do the compression with less time at least 1 minute... Please do share with me. Or some other piece of code that can overcome the compression time problem from 20 - 30 minutes to at least 1 minute.

Thanks...

like image 209
Muhammd Hassan Avatar asked Aug 02 '16 22:08

Muhammd Hassan


Video Answer


1 Answers

Here is a document, which contains some RnD on video compression: https://drive.google.com/file/d/0BySTUFVtfzJmM3pYeVRiWmxSLVU/view

It also contains a sample code for quick compression of videos in objective-C. It uses AVAssetExportSession for compressing videos.

like image 93
Aneeq Anwar Avatar answered Nov 15 '22 00:11

Aneeq Anwar