【问题标题】:Cocoa: AVAsset loaded from file has 0 tracksCocoa:从文件加载的 AVAsset 有 0 个轨道
【发布时间】:2014-02-23 03:43:03
【问题描述】:

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

    }];

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

关于如何使它工作的任何建议?

【问题讨论】:

  • 您在哪个 OS X 版本上试用?

标签: objective-c macos cocoa audio avfoundation


【解决方案1】:

显然我使用了错误的 NSURL 方法。我把它改成了这样:

AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:tempOldFilePath] options:nil];

现在我的 AVAsset 中每个都有 1 个轨道。如果有人能很好地解释为什么这是必要的,我会接受这个答案。

【讨论】:

    【解决方案2】:

    正如您已经发现的,您需要使用fileURLWithPath:,而不是URLWithString:,来创建您的网址。

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

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

    【讨论】:

      【解决方案3】:

      我找到了出现这个错误的原因并最终解决了。

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

      NSString *source_file_path = @"temp_video.mov"
      

      而不是

      NSString *source_file_path = @"temp_video.mp4"
      

      问题已解决,现在运行良好。

      希望对大家有所帮助。

      【讨论】:

        猜你喜欢
        • 2018-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多