Get Audio (mp3) From MOV File iOS - ios

How can I extract the Audio (preferably .mp3) from a .MOV file I got from the user's camera roll?
I extract the MOV file here:
- (void) imagePickerController: (UIImagePickerController *) picker
didFinishPickingMediaWithInfo: (NSDictionary *) info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:NO completion:nil];
if (CFStringCompare ((__bridge_retained CFStringRef)mediaType, kUTTypeMovie, 0)
== kCFCompareEqualTo) {
NSString *fileName = [[info objectForKey:
UIImagePickerControllerMediaURL] path];
NSData *data = [[NSData alloc] initWithContentsOfFile:moviePath];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
Please let me know if more code need be provided but I think this is a sufficient amount of information.
I have tried a few things but gotten absolutely nowhere. Any help is appreciated. Thank you

I extract m4a file using the following piece of code and write the file application documents directory
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
AVMutableComposition *newAudioAsset = [AVMutableComposition composition];
AVMutableCompositionTrack *dstCompositionTrack = [newAudioAsset addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// 1 - Get media type
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
// 2 - Dismiss image picker
[self dismissViewControllerAnimated:YES completion:nil];
// 3 - Handle video selection
if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
videoAsset = [AVAsset assetWithURL:[info objectForKey:UIImagePickerControllerMediaURL]];
// NSLog(#"track = %#",[videoAsset tracksWithMediaType:AVMediaTypeAudio]);
NSArray *trackArray = [videoAsset tracksWithMediaType:AVMediaTypeAudio];
if(!trackArray.count){
NSLog(#"Track returns empty array for mediatype AVMediaTypeAudio");
return;
}
AVAssetTrack *srcAssetTrack = [trackArray objectAtIndex:0];
//Extract time range
CMTimeRange timeRange = srcAssetTrack.timeRange;
NSError *err = nil;
if(NO == [dstCompositionTrack insertTimeRange:timeRange ofTrack:srcAssetTrack atTime:kCMTimeZero error:&err]){
NSLog(#"Failed to insert audio from the video to mutable avcomposition track");
return;
}
//Export the avcompostion track to destination path
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];
NSString *dstPath = [documentsDirectory stringByAppendingString:#"/sample_audio.m4a"];
NSURL *dstURL = [NSURL fileURLWithPath:dstPath];
//Remove if any file already exists
[[NSFileManager defaultManager] removeItemAtURL:dstURL error:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:newAudioAsset presetName:AVAssetExportPresetPassthrough];
NSLog(#"support file types= %#", [exportSession supportedFileTypes]);
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.outputURL = dstURL;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
AVAssetExportSessionStatus status = exportSession.status;
if(AVAssetExportSessionStatusCompleted != status){
NSLog(#"Export status not yet completed. Error: %#", exportSession.error.description);
}
}];
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Asset Loaded" message:#"Video Asset Loaded"
// delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// [alert show];
}
}

Related

Export session error - When using AVAudioPlayer for mp3 files

In my app I can access the device music library, and when you select a song, it loads, however, it no longer works, and I am constantly met with the error 'export session error'
Then the app just hangs with the spinning loading bar forever until I close the app.
Select music AssetUrl = ipod-library://item/item.mp3?id=2023536838012570661
export session error
The files that I believe are troublesome are .mp3 files;
If I use .m4a files, it seems to work fine - so is there a way to block mp3 files from appearing in the mediapicker? Or at least an alert to show the user they can't use them if they try to select an mp3 file?
Here is the code;
Picker code;
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection
{
dispatch_async(dispatch_get_main_queue(), ^{
// Dismiss the media item picker.
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaItemCollection count] < 1) {
return;
}
[selectedItem release];
selectedItem = [[[mediaItemCollection items] objectAtIndex:0] retain];
NSURL* filePath = [selectedItem valueForProperty: MPMediaItemPropertyAssetURL];
NSLog(#"Select music AssetUrl = %#", filePath);
});
}
- (void)exportAssetAsSourceFormat:(MPMediaItem *)item {
dispatch_async(dispatch_get_main_queue(), ^{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL]; //MPMediaItemPropertyAssetURL
if (assetURL == nil)
{
NSLog(#"assetURL is null");
[pool release];
return;
}
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
// JP
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
initWithAsset:songAsset
presetName:AVAssetExportPresetPassthrough];
NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *track = [tracks objectAtIndex:0];
id desc = [track.formatDescriptions objectAtIndex:0];
const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
FourCharCode formatID = audioDesc->mFormatID;
NSString *fileType = nil;
NSString *ex = nil;
switch (formatID) {
case kAudioFormatLinearPCM:
{
UInt32 flags = audioDesc->mFormatFlags;
if (flags & kAudioFormatFlagIsBigEndian) {
fileType = #"public.aiff-audio";
ex = #"aif";
} else {
fileType = #"com.microsoft.waveform-audio";
ex = #"wav";
}
}
break;
case kAudioFormatMPEGLayer3:
fileType = #"com.apple.quicktime-movie";
ex = #"mp3";
break;
case kAudioFormatMPEG4AAC:
fileType = #"com.apple.m4a-audio";
ex = #"m4a";
break;
case kAudioFormatAppleLossless:
fileType = #"com.apple.m4a-audio";
ex = #"m4a";
break;
default:
break;
}
exportSession.outputFileType = fileType;
NSString *exportPath = [[NSTemporaryDirectory() stringByAppendingPathComponent:[EXPORT_NAME stringByAppendingPathExtension:ex]] retain];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
exportSession.outputURL = [NSURL fileURLWithPath:exportPath];
[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSLog(#"export session completed");
//return YES;
[self performSelectorOnMainThread:#selector(gotoMainView:)
withObject:[EXPORT_NAME stringByAppendingPathExtension:ex]
waitUntilDone:NO];
} else {
NSLog(#"export session error");
//return NO;
}
[exportSession release];
}];
[pool release];
});
}

How to copy video from iPhone album without compression?

When I tried to copy a video from album to app using UIImagePickerController, the video is compressed.
When the video imported via Photos app on Mac, the ten-second long video is:
1920x1280 ~22MB
After the video is imported into app, then copied via iTunes Sharing, the compressed video is:
1280x720 ~6.3MB
How can I import video into app in original resolution and quality?
Code:
- (void)importVideo:(id)sender {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
imagePickerController.allowsEditing = YES;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if (CFStringCompare((__bridge_retained CFStringRef)mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [paths firstObject];
NSString *filename = [folder stringByAppendingPathComponent:self.uniqueFilename];
BOOL success = [videoData writeToFile:filename atomically:NO];
NSLog(#"Write to file %#", success ? #"OK" : #"Error");
}
}
Once a PHAsset is obtained via GMImagePicker, it can be saved by:
for (PHAsset *asset in assetArray) {
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;
[[PHImageManager defaultManager] requestAVAssetForVideo:asset
options:options
resultHandler:^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
if ([avAsset isKindOfClass:[AVURLAsset class]]) {
NSURL *videoURL = [(AVURLAsset *) avAsset URL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [paths firstObject];
NSString *filename = [folder stringByAppendingPathComponent:#"foo.mp4"];
[videoData writeToFile:filename atomically:NO];
}
}];
}

Capture Video in Mp4 format

I am using UIImagePickerController to record video, the problem is its recording the video in mov format for android compatibility.
I need to convert the video into mp4 format using below code the issue is its taking hell of a time for a 6 sec video it takes around 30 to 35 seconds.
Any solution that I can directly record the video in mp4 format or faster method would be of great help. Thanks in Advance
-(void)movToMp4:(NSURL *)videoURL{ // method for mov to mp4 conversion
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* videoPath = [NSString stringWithFormat:#"%#/xyz.mp4", [paths objectAtIndex:0]];
exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) { // switch case to get completion case where i put my delegate
return;
break;
case AVAssetExportSessionStatusCompleted: {
[self.delegate mp4Response:videoPath];
break;
}
}
}
}];
}
}
Yes because it takes time when you load video from library / album using AVURLAsset.
So you need to use block here to load video from library.
Also line
[self.delegate mp4Response:videoPath];
Which in a completion block - It should be on main thread.
Follow this approach:
UIImagePickerController delegate method to get videos from library.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *localUrl = (NSURL *)[info valueForKey:UIImagePickerControllerMediaURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* videoPath = [NSString stringWithFormat:#"%#/xyz.mp4", [paths objectAtIndex:0]];
NSURL *outputURL = [NSURL fileURLWithPath:videoPath];
[self convertVideoToLowQuailtyWithInputURL:localUrl outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSLog(#"Capture video complete");
[self performSelectorOnMainThread:#selector(doneCompressing) withObject:nil waitUntilDone:YES];
}
}];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (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:AVAssetExportPresetPassthrough];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
handler(exportSession);
}];
}
In didFinishPickingMediaWithInfo method observed this line:
[self performSelectorOnMainThread:#selector(doneCompressing) withObject:nil waitUntilDone:YES];
It will call a one more method doneCompressing in main thread (in foreground). So that you can call delegate method in doneCompressing. And this will reduce time.
- (void) doneCompressing {
[self.delegate mp4Response:videoPath];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"file info = %#", info);
NSString *pickedType = [info objectForKey:#"UIImagePickerControllerMediaType"];
NSData *videoData;
if ([pickedType isEqualToString:#"public.movie"]){
NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
videoData = [NSData dataWithContentsOfURL:videoUrl];
}
[self dismissViewControllerAnimated:YES completion:^{
//
[self writeFileData:videoData];
}];
}
// to get path of document directory
- (NSString *)applicationDocumentsDirectory
{
// return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
- (void) writeFileData:(NSData *)fileData{
float size = fileData.length / (1024 * 1024);
NSString *fileName = nil;
NSString *strPath = nil;
NSString *documentsDirectory = [self applicationDocumentsDirectory];
double CurrentTime = CACurrentMediaTime();
fileName = [NSString stringWithFormat:#"%d.mp4",(int)CurrentTime];
strPath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSFileManager *filemanager=[[NSFileManager alloc] init];
NSError *er;
if (![filemanager fileExistsAtPath:documentsDirectory]) {
[filemanager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:&er];
NSLog(#"error in folder creation = %#", er);
}
NSLog(#"size of data = %lu", (unsigned long)[fileData length]);
BOOL saved = [fileData writeToFile:strPath atomically:YES];
if (saved) {
NSURL *videoURL = [NSURL URLWithString:strPath];
// now u can handle mp4 video from videoURL
}
else
return;
}

How to merge multiple videos and audio using AVAsset

Hi I am trying to merge videos together using AVMutableComposition .
The problem I am having is that the AVAsset tracksWithMediaTypes method returns an empty array and the app crashed.
Can someone point out what I am doing wrong.
Thanks
Here is what I have so far:
-(void) mergeVideosAndAudio:(AVAsset *)audioAsset{
//Load Video Assets
NSError *error;
NSArray *dirFiles;
if ((dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self documentsDirectory] error:&error]) == nil) {
// handle the error
};
// find all the temp files
NSArray *movFiles = [dirFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self BEGINSWITH 'temp'"]];
NSLog(#"The are %i temp files",movFiles.count);
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:[self documentsDirectory] error:nil];
//Create the composition
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
// 1 - Video track
AVMutableCompositionTrack *firstTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime videoTrackDuration;
for (int j = 0; j < filePathsArray.count; j++) {
NSURL *url = [NSURL fileURLWithPath:filePathsArray[j]];
AVURLAsset *currentAsset = [[AVURLAsset alloc]initWithURL:url options:nil];
videoTrackDuration = CMTimeAdd(videoTrackDuration, currentAsset.duration);
CMTime time;
if (j == 0) {
time = kCMTimeZero;
}else{
NSURL *previousAssetURL = [NSURL fileURLWithPath:filePathsArray[j-1]];
AVURLAsset *previousAsset = [[AVURLAsset alloc]initWithURL:previousAssetURL options:nil];
time = previousAsset.duration;
}
[firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, currentAsset.duration) ofTrack:[[currentAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:time error:nil];
}
// 2 - Audio track
if (audioAsset!=nil){
AVMutableCompositionTrack *AudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
[AudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoTrackDuration)
ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
}
//3 - Get Path for merge
NSString *myPathDocs = [[self documentsDirectory] stringByAppendingPathComponent:
[NSString stringWithFormat:#"mergeVideo-%d.mov",arc4random() % 1000]];
self.fileURL = [NSURL URLWithString: myPathDocs];
// 5 - Create exporter
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=self.fileURL;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:exporter];
});
}];
}
-(void)exportDidFinish:(AVAssetExportSession*)session {
if (session.status == AVAssetExportSessionStatusCompleted) {
self.fileURL = session.outputURL;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:self.fileURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:self.fileURL completionBlock:^(NSURL *assetURL, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Video Saving Failed"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Video Saved" message:#"Saved To Photo Album"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
});
}];
}
}
[self removeTempFilesFromDocuments];
}
Here is a screenshot of the error:
Well, the error is right there "index 0 beyond bounds for empty array".
That means that you have empty array of video assets. Thus, there is something wrong with getting your videoassets via NSFileManager. Go check the array filePathsArray, there is something wrong with it.
First Check video is present at particular path and run proper .
In my case,video is present at path ,but not able to run .
This mostly happen because video not write properly at that path.
Hope it helps.
Please check your files duration that should't be zero.
Not sure if this solves your problem. But I've ran into this issue before when I was trying to load an AVAsset from a url but was getting an asset with no tracks. What fixed it for me was adding "isDirectory:NO" when creating the NSURL:
NSURL *url = [NSURL fileURLWithPath:filePathsArray[j] isDirectory:NO];

UIStatusBar become red after using AVAssetExportSession for UIImagePickerController media conversion

I am converting the .MOV video i get from UIImagePickerController to the .mp4 format using AVAssetExportSession. Once the conversion is completed I send the data to a server. Everything works fine, except the status bar become red and pulsing after the transmission is completed. If I put the app in background and open it again, then the status bar returns to its normal status again.
This is what I think is the piece of code that causes this behavior:
//I took a video
__block NSString *messageType;
__block NSData *messageData;
__block NSString *messageText;
[...]
NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
NSString *videoPath = nil;
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
videoPath = [[NSTemporaryDirectory() stringByAppendingPathComponent:videoDirectory]stringByAppendingPathComponent:tempVideoFileName];
exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
NSLog(#"videopath of your mp4 file = %#",videoPath); // PATH OF YOUR .mp4 FILE
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) {
case AVAssetExportSessionStatusFailed:{
NSLog(#"Export failed: %#", [[exportSession error] localizedDescription]);
[picker dismissViewControllerAnimated:YES completion:^{
[SVProgressHUD showErrorWithStatus:[[exportSession error] localizedDescription]];
}];
}
break;
case AVAssetExportSessionStatusCancelled:
NSLog(#"Export canceled");
break;
case AVAssetExportSessionStatusCompleted:{
messageData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoPath]];
messageText = videoPath;
messageType = kMessageTypeVideo;
// This method sends asynchronously the data to the server
[self sendMediaType:messageType MessageData:messageData MessageText:messageText];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
break;
default:
break;
}
}];
}
Is there a way to avoid the appearance of the red status bar or at least the way I should use to make it disappear?
It turns out that in some way the recording session of the UIImagePickerController went in conflict with the AVAssetExportSession.
I resolved this issue by converting the video after having dismissed the UIImagePicker controller:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeImage, 0)
== kCFCompareEqualTo) {
[....]
}
else{
//Took a video
NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL];
[picker dismissViewControllerAnimated:YES completion:^{
[self convertAndSendVideo:url];
}];
}
}
-(void)convertAndSendVideo:(NSURL *)url{
__block NSString *messageType;
__block NSData *messageData;
__block NSString *messageText;
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
NSString *videoPath = nil;
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
__block AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
videoPath = [[NSTemporaryDirectory() stringByAppendingPathComponent:videoDirectory]stringByAppendingPathComponent:tempVideoFileName];
exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
NSLog(#"videopath of your mp4 file = %#",videoPath); // PATH OF YOUR .mp4 FILE
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) {
case AVAssetExportSessionStatusFailed:{
NSLog(#"Export failed: %#", [[exportSession error] localizedDescription]);
[SVProgressHUD showErrorWithStatus:[[exportSession error] localizedDescription]];
}
break;
case AVAssetExportSessionStatusCancelled:
NSLog(#"Export canceled");
break;
case AVAssetExportSessionStatusCompleted:{
messageData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoPath]];
messageText = videoPath;
messageType = kMessageTypeVideo;
[self sendMediaType:messageType MessageData:messageData MessageText:messageText];
}
break;
default:
break;
}
}];
}
}

Resources