Issue in playing Video URL in MPMoviePlayerController - ios

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

Related

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"]];

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)

How do you compress a local video to a custom size in iOS?

AVAssetExportSession allows me to compress a video using different presets such as AVAssetExportPreset1280x720 like so
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPreset1280x720];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
}];
But what if I wanted to compress my local video to a custom size such as 640x360. Is there a way to accomplish this?

AVAssetExportSession increasing the size of video instead of compressing

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

Play song from ipod library with superpowered

since Apple anounced that every app has to support 64-bit starting February 1rst, I can't use Dirac3LE anymore. So I found Superpowered which seems to do the same. The only problem I currently see is, that I can't get it to play songs from the iPod Library.
I've tried importing the song via AVAssetExportSession but can't get it to work. This is the code I've tried so far:
NSURL *url = [playingSong valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset presetName: AVAssetExportPresetPassthrough];
exporter.outputFileType = #"com.apple.coreaudio-format";
NSString *fname = [[NSString stringWithFormat:#"tmp"] stringByAppendingString:#".mp3"];
NSString *tempPath = NSTemporaryDirectory();
NSString *exportFile = [tempPath stringByAppendingPathComponent: fname];
exporter.outputURL = [NSURL fileURLWithPath:exportFile];
[exporter exportAsynchronouslyWithCompletionHandler:^{
self.player = [[SuperpoweredAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:exportFile]];
[self.player play];
}];
With opening the file via:
player->open([[url path] fileSystemRepresentation]);
Even if this would work, I'm kind of concerned if this would be fast enough for a music player. Importing a song, as soon as the other finished.
Are there any other options?
Thanks!
if you have a MPMediaItem *item got from iTunes Library, you can use:
player->open([[item assetURL].absoluteString UTF8String]);

Resources