dimanche 25 janvier 2015

Merging Audio With Video on iOS 7/8

I am making an application which is supposed to merge audio (.caf) and video (mp4 --> mov) files. On my iPhone, the video and audio usually merge fine, and only sometimes cutting out the video. On my iPad, it never puts the video along with the audio. It is technically still an MOV file at the end, but there is just a quicktime logo when I try to play the file. Here is my code:



NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

NSString *videoURL = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@.mp4", _nameField.text]];
NSURL *videoFileURL = [NSURL fileURLWithPath:videoURL];
NSString *audioURL = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@.caf", _nameField.text]];
NSURL *audioFileURL = [NSURL fileURLWithPath:audioURL];



AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioFileURL options:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoFileURL options:nil];




AVAssetTrack *assetVideoTrack = nil;
AVAssetTrack *assetAudioTrack = nil;





if ([[NSFileManager defaultManager] fileExistsAtPath:videoURL]) {
NSArray *assetArray = [videoAsset tracksWithMediaType:AVMediaTypeVideo];
if ([assetArray count] > 0)
assetVideoTrack = assetArray[0];
}

if ([[NSFileManager defaultManager] fileExistsAtPath:audioURL] && [prefs boolForKey:@"switch_audio"]) {
NSArray *assetArray = [audioAsset tracksWithMediaType:AVMediaTypeAudio];
if ([assetArray count] > 0)
assetAudioTrack = assetArray[0];
}

//double degrees = 0.0;
//if ([prefs objectForKey:@"video_orientation"])
// degrees = [[prefs objectForKey:@"video_orientation"] doubleValue];


AVMutableComposition *mixComposition = [AVMutableComposition composition];

if (assetVideoTrack != nil) {
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:assetVideoTrack atTime:kCMTimeZero error:nil];
if (assetAudioTrack != nil) [compositionVideoTrack scaleTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) toDuration:audioAsset.duration];
//[compositionVideoTrack setPreferredTransform:CGAffineTransformMakeRotation(degreesToRadians(degrees))];
}

if (assetAudioTrack != nil) {
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:assetAudioTrack atTime:kCMTimeZero error:nil];
}

AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetPassthrough];


NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@.mov", _nameField.text]];
NSURL *savetUrl = [NSURL fileURLWithPath:savePath];

_assetExport.outputFileType = AVFileTypeQuickTimeMovie;
_assetExport.outputURL = savetUrl;
_assetExport.shouldOptimizeForNetworkUse = NO;


//[_startStopButton setTitle:@"Merging... Please Wait..." forState:UIControlStateNormal];
//_startStopButton.userInteractionEnabled = NO;



[_assetExport exportAsynchronouslyWithCompletionHandler:^(void){

switch(_assetExport.status)
{
case AVAssetExportSessionStatusCompleted:
{

//statusText.text = @"Export Completed";
//[_startStopButton setTitle:@"Start Recording" forState:UIControlStateNormal];
_nameField.userInteractionEnabled = YES;
//_startStopButton.userInteractionEnabled = YES;

NSString *videoToDelete = _nameField.text;
NSString *audioToDeletePath = [[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
stringByAppendingPathComponent:videoToDelete]
stringByAppendingPathExtension:@"caf"];
NSString *videoToDeleteTwo = [NSString stringWithFormat:@"%@", _nameField.text];
NSString *videoToDeletePath = [[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
stringByAppendingPathComponent:videoToDeleteTwo]
stringByAppendingPathExtension:@"mp4"];
[[[NSFileManager alloc]init]removeItemAtPath:audioToDeletePath error:NULL];
[[[NSFileManager alloc]init]removeItemAtPath:videoToDeletePath error:NULL];

}
break;

case AVAssetExportSessionStatusWaiting:
{
//statusText.text = @"Waiting...";
//[_startStopButton setTitle:@"Waiting..." forState:UIControlStateNormal];
}
break;
case AVAssetExportSessionStatusExporting:
{
//statusText.text = @"Exporting...";
//[_startStopButton setTitle:@"Exporting..." forState:UIControlStateNormal];
}
break;

case AVAssetExportSessionStatusFailed:
{
//statusText.text = @"FAILED. Trying again...";
//[_startStopButton setTitle:@"FAILED. Trying again..." forState:UIControlStateNormal];
[self mergeAudio];

}
break;
case AVAssetExportSessionStatusCancelled:
{

}
break;
case AVAssetExportSessionStatusUnknown:
{

}
break;
}

]; }


The files start off as caf and mp4 files. It then takes them, merges them, deletes them, and exports the final file as a single MOV. I just cannot figure out why it sometimes cuts out the audio from the final file.




Aucun commentaire:

Enregistrer un commentaire