AVAssetExportSession increasing the size of video instead of compressing - ios

- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler
{
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.fileLengthLimit = 20*1024*1024;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
}];
}
I am using this code to compress a video
With the above code I successfully compressed 106mb video to 25mb.
With the above code I tried to compress 285mb video and I get 1.59gb as an output.
I can't understand what is going wrong.

Related

AVAssetExportSession export a video in Normal Rate even video is 120FPS

I recorded a video in 120FPS. It is SLOW_Mo video. IF I export that video in CameraRoll using PHImageManager. Everything is ok like as VIDEO Effect is slow_mo. I can play it using QuickPlayer and AVPlayer and effect is 120FPS.
This is my working code:
PHAsset *oneVideo = [[PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil] lastObject];
PHVideoRequestOptions *options = [PHVideoRequestOptions new];
options.networkAccessAllowed = YES;
options.version = PHVideoRequestOptionsVersionCurrent;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
[[PHImageManager defaultManager] requestAVAssetForVideo:oneVideo options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
if(([asset isKindOfClass:[AVComposition class]])){
BOOL bResult = FALSE;
DebugLog(#"\navPlayer.outputFileURL.absoluteString:%#", URl);
bResult = [[NSFileManager defaultManager] removeItemAtURL:URl error:nil];
DebugLog(#"\nremoveItemAtPath:%d", bResult);
//Begin slow mo video export
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = avPlayer.outputFileURL;
// exporter.outputURL = urlFirstVideoPath;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
NSLog(#"Video test run exported video into file: %#", exporter.outputURL);
NSLog(#"exportSession.status: %ld", (long)exporter.status);
dispatch_async(dispatch_get_main_queue(), ^{
if (exporter.status == AVAssetExportSessionStatusCompleted) {
NSLog(#"exportSession.status: okkkkkkk");
}
});
}];
}
}];
NOW I don't want to save that video in CAMERAROLL. I saved video in Document folder. and get AVAssets. But effect is not slow_mo 120FPS I READ about it and got i should use AVComposition for export slow_mo video. but i am unable to do it. Below is my NOT working code.
AVAsset *assetURL = [AVURLAsset URLAssetWithURL:URl options:nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = paths.firstObject;
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"mergeSlowMoVideo-%d.mov",arc4random() % 1000]];
NSURL *_filePath = [NSURL fileURLWithPath:myPathDocs];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:assetURL presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = _filePath;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{ //start
NSLog(#"Export failed: %#", [[exporter error] localizedDescription]);
NSLog(#"Video test run exported video into file: %#", exporter.outputURL);
NSLog(#"export %ld", (long)exporter.status);
dispatch_async(dispatch_get_main_queue(), ^{
if (exporter.status == AVAssetExportSessionStatusCompleted) {
}
});
}];
Please any expert help me.
UPDATE: this is my actual problem.
This Question has my Actual problem explanation

iOS: How to compress video to expected size if too big?

I would like to compress videos to an expected size if too big. For example, if my video is bigger than 2mb, I want to compress it next to 2mb. My goal is not to have a video superior to 2mb.
- (void)convertVideoToLowQualityWithInputURL:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
handler:(void (^)(AVAssetExportSession*))handler
{
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetLowQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
[exportSession release];
}];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSURL *outputURL = [NSURL fileURLWithPath:#"/Users/josh/Desktop/output.mov"];
[self convertVideoToLowQualityWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted)
{
printf("completed\n");
}
else
{
printf("error\n");
}
}];
}
Thanks in advance.

Video is playing in Simulator but not on real device

Video is playing in simulator but not on real device. Its stored in the local file path. After choosen the video from gallery, I'm compressing the video and storing the data in document directory. Here is the code.
video Compression:
- (void)compressVideo:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
handler:(void (^)(AVAssetExportSession*))handler
{
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
}];
}
Stored the compressed video here:
[self compressVideo:sourceURL outputURL:uploadURL handler:^(AVAssetExportSession *completion) {
if (completion.status == AVAssetExportSessionStatusCompleted) {
NSData *newDataForUpload = [NSData dataWithContentsOfURL:uploadURL];
// ...
}
];
And this is sourceURL and UploadURL
NSURL *sourceURL = [(AVURLAsset *)asset URL];
NSURL* uploadURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:#"temporaryPreview.mov"]];

Issue in playing Video URL in MPMoviePlayerController

I have to compress the video size in my app and play that compressed video in MPMoviePlayerController.I am using AVURLAsset to compress that video and after compressing i m getting a Output URL and when i am playing that URL it shows me this Err0r:-'NSInternalInconsistencyException', reason: 'property storage cannot find expected per-thread storage data
Here is the code
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) { handler(exportSession);
}];
What to do to resolve this issue.
Help me out

How To compress a video to accurate size in objective c?

Probably most of you using WhatsApp and you probably know that when you want to send a video to one of your contacts WhatsApp first of all compressing the video to maximum size of 16mb and only afterword it uploads the chosen video to your contact.
what i am trying to do it is simply the same thing using AV Foundation or to be more specific AVAssetExportSession.
here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *sourcePath =[documentsDirectory stringByAppendingString:#"/output.mov"];
NSURL *outputURL = [NSURL fileURLWithPath:sourcePath];
[self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted)
{
NSLog(#"completed");
}
else
{
NSLog(#"error: %#",exportSession.error);
}
}];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler
{
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
}];
}
this code works wonderful, it takes the video and compressing it really small size.
the problem is when the user try to upload a quite long video with powerful camera the size is not small enough to me.
What i want to do is actually to compress any video to a limited size
lets say for example to 16Mb like WhatsApp do.
How can i do that?
It doesn't seems to exist an easy way but AVAssetExportSession has an estimatedOutputFileLenght that could help.
In my code I iterate over different qualities and check if the file size is in the size I want:
NSURL * inputURL = [NSURL fileURLWithPath:path];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = nil;
for (NSString * string in #[AVAssetExportPresetHighestQuality,AVAssetExportPresetMediumQuality,AVAssetExportPresetLowQuality]) {
exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:string];
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
unsigned long long espectedFileSize = exportSession.estimatedOutputFileLength;
if (espectedFileSize < VIDE_LIMIT) {
break;
}
}
//Temp file
NSString *fileName = [NSString stringWithFormat:#"%#_%#", [[NSProcessInfo processInfo] globallyUniqueString], #"video.mov"];
NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
exportSession.outputURL = fileURL;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)

Resources