Cocoa: AVAsset, загруженный из файла, имеет 0 дорожек
Я пытаюсь объединить некоторые аудиофайлы, используя технику, показанную здесь. Мои аудиофайлы -.m4a, и я могу проверить, что они отлично работают в Quicktime. Вот код, который я пытаюсь использовать для их конкатенации:
[currFile.audioContent writeToFile:tempOldFilePath atomically:NO];
AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempOldFilePath] options:nil];
AVURLAsset *newAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempInputFilePath] options:nil];
NSLog(@"oldAsset num tracks = %lu",(unsigned long)oldAudioAsset.tracks.count);
NSLog(@"newAsset num tracks = %lu",(unsigned long)newAudioAsset.tracks.count);
AVAssetTrack *oldTrack = [[oldAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVAssetTrack *newTrack = [[newAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVMutableComposition *mutableComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error=nil;
[compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, oldTrack.timeRange.duration) ofTrack:oldTrack atTime:kCMTimeZero error:&error];
if (error) {
NSLog(@"%@",error.localizedDescription);
error=nil;
}
[compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, newTrack.timeRange.duration) ofTrack:newTrack
atTime:oldTrack.timeRange.duration error:&error];
if (error) {
NSLog(@"%@",error.localizedDescription);
error=nil;
}
exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetAppleM4A];
exporter.outputURL = [NSURL URLWithString:tempCompFilePath];
exporter.outputFileType = AVFileTypeAppleM4A;
[exporter exportAsynchronouslyWithCompletionHandler:^{
NSLog(@"handller");
NSError *error=nil;
NSData *newData = [NSData dataWithContentsOfFile:tempCompFilePath options:0 error:&error];
NSLog(@"%lu",(unsigned long)newData.length);
if (error) {
NSLog(@"%@",error.localizedDescription);
}
currFile.audioContent = newData;
[[AppDelegate sharedDelegate] saveAction:nil];
}];
Первая проблема, которую я заметил, заключается в том, что метод обработчика-экспортера никогда не вызывается. Я предполагаю, что причина в том, что это другая проблема, которую я заметил: после создания моих AVAssets из URL-адресов, операторы журналов показывают, что они содержат 0 треков. Пример Apple точно не показывает, как загружаются AVAssets.
Любые советы о том, как это сделать?
Ответы
Ответ 1
Как вы уже нашли, для создания своих URL-адресов вам нужно использовать fileURLWithPath:
, а не URLWithString:
.
URLWithString:
ожидает строку, которая описывает URL-адрес, например @"file:///path/to/file"
или @"http://example.com/"
. Когда ваша строка описывает один путь, например @"/path/to/file"
, вы должны использовать fileURLWithPath:
, который правильно заполнит недостающие части.
Более технически, URLWithString:
интерпретирует путь как просто URL-адрес с единственным путем, но не с конкретной схемой, которую вы могли бы использовать относительно базового URL-адреса в любой файловой схеме, такой как HTTP (GET /path/to/file
). fileURLWithPath:
интерпретирует путь как локальный путь к файлу и возвращает соответственно URL file:
.
Ответ 2
Я нашел причину, по которой эта ошибка произошла и в конечном итоге решила ее.
Первоначально я установил путь к исходному файлу как ".mp4".
Но тип записанного видеофайла был MOV, поэтому я изменился как ".mov".
NSString *source_file_path = @"temp_video.mov"
вместо
NSString *source_file_path = @"temp_video.mp4"
Проблема была исправлена, и теперь она работает хорошо.
Надеюсь, что это будет полезно для всех.
Ответ 3
По-видимому, я использовал неправильный метод NSURL. Я изменил его на следующее:
AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:tempOldFilePath] options:nil];
Теперь мои AVAssets имеют по 1 трек. Если кто-то может дать хорошее объяснение, почему это необходимо, я буду принимать этот ответ.