MP4 Conversion
Sometimes
we need to develop applications both for android and iOS that uses
the videos captured from the devices.By default iOS saves the video
in .mov format which can not be played on the android devices.To make
the iOS videos compatible for all devices(android and iOS) we use a
common video format and that is .mp4. Now we can achieve this by
using AVFoundation
framework.
This blog will provide the steps to convert video in mp4 format.
//
Create the asset url with the video file
AVURLAsset
*avAsset = [AVURLAsset
URLAssetWithURL:videoURL
options:nil];
NSArray
*compatiblePresets = [AVAssetExportSession
exportPresetsCompatibleWithAsset:avAsset];
//
Check if video is supported for conversion or not
if
([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
//Create
Export session
AVAssetExportSession
*exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset
presetName:AVAssetExportPresetLowQuality];
//Creating
temp path to save the converted video
NSString*
documentsDirectory= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES)
objectAtIndex:0];
NSString*
myDocumentPath= [documentsDirectory
stringByAppendingPathComponent:@"temp.mp4"];
NSURL
*url = [[NSURL
alloc]
initFileURLWithPath:myDocumentPath];
//Check
if the file already exists then remove the previous file
if
([[NSFileManager
defaultManager]fileExistsAtPath:myDocumentPath])
{
[[NSFileManager
defaultManager]removeItemAtPath:myDocumentPath
error:nil];
}
exportSession.outputURL
= url;
//set
the output file format if you want to make it in other file format
(ex .3gp)
exportSession.outputFileType
= AVFileTypeMPEG4;
exportSession.shouldOptimizeForNetworkUse
= YES;
[exportSession
exportAsynchronouslyWithCompletionHandler:^{
switch
([exportSession status])
{
case
AVAssetExportSessionStatusFailed:
NSLog(@"Export
session failed");
break;
case
AVAssetExportSessionStatusCancelled:
NSLog(@"Export
canceled");
break;
case
AVAssetExportSessionStatusCompleted:
{
//Video
conversion finished
NSLog(@"Successful!");
}
break;
default:
break;
}
}];
}
else
{
NSLog(@"Video
file not supported!");
}
Videos Merging(Adding two videos)
While
developing iOS applications some times we required a functionality
where we have to merge small video clips in one large video file. Now
this we can achieve through iOS AVFoundation
framework.
//Create
the AVMutable composition to add tracks
AVMutableComposition*
composition = [[AVMutableComposition
alloc]init];
//Create
assets url for first video
AVURLAsset*
video1 = [[AVURLAsset
alloc]initWithURL:[NSURL
fileURLWithPath:path1]options:nil];
//Create
assets url for second video
AVURLAsset*
video2 = [[AVURLAsset
alloc]initWithURL:[NSURL
fileURLWithPath:path2]options:nil];
//Create
the mutable composition track with video media type. You can also
create the tracks depending on your need if you want to merge audio
files and other stuffs.
AVMutableCompositionTrack*
composedTrack = [composition
addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
//Set
the video time ranges of both the videos in composition
[composedTrack
insertTimeRange:CMTimeRangeMake(kCMTimeZero,
video1.duration)
ofTrack:[[video1
tracksWithMediaType:AVMediaTypeVideo]
objectAtIndex:0]
atTime:kCMTimeZero
error:nil];
[composedTrack
insertTimeRange:CMTimeRangeMake(kCMTimeZero,
video2.duration)
ofTrack:[[video2
tracksWithMediaType:AVMediaTypeVideo]
objectAtIndex:0]
atTime:video1.duration
error:nil];
//
Create a temp path to save the video in the documents dir.
NSString*
documentsDirectory=
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES)
objectAtIndex:0];
NSString*
myDocumentPath= [documentsDirectory
stringByAppendingPathComponent:@"merge_video.mp4"];
NSURL
*url = [[NSURL
alloc]
initFileURLWithPath:
myDocumentPath];
//Check
if the file exists then delete the old file to save the merged video
file.
if([[NSFileManager
defaultManager]fileExistsAtPath:myDocumentPath])
{
[[NSFileManager
defaultManager]removeItemAtPath:myDocumentPath
error:nil];
}
//
Create the export session to merge and save the video
AVAssetExportSession*exporter
= [[AVAssetExportSession
alloc]initWithAsset:composition
presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=url;
exporter.outputFileType=@"com.apple.quicktime-movie";
exporter.shouldOptimizeForNetworkUse=YES;
[exporter
exportAsynchronouslyWithCompletionHandler:^{
switch([exporter
status])
{
case
AVAssetExportSessionStatusFailed:
NSLog(@"Failed
to export video");
break;
case
AVAssetExportSessionStatusCancelled:
NSLog(@"export
cancelled");
break;
case
AVAssetExportSessionStatusCompleted:
//Here
you go you have got the merged video :)
NSLog(@"Merging
completed");
break;
default:
break;
}
}];
For Mixing audio and video
//From above code to mix
a audio with video simply create a mutable composition of audio track
and insert it in the video time range.
NSArray
*pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES)
lastObject],@"MyAudio.m4a",nil];
NSURL
*outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
AVAsset
*audioAsset = [AVAsset assetWithURL:outputFileURL];
//Create mutable composition of audio type
AVMutableCompositionTrack
*audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[audioTrack
insertTimeRange:CMTimeRangeMake(kCMTimeZero,firstAsset.duration)
ofTrack:[[audioAsset
tracksWithMediaType:AVMediaTypeAudio]
objectAtIndex:0]
atTime:kCMTimeZero
error:nil];
Here is sample project with all of the code from the above tutorial.
it works but remaining video getting mute.
ReplyDeleteIt will not make the video mute.Check your integration again and if you face any problem, share you code. I will be happy to help you.
Deletebecause of no audio in my videos i am getting error for --> index 0 beyond bounds for empty NSArray' Please provide solution
ReplyDeleteIf you are mixing the audio and video then you should apply the check that file should exist in the path then only the code should execute.
DeleteIf there is no file then it will crash, so make sure file exists.
Please provide more details as what you are doing so that I can better help you.
Hello
ReplyDeleteIt is not working giving me an error index 0 beyond bounds for empty NSArray'.. Because my videos dont have audio.. Please provide solution
This comment has been removed by the author.
DeletePlease check for the array count before you access any index of array... Please make habit of checking count of array if it is greater then 0 then only proceed... put condition like that before execution.
DeleteI am aiyub
ReplyDeleteabove is my code to merge two videos i've checked both videos are ready and complete at directory. Buyt the problem is both dont contain audio
Hi Aiyub,
DeleteWhat I have understand from your issue is that you are merging two videos that does not contain the audio and you are getting the crash.
It should not crash until video have some issue. Could you replace your videos in my sample project and check that you are getting the same crash or not.
I have checked with some video without audio and it's working fine.
Please check and let me know if you still face the issue.
Also, try with some different videos and if possible share the videos so that I can check and better help you.
Thanks,
Pradeep
OK I don't know why but I tried it with different paths and yepp.. It's working Now!!!!!
ReplyDeleteGreat!!
DeletePradeep .. Can you please help me into this???
ReplyDeletehttp://stackoverflow.com/questions/37762393/save-video-with-dezired-playback-speed-in-ios
I don't think it is possible but I will check more and will let you know if I will found any solution.
DeleteHi ,
ReplyDeleteThis is Sharukh, an iOS developer from India. This code is not working with iOS 10. Can anybody let me know how we can merge videos in iOS 10.
Any help will be highly appreciated.
Hi ,
ReplyDeleteThis is Sharukh, an iOS developer from India. This code is not working with iOS 10. Can anybody let me know how we can merge videos in iOS 10.
Any help will be highly appreciated.
Could you please let me know what exact issue you are getting while merging ?
DeleteHi Sharooque,
DeleteThis code is also working with iOS 11... I have checked this code...
Hi Pradeep,
ReplyDeleteWhen I am checking the instance of AVASSetExportSession, it is null. Lets' see following code :
AVAssetExportSession*exporter = [[AVAssetExportSession alloc]initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=url;
exporter.outputFileType=@"com.apple.quicktime-movie";
exporter.shouldOptimizeForNetworkUse=YES;
NSLog(@"exporter == %@",exporter);
The ouptput is : exporter == null
Kindly suggest what might be problem here.
ReplyDelete// 2.3 - Create an AVMutableVideoCompositionLayerInstruction for the second track
ReplyDeleteAVMutableVideoCompositionLayerInstruction *secondlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:secondTrack];
AVAssetTrack *secondAssetTrack = [[secondAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
UIImageOrientation secondAssetOrientation_ = UIImageOrientationUp;
BOOL isSecondAssetPortrait_ = NO;
CGAffineTransform secondTransform = secondAssetTrack.preferredTransform;
if (secondTransform.a == 0 && secondTransform.b == 1.0 && secondTransform.c == -1.0 && secondTransform.d == 0) {
secondAssetOrientation_= UIImageOrientationRight;
isSecondAssetPortrait_ = YES;
}
if (secondTransform.a == 0 && secondTransform.b == -1.0 && secondTransform.c == 1.0 && secondTransform.d == 0) {
secondAssetOrientation_ = UIImageOrientationLeft;
isSecondAssetPortrait_ = YES;
}
if (secondTransform.a == 1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == 1.0) {
secondAssetOrientation_ = UIImageOrientationUp;
}
if (secondTransform.a == -1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == -1.0) {
secondAssetOrientation_ = UIImageOrientationDown;
}
[secondlayerInstruction setTransform:secondAsset.preferredTransform atTime:firstAsset.duration];
// 2.4 - Add instructions
ReplyDeletemainInstruction.layerInstructions = [NSArray arrayWithObjects:firstlayerInstruction, secondlayerInstruction,nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);
CGSize naturalSizeFirst, naturalSizeSecond;
if(isFirstAssetPortrait_){
naturalSizeFirst = CGSizeMake(firstAssetTrack.naturalSize.height, firstAssetTrack.naturalSize.width);
} else {
naturalSizeFirst = firstAssetTrack.naturalSize;
}
if(isSecondAssetPortrait_){
naturalSizeSecond = CGSizeMake(secondAssetTrack.naturalSize.height, secondAssetTrack.naturalSize.width);
} else {
naturalSizeSecond = secondAssetTrack.naturalSize;
}
float renderWidth, renderHeight;
if(naturalSizeFirst.width > naturalSizeSecond.width) {
renderWidth = naturalSizeFirst.width;
} else {
renderWidth = naturalSizeSecond.width;
}
if(naturalSizeFirst.height > naturalSizeSecond.height) {
renderHeight = naturalSizeFirst.height;
} else {
renderHeight = naturalSizeSecond.height;
}
mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight);
// 4 - Get path
ReplyDeleteNSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *video_title = [NSString stringWithFormat:@"%@%@",titleLbl.text,@".mov"];
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:
video_title];
// NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:
//[NSString stringWithFormat:@"mergeVideo-%d.mov",arc4random() % 1000]];
if([[NSFileManager defaultManager] fileExistsAtPath:myPathDocs]){
NSError *error;
[[NSFileManager defaultManager] removeItemAtPath:myPathDocs error:&error];
if (error){
NSLog(@"%@", error);
}
else{
NSLog(@"file deleted olddddd");
}
}
else{
NSLog(@"File doesn't exist ......");
}
NSURL *url = [NSURL fileURLWithPath:myPathDocs];
ReplyDelete// 5 - Create exporter
NSLog(@"mixComposition == %@",mixComposition);
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=url;
NSLog(@"url == %@",url);
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.videoComposition = mainCompositionInst;
NSLog(@"mainCompositionInst == %@",mainCompositionInst);
NSLog(@"exporter === %@",exporter);
[exporter exportAsynchronouslyWithCompletionHandler:^{
NSLog(@"Did it execute ?");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Export Now ....");
[self exportDidFinish:exporter];
});
}];
I've posted my complete code for your convenience.
ReplyDeleteHave you check the attached sample project with your videos? It seems somewhere your mixComposition (asset) is not created correct.
DeleteHi Pradeep,
ReplyDeleteI've tried sample code with my videos. It's not working. When I am saving videos in resource folder within the application, it's working fine. But when I am fetching videos from library, it's not working at all.
Pradeep, I am using ASAsset for creating the URLs of the videos. Is there any problem with that ? Sample code is here :
ReplyDeletefor(ALAsset *mediaALasset in self.selectedVideosArray){
NSURL *URL = [[mediaALasset defaultRepresentation] url];
[allURLArray addObject:URL];
}
You have to copy the video to document or temp directory and then you have to use the file path.
DeleteAny one can suggest me that how can i get the audio file from recorded video file ?
ReplyDeleteIf you have download song then mp3 option is right if you want to Look Ace Baker download video then you will have to download it in mp4 format.
ReplyDeleteelazığ
ReplyDeleteerzincan
bayburt
tunceli
sakarya
0PM
whatsapp görüntülü show
ReplyDeleteücretli.show
FV812
görüntülü.show
ReplyDeletewhatsapp ücretli show
NNJXN
ankara parça eşya taşıma
ReplyDeletetakipçi satın al
antalya rent a car
antalya rent a car
ankara parça eşya taşıma
853
4DE74
ReplyDeleteKırklareli Evden Eve Nakliyat
Kırklareli Lojistik
Amasya Lojistik
Bursa Evden Eve Nakliyat
Bitlis Lojistik
447DA
ReplyDeleteKayseri Şehirler Arası Nakliyat
Tokat Lojistik
İstanbul Lojistik
Ünye Çatı Ustası
Amasya Evden Eve Nakliyat
Pursaklar Boya Ustası
Maraş Şehir İçi Nakliyat
Bartın Şehirler Arası Nakliyat
Kars Şehir İçi Nakliyat
B3C0B
ReplyDeleteMaraş Şehir İçi Nakliyat
Maraş Parça Eşya Taşıma
Muş Evden Eve Nakliyat
Çerkezköy Oto Elektrik
Tekirdağ Cam Balkon
Kırşehir Parça Eşya Taşıma
Bolu Lojistik
Hakkari Evden Eve Nakliyat
Kırşehir Şehir İçi Nakliyat
9C4A8
ReplyDeletebinance %20 komisyon indirimi
DF743
ReplyDeleteMexc Borsası Güvenilir mi
Gate io Borsası Güvenilir mi
Mexc Borsası Kimin
Coin Madenciliği Nasıl Yapılır
Gate io Borsası Güvenilir mi
Coin Nedir
Kripto Para Madenciliği Siteleri
Binance Para Kazanma
Ön Satış Coin Nasıl Alınır
F8D36
ReplyDeleteAdana Sohbet Odaları
Ağrı Ücretsiz Sohbet Odaları
sesli sohbet odası
karabük rastgele görüntülü sohbet ücretsiz
burdur yabancı görüntülü sohbet
adana rastgele sohbet odaları
balıkesir telefonda kadınlarla sohbet
ücretsiz sohbet uygulamaları
sohbet uygulamaları
9AABF
ReplyDeletegümüşhane ücretsiz sohbet uygulaması
Çankırı En İyi Görüntülü Sohbet Uygulaması
antalya bedava görüntülü sohbet sitesi
artvin parasız sohbet
Karaman Telefonda Görüntülü Sohbet
nevşehir görüntülü sohbet ücretsiz
Bursa Mobil Sohbet
gümüşhane ücretsiz sohbet uygulamaları
aksaray canli sohbet chat
300E2
ReplyDeleteNWC Coin Hangi Borsada
Bitcoin Nasıl Oynanır
Paribu Borsası Güvenilir mi
Facebook Grup Üyesi Hilesi
Coin Nasıl Kazılır
Kwai Beğeni Hilesi
Yeni Çıkan Coin Nasıl Alınır
Coin Nasıl Üretilir
Binance Yaş Sınırı
شركة تنظيف سجاد بالجبيل YegkuX94AD
ReplyDeleteشركة تنظيف شقق بالجبيل dzNduPWMcA
ReplyDelete