Cocoa:从文件加载的AVAsset有0个轨道

Jam*_*rpe 10 audio macos cocoa objective-c avfoundation

我正在尝试使用此处显示的技术连接一些音频文件.我的音频文件是.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];

    }];
Run Code Online (Sandbox Code Playgroud)

我注意到的第一个问题是从不调用导出器的处理程序方法.我猜这是我注意到的另一个问题的原因:从URL创建我的AVAssets后,日志语句显示它们包含0个轨道.Apple的示例并未准确显示AVAsset的加载方式.

有关如何使这项工作的任何建议?

Pet*_*sey 19

正如您已经发现的那样,您需要使用fileURLWithPath:而不是URLWithString:创建URL.

URLWithString:需要一个描述URL的字符串,例如@"file:///path/to/file"@"http://example.com/".当你的字符串单独描述一个路径时,@"/path/to/file"你必须使用fileURLWithPath:,这将正确地填充缺失的部分.

从技术上讲,URLWithString:将路径解释为仅具有路径但没有特定方案的URL ,您可以继续在任何面向文件的方案(例如HTTP(GET /path/to/file))中使用相对于基本URL 的路径.fileURLWithPath:将路径解释为本地文件路径,并相应地返回file:URL.


小智 5

我找到了这个错误发生的原因并最终解决了.

最初我将源文件路径设置为" .mp4".但录制的视频文件的类型是MOV所以我改为" .mov".

NSString *source_file_path = @"temp_video.mov"
Run Code Online (Sandbox Code Playgroud)

代替

NSString *source_file_path = @"temp_video.mp4"
Run Code Online (Sandbox Code Playgroud)

问题得到解决,现在运作良好.

希望对所有人都有所帮助.