ios - insertTimeRange:ofTrack:atTime:error:(类AVMutableCompositionTrack)在iPhone上失败

标签 ios objective-c iphone avasset avmutablecomposition

类AVMutableCompositionTrack的insertTimeRange:ofTrack:atTime:error:在iPhone(但不是模拟器)上返回NO且错误“无法完成操作”。错误消息没有帮助,我很想找出错误的原因,更不用说解决方法了。任何帮助,将不胜感激。

在下面的示例代码中,我要做的就是尝试将音频剪辑添加到AVMutableCompositionTrack。这是代码中发生的事情:

  • AVMutableComposition和AVMutableCompositionTrack对象是在init中创建的。
  • 调用类方法addPhrase:atTime:将音频剪辑添加到合成音轨。
  • 实际插入的函数是addAudioClip:atTime:。
  • 帮助程序函数audioClipWithName:ofType将请求的音频文件加载到AVAssetTrack中。

  • -> NSLOG输出:

    insertTimeRange atTime = 0.0范围=(0.0,2.1)compositionTrack =
    - - - - - 错误!错误域= AVFoundationErrorDomain代码= -11800“操作无法完成” UserInfo = {NSLocalizedDescription =操作无法完成,NSUnderlyingError = 0x16fc1c90 {Error Domain = NSOSStatusErrorDomain代码= -12780“(null)”},NSLocalizedFailureReason = An发生未知错误(-12780)}

    ->样本代码:
    @interface MyAudioPlayer()
    
    @property (strong, nonatomic) AVMutableComposition *composition;
    @property (strong, nonatomic) AVMutableCompositionTrack *compositionTrack;
    
    @end
    
    
    @implementation MyAudioPlayer
    
    - (id) init
    {
        self = [super init];
        if (self != nil) {
            self.composition = [AVMutableComposition composition];
            self.compositionTrack = [self.composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
        }
        return self;
    }
    
    // Add the phrase into compositionAudioTrack at the given time.
    - (void) addPhrase:(NSString *)phrase atTime:(CMTime)atTime
    {
        // Add the phrase to the audio.
        AVAssetTrack *audioClip = [self audioClipWithName:phrase ofType:@"mp3"];
        // Add the phrase to the audio track.
        [self addAudioClip:audioClip atTime];
    }
    
    // Add the given audio clip to the composed audio at the given time.
    - (void) addAudioClip:(AVAssetTrack *)audioClip atTime:(CMTime)atTime
    {
        NSError *error = [[NSError alloc] init];
        CMTimeRange audioClipRange = CMTimeRangeMake(kCMTimeZero, audioClip.timeRange.duration);
        BOOL success = [self.compositionTrack insertTimeRange:audioClipRange ofTrack:audioClip atTime:atTime error:&error];
        NSLog(@"insertTimeRange atTime=%.1f range=(%.1f, %.1f) compositionTrack=%@\n", CMTimeGetSeconds(atTime), CMTimeGetSeconds(audioClipRange.start), CMTimeGetSeconds(audioClipRange.duration), self.compositionTrack);
        if (!success) {
            NSLog(@"----------ERROR! %@", error);
        }
    }
    
    // Return an audio clip with the given name and type.
    - (AVAssetTrack *) audioClipWithName:(NSString *)name ofType:(NSString *)type
    {
        NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:name ofType:type];
        NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
        AVAsset *avAsset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
        AVAssetTrack *audioClip = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
        return audioClip;
    }
    
    @end
    

    最佳答案

    你的问题在于

    - (AVAssetTrack *) audioClipWithName:(NSString *)name ofType:(NSString *)type;
    

    它使轨道拥有的AVAsset超出范围并被释放,从而使轨道处于不良状态。

    确保(至少)一直引用AVAsset,直到调用insertTimeRange为止。实际上,这意味着您应该一起传递AVAsset及其AVAssetTrack

    关于ios - insertTimeRange:ofTrack:atTime:error:(类AVMutableCompositionTrack)在iPhone上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39443484/

    相关文章:

    ios - 更改 SwiftUI 中选取器的导航标题

    ios - 如何在 Swift 中使用坐标打开 MKMapItem?

    ios - 如何在 View 中重叠 UIButton 和 UIImage?

    objective-c - 如何使用此配置访问我的 UINavigationBar 属性?

    ios - UITableViewCell 中的 UIButton

    objective-c - 添加推送通知时的 Bundle ID 问题

    ios - 在 Sprite Kit 中创建按钮的正确方法?

    iphone - PerformSelectorOnMainThread 结果为 "unrecognized selector sent to instance"

    ios - 未使用 iBeacon Simulator 调用 CLLocationManager 委托(delegate)方法

    iphone - 通过iOS免费进行非消耗性应用内购买