AVAudioPlayer拒绝播放修改过的wav文件

时间:2011-12-28 23:25:59

标签: objective-c c avaudioplayer wav

我第一次调用此方法file1将为nil并返回file2。当这个hapens文件将正常播放(因此调用此方法应该没问题)。但是当我第二次调用它时,它将返回AVAudioPlayer不播放的NSURL。我的猜测是我错过了标题中的内容。在调试模式中,我已经看到totalLength与数据的长度完全一样长。

+(NSURL *)mergeFile1:(NSURL *)file1 withFile2:(NSURL *)file2 {
    if(file1 == nil) {
        return [file2 copy];
    }

    NSData * wav1Data = [NSData dataWithContentsOfURL:file1];
    NSData * wav2Data = [NSData dataWithContentsOfURL:file2];

    int wav1DataSize = [wav1Data length] - 46;  
    int wav2DataSize = [wav2Data length] - 46;

    if (wav1DataSize <= 0 ||  wav2DataSize <= 0) {
        return nil;
    }   

    NSMutableData * soundFileData = [NSMutableData dataWithData:[wav1Data subdataWithRange:NSMakeRange(0, 46)]];
    [soundFileData appendData:[wav1Data subdataWithRange:NSMakeRange(46, wav1DataSize)]];
    [soundFileData appendData:[wav2Data subdataWithRange:NSMakeRange(46, wav2DataSize)]];

    unsigned int totalLength = [soundFileData length];

    NSLog(@"Calculated: %d - Real: %d", totalLength, [soundFileData length]);

    [soundFileData replaceBytesInRange:NSMakeRange(4, 4)
                             withBytes:&(UInt32){NSSwapHostIntToLittle(totalLength-8)}];
    [soundFileData replaceBytesInRange:NSMakeRange(42, 4)
                             withBytes:&(UInt32){NSSwapHostIntToLittle(totalLength)}];

    [soundFileData writeToURL:file1 atomically:YES];

    return [file1 copy];
}

如果有人看到可以提供帮助的东西,我将不胜感激! 任何问题都会尽快回答。

修改

我知道有两种wav标头:44个字节或46个字节。我试过了两个。

修改

我看过Audio File Services Reference,其中包含了许多我想要使用的好东西,但我无法弄清楚如何使用这一切。我真的不知道c。希望有人能帮助我解决这个问题。

修改

此处可找到合并的wav文件的示例:7--443522512

1 个答案:

答案 0 :(得分:1)

看起来你的WAV文件在FLLR块之前包含一个损坏的data块,或者至少VLC认为FLLR块超过2GB大,所以它试图跳到下一个超出文件结束的块。

也许你应该在合并之前尝试创建没有FLLR块的WAV文件,kAudioFileFlags_DontPageAlignAudioData接缝使音频文件服务跳过它。

另一种选择是提取data块并编写一个新的wav文件,并在此处执行概念验证:https://gist.github.com/1555889