Главная > iOS > Наложение звука на видео и сохранение результата в camera roll iPhone/iPad

Наложение звука на видео и сохранение результата в camera roll iPhone/iPad

В этой статье будет рассмотрен способ наложения звукового файла на видео. Данная реализация основана на использовании фреймворка AV Foundation, который входит в стандартный состав iOS (начиная с версии 2.2). Полученный результат нужно сделать доступным для просмотра с телефона, для этого мы сохраним его в camera roll на iPhone или iPad.

Подразумевается, что файлы лежат в определенном месте на устройстве (предполагается, что во временной папке нашей программы). Возможные ситуации возникновения ошибок не обрабатываются, но они заносятся в объект класса NSError. Таким образом, данный код представляет из себя набор сниппетов для использования в своем коде.

Реализация

Создадим функцию, в которая будет вызываться для смешивания звука с видео и записи результата в camera roll. В качестве аргументов она принимает пути к файлам с видео и аудио данными в строковом формате NSString.

- (void) mixAudioVideo: (NSString *) strAudioFile: (NSString *) strVideoFile
{
    NSError *err = nil;
}

Создадим дополнительно строковую переменную, в которой будет храниться путь к файлу с нашим результатом. Он будет располагаться как и другие файлы во временной папке нашего приложения под именем mix.m4v.

NSString* strMixFile = [[NSTemporaryDirectory()
    stringByAppendingPathComponent:@"mix.m4v"] retain];

Теперь исходные файлы нам нужно представить в виде хранилища, которые затем будем смешивать.

AVURLAsset* mixAudioAsset = [[AVURLAsset alloc]
    initWithURL:[NSURL fileURLWithPath:strAudioFile] options:nil];
AVURLAsset* mixVideoAsset = [[AVURLAsset alloc]
    initWithURL:[NSURL fileURLWithPath:strVideoFile] options:nil];

Создаем пустую композицию, в которой будем использовать наши хранилища.

AVMutableComposition* mixComposition = [AVMutableComposition composition];

Полученная композиция должна состоять из одного или более треков, которые мы ниже и создаем, указывая шкалу времени, на которой они будут располагаться, тип трека и т.д..

AVMutableCompositionTrack *compositionAudioTrack = [mixComposition
    addMutableTrackWithMediaType:AVMediaTypeAudio
    preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack
        insertTimeRange:CMTimeRangeMake(kCMTimeZero, mixAudioAsset.duration)
        ofTrack:[[mixAudioAsset tracksWithMediaType:AVMediaTypeAudio]
            objectAtIndex:0]
        atTime:kCMTimeZero
        error:&err];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition
    addMutableTrackWithMediaType:AVMediaTypeVideo
    preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionVideoTrack
        insertTimeRange:CMTimeRangeMake(kCMTimeZero, mixVideoAsset.duration)
        ofTrack:[[mixVideoAsset tracksWithMediaType:AVMediaTypeVideo]
            objectAtIndex:0]
        atTime:kCMTimeZero
        error:&err];

Создаем сессию для экспорта.

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

Задаем для нее такие параметры, как тип файла, путь к нему и оптимизировать ли для использования в сети.

assetExport.outputFileType = @"com.apple.quicktime-movie";
assetExport.outputURL = [NSURL fileURLWithPath:movieWrite];
assetExport.shouldOptimizeForNetworkUse = YES;

И, наконец, запускаем нашу сессию смешивания в асинхронном режиме. Также в отмеченном месте можно вставить любой код, который будет выполняться при смешивании очередного семпла.

[_assetExport exportAsynchronouslyWithCompletionHandler:
    ^(void)
    {
        //Здесь промежуточный код для обработки семплов
    }
];

Осталось только сохранить полученный результат в camera roll. Реализуется это следующей строчкой:

UISaveVideoAtPathToSavedPhotosAlbum (path, self,
    @selector(video:didFinishSavingWithError: contextInfo:), nil);

В последней строке мы указали вызов функции, которая будет запускаться при возникновении ошибки во время сохранения в camera roll. Поэтому, нужно создать эту функцию, в которой будут обрабатываться ошибки. Для примера ниже представлена пустая функция:

- (void) video: (NSString *) videoPath
didFinishSavingWithError: (NSError *) err
contextInfo: (void *) contextInfo
{
    //Здесь код для обработки ошибки
}
Categories: iOS Tags: , , ,
  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.