AVMutableCompositionTrack - 使用insertEmptyTimeRange在两个WAV文件之间插入静音

时间:2014-08-02 21:42:12

标签: ios audio avfoundation

我遇到的问题是在两个wav文件之间放置一定量的沉默。

到目前为止我的方法如下:

首先,我创建了AVMutableCompositionAVMutableCompositionTrack

AVMutableComposition* composition = [AVMutableComposition composition];
AVMutableCompositionTrack* appendedAudioTrack =
[composition addMutableTrackWithMediaType:AVMediaTypeAudio
                         preferredTrackID:kCMPersistentTrackID_Invalid];

然后使用AVURLAsset我分配了方便命名的first.wav文件。

AVURLAsset* firstComponent = [[AVURLAsset alloc]
                             initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]  pathForResource: @"first" ofType: @"wav"]] options:nil];

然后我将其插入我之前命名为appendedAudioTrack的可变组合轨道

NSArray *firstTrack = [firstComponent tracksWithMediaType:AVMediaTypeAudio];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, firstComponent.duration);
[appendedAudioTrack insertTimeRange:timeRange
                            ofTrack:[firstTrack objectAtIndex:0]
                             atTime:kCMTimeZero
                              error:&error];

以完全相同的方式插入second.wav文件:

AVURLAsset* secondComponent = [[AVURLAsset alloc]
                              initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource: @"second" ofType: @"wav"]] options:nil];
NSArray *secondTrack = [secondComponent tracksWithMediaType:AVMediaTypeAudio];
CMTimeRange timeRange2 = CMTimeRangeMake(kCMTimeZero, secondComponent.duration);
[appendedAudioTrack insertTimeRange:timeRange2
                            ofTrack:[secondTrack objectAtIndex:0]
                             atTime:kCMTimeZero
                              error:&error];

到目前为止,这成功地将两个wav文件端到端地连接起来。

然后我尝试使用insertEmptyTimeRange插入可变数量的沉默,如下所示:

    CMTimeRange timeRange3 = CMTimeRangeFromTimeToTime(firstComponent.duration,CMTimeAdd(firstComponent.duration,CMTimeMake(interval,1)));
[appendedAudioTrack insertEmptyTimeRange:timeRange3];

静音持续时间为float,出于测试目的,目前为0.49。它的变量名是interval,它表示所需的静音,以秒为单位。

我使用CMTimeRange做出的假设是AVURLAsset的持续时间属性可以被视为第一个音轨的结束CMTime

当我从Xcode中的组织者下载文档目录,并在audacity中查看生成的m4a文件时,静音在文件中,但它在开头,而不是在两个.wav文件的中间。

错误地说:SILENCE,first.wav,second.wav

我想知道如何正确使用insertEmptyTimeRange来生成 first.wav,SILENCE,second.wav。

注意:我看到this问题(以及其他问题)提出了一个非常类似的问题,但他们采用的方法是使用恒定的静音文件。我的沉默是可变的,并在运行时确定。而且我也知道另一个答案提供了他们所说的解决方案,但它对我没有用。我尝试过在互联网上找到的所有不同的方法,但似乎我误解了一些东西,因为它对我来说无法正常工作。

如果重要,我会像这样导出文件:

 // Create a new audio file using the appendedAudioTrack
AVAssetExportSession* exportSession = [AVAssetExportSession
                                       exportSessionWithAsset:composition
                                       presetName:AVAssetExportPresetAppleM4A];

if (!exportSession)
{
    // do something
    return nil;
}



//This gives me an output URL to a file name that doesn't yet exist
NSString *path2;
NSArray *paths2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path2 = [paths2 objectAtIndex:0];
path2 = [path2 stringByAppendingPathComponent:[string stringByAppendingString: @".m4a"]];
NSString* appendedAudioPath= path2;



exportSession.outputURL = [NSURL fileURLWithPath:appendedAudioPath];
exportSession.outputFileType = AVFileTypeAppleM4A;



[exportSession exportAsynchronouslyWithCompletionHandler:^{


    switch (exportSession.status)
    {
        case AVAssetExportSessionStatusFailed:
            NSLog(@"%@",exportSession.error);
            break;
        case AVAssetExportSessionStatusCompleted:

            break;
        case AVAssetExportSessionStatusWaiting:
            break;
        default:
            break;
    }

由于

1 个答案:

答案 0 :(得分:0)

事实证明,间隔不是正确的持续时间,当检查大胆时它实际上是0.049,而不是0.49。

我遇到的问题是这个

CMTimeMake(interval,1)

我认为这会产生interval/1秒,但我错了。

相反,我使用CMTimeMakeWithSecondsNSEC_PER_SEC一样

    CMTimeRange timeRange3 = CMTimeRangeFromTimeToTime(firstComponent.duration,CMTimeAdd(firstComponent.duration,CMTimeMakeWithSeconds(interval ,NSEC_PER_SEC)));
[appendedAudioTrack insertEmptyTimeRange:timeRange3];

这为我提供了所需的interval秒长的沉默,并且在正确的位置。