Как объединить аудио и видео в iOS

Мне нравится объединять аудио и видео в приложении с помощью AVMutableComposition, а также я использовал следующий код в приложении, но я могу получить выходные данные.

-(void) playerFunction
{
    NSString  *fileNamePath = @"mexicanDance.mp3";//myaudio
    NSArray   *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString  *documentsDirectory = [paths  objectAtIndex:0];
    NSString  *oldappSettingsPath = [documentsDirectory stringByAppendingPathComponent:fileNamePath];
    NSURL *audioUrl = [NSURL fileURLWithPath:oldappSettingsPath];
    NSString  *fileNamePath1 = @"Egg_break.mov";//my video
    NSArray   *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString  *documentsDirectory1 = [paths1  objectAtIndex:0];
    NSString  *oldappSettingsPath1 = [documentsDirectory1 stringByAppendingPathComponent:fileNamePath1];
    NSLog(@"oldpath=%@",oldappSettingsPath);
    NSURL *videoUrl = [NSURL fileURLWithPath:oldappSettingsPath1];
//    if (avPlayer.duration >0.00000)
//    {
        NSLog(@"SOMEDATA     IS THERE ");
        AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
        AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];

        AVMutableComposition* mixComposition = [AVMutableComposition composition];

        NSLog(@"audio =%@",[audioAsset tracksWithMediaType:AVMediaTypeAudio]);
    NSLog(@"Video =%@",[videoAsset tracksWithMediaType:AVMediaTypeVideo]);

        AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    NSLog(@"%@",compositionCommentaryTrack);
        [compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];

        AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
        [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];


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

        NSString* videoName = @"output.mp4";//outputdata

        NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];
        NSURL    *exportUrl = [NSURL fileURLWithPath:exportPath];

        if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
        {
            [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
        }

        _assetExport.outputFileType = @"com.apple.quicktime-movie";
        NSLog(@"file type %@",_assetExport.outputFileType);
        _assetExport.outputURL = exportUrl;
        _assetExport.shouldOptimizeForNetworkUse = YES;



        [_assetExport exportAsynchronouslyWithCompletionHandler:
         ^(void )
         {

             NSString  *fileNamePath = @"sound_record.mov";
             NSArray   *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
             NSString  *documentsDirectory = [paths  objectAtIndex:0];
             NSString  *oldappSettingsPath = [documentsDirectory stringByAppendingPathComponent:fileNamePath];


             //             if ([[NSFileManager defaultManager] fileExistsAtPath:oldappSettingsPath]) {
             //
             //                 NSFileManager *fileManager = [NSFileManager defaultManager];
             //                 [fileManager removeItemAtPath: oldappSettingsPath error:NULL];
             //
             //             }
             NSURL *documentDirectoryURL = [NSURL fileURLWithPath:oldappSettingsPath];
             [[NSFileManager defaultManager] copyItemAtURL:exportUrl toURL:documentDirectoryURL error:nil];
             [audioAsset release];
             [videoAsset release];
             [_assetExport release];
         }       
         ];

//}
    video = [[MPMoviePlayerController alloc] init];
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        video.view.frame = CGRectMake(0, 0, 768, 1004);
    else
        video.view.frame = CGRectMake(0, 0, 320, 460);

    NSString * audioPath=[[NSBundle mainBundle] pathForResource:@"output" ofType:@"mp4"];
    [video setContentURL:[NSURL fileURLWithPath:audioPath]];

    [video prepareToPlay];
    [video play];
    [self.view addSubview:video.view];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopAudio)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification object:video];

    [video setFullscreen:YES];
}

Но этот код у меня не работает, потому что оба AVURLAsset выдают мне пустой набор. Я не знаю, что это за ошибка. Может ли кто-нибудь помочь решить эту проблему

Заранее спасибо


person btmanikandan    schedule 01.03.2013    source источник
comment
Может попробовать [AVURLAsset URLAssetWithURL: ... ]? Пути к файлам печатаются правильно?   -  person anon_dev1234    schedule 01.03.2013
comment
Спасибо за ваш ответ, сэр. Как я могу добавить вывод в каталог документов, сэр?   -  person btmanikandan    schedule 01.03.2013
comment
Похоже, вы установили выходной URL-адрес AVAssetExporter во временный каталог, тогда как вы можете просто установить его непосредственно в каталог документов! Не нужно записывать его во временный каталог, а затем пытаться скопировать в каталог docs.   -  person anon_dev1234    schedule 01.03.2013
comment
Если я попытаюсь воспроизвести output.mp4, произойдет сбой, сэр.   -  person btmanikandan    schedule 01.03.2013
comment
Если outputURL из AVAssetExportSession установлено на output.mp4, убедитесь, что в файле действительно есть данные. Также убедитесь, что вы удалили любой файл по этому пути, прежде чем пытаться записать в него, так как AVAssetExportSession не перезапишется.   -  person anon_dev1234    schedule 01.03.2013
comment
Привет, сэр, теперь код работает для локальных файлов, и он не работает для видео и аудио, которые загружают для сервера любую идею по этому поводу.   -  person btmanikandan    schedule 06.03.2013


Ответы (2)


убедитесь, что ваш файл (аудио и видео) имеет правильное расширение, и его продолжительность не должна быть пустой, мы можем проверить это перед использованием, как это

if ([[_videoAsset tracksWithMediaType:AVMediaTypeVideo]count]!=0)
{
 // write code here to add video in composition. you can check same for audio too.
}
person user3306145    schedule 21.01.2016

@btmanikandan для загрузки файлов с сервера сохраните данные файла (NSdata) в temp. каталог документов с сервера, а затем объединиться оттуда. после слияния удалить файл из каталога документов. Надеюсь, что это поможет вам!!!

person user3306145    schedule 21.01.2016