【问题标题】:Wave to Caf format using AVAssetWriter使用 AVAssetWriter 将波形转换为 Caf 格式
【发布时间】:2013-07-12 14:30:15
【问题描述】:

使用 AVAssetWriter 将波形转换为 Caf 格式。 我有一个波形文件。 我想将其转换为 Core Audio 格式。

这是我一直在尝试但无处可去的代码。 尝试搜索所有论坛,但没有找到任何人的工作代码。

NSError *error = nil ;

NSDictionary *audioSetting = [NSDictionary dictionaryWithObjectsAndKeys:
[ NSNumber numberWithFloat:16000.0], AVSampleRateKey,
[ NSNumber numberWithInt:1], AVNumberOfChannelsKey,
[ NSNumber numberWithInt:kAudioFormatAppleIMA4], AVFormatIDKey, nil ];

NSString *audioFilePath = filePath;
AVURLAsset * URLAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:audioFilePath] options:nil];

if (!URLAsset) return NO ;

AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:URLAsset error:&error];
if (error) return NO;

/*NSArray *tracks = [URLAsset tracksWithMediaType:AVMediaTypeAudio];
if (![tracks count]) return NO;

AVAssetReaderAudioMixOutput *audioMixOutput = [AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:tracks
audioSettings :audioSetting];

AVAssetReaderOutput *audioOutput = [AVAssetReaderOutput ]
if (![assetReader canAddOutput:audioMixOutput]) return NO ;

[assetReader addOutput :audioMixOutput];
*/

if (![assetReader startReading]) return NO;

NSString *outPath = [filePath stringByDeletingPathExtension];
outPath = [outPath stringByAppendingPathExtension:@"caf"];

[[NSFileManager defaultManager] removeItemAtPath:outPath error:nil];
NSURL *outURL = [NSURL fileURLWithPath:outPath];
AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:outURL
fileType:AVFileTypeCoreAudioFormat
error:&error];
if (error) return NO;

AVAssetWriterInput *assetWriterInput = [ AVAssetWriterInput assetWriterInputWithMediaType :AVMediaTypeAudio
outputSettings:audioSetting];
assetWriterInput. expectsMediaDataInRealTime = NO;

if (![assetWriter canAddInput:assetWriterInput]) return NO ;

[assetWriter addInput :assetWriterInput];

if (![assetWriter startWriting]) return NO;

[assetWriter startSessionAtSourceTime:kCMTimeZero ];

dispatch_queue_t queue = dispatch_queue_create( "assetWriterQueue", NULL );

[assetWriterInput requestMediaDataWhenReadyOnQueue:queue usingBlock:^{

NSLog(@"start");

while (1)
{
if ([assetWriterInput isReadyForMoreMediaData]) {

CMSampleBufferRef sampleBuffer = [audioMixOutput copyNextSampleBuffer];

if (sampleBuffer) {
[assetWriterInput appendSampleBuffer :sampleBuffer];
CFRelease(sampleBuffer);
} else {
[assetWriterInput markAsFinished];
break;
}
}
}

[assetWriter finishWritingWithCompletionHandler:^(void)
{
NSLog(@"CAF Completed");
}];

NSLog(@"finish");
}];
return YES;

如果有人能指出正确的方向,那将非常有帮助。

【问题讨论】:

    标签: ios ipad avassetwriter wave caf


    【解决方案1】:

    试试这个,

    NSString *wavFilePath = [[NSBundle mainBundle] pathForResource:@"sampleaudio" ofType:@"wav"];
    
    NSURL *assetURL = [NSURL fileURLWithPath:wavFilePath];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
    
    NSError *assetError = nil;
    AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:songAsset
                                                               error:&assetError]
    ;
    if (assetError) {
        NSLog (@"error: %@", assetError);
        return;
    }
    
    AVAssetReaderOutput *assetReaderOutput = [AVAssetReaderAudioMixOutput
                                              assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
                                              audioSettings: nil];
    if (! [assetReader canAddOutput: assetReaderOutput]) {
        NSLog (@"can't add reader output... die!");
        return;
    }
    [assetReader addOutput: assetReaderOutput];
    
    NSString *strcafFileName = [NSString stringWithFormat:@"%@.caf",[wavFilePath stringByDeletingPathExtension]];
    NSString *cafFilePath = [delegate.strCassettePathSide stringByAppendingPathComponent:strcafFileName];
    
    NSURL *exportURL = [NSURL fileURLWithPath:cafFilePath];
    AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:exportURL
                                                          fileType:AVFileTypeCoreAudioFormat
                                                             error:&assetError];
    if (assetError)
    {
        NSLog (@"error: %@", assetError);
        return;
    }
    
    AudioChannelLayout channelLayout;
    memset(&channelLayout, 0, sizeof(AudioChannelLayout));
    channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
                                    [NSNumber numberWithFloat:11025], AVSampleRateKey,
                                    [NSNumber numberWithInt:2], AVNumberOfChannelsKey,
                                    [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
                                    [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                                    [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
                                    nil];
    AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
                                                                              outputSettings:outputSettings];
    if ([assetWriter canAddInput:assetWriterInput])
    {
        [assetWriter addInput:assetWriterInput];
    }
    else
    {
        NSLog(@"can't add asset writer input... die!");
        return;
    }
    
    assetWriterInput.expectsMediaDataInRealTime = NO;
    
    [assetWriter startWriting];
    [assetReader startReading];
    
    AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
    CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
    [assetWriter startSessionAtSourceTime: startTime];
    
    __block UInt64 convertedByteCount = 0;
    dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
    
    [assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
                                            usingBlock: ^
     {
         while (assetWriterInput.readyForMoreMediaData)
         {
             CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
             if (nextBuffer)
             {
                 // append buffer
                 [assetWriterInput appendSampleBuffer: nextBuffer];
                 convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
    
                 CMSampleBufferInvalidate(nextBuffer);
                 CFRelease(nextBuffer);
                 nextBuffer = NULL;
             }
             else
             {
                 [assetWriterInput markAsFinished];
                 //              [assetWriter finishWriting];
                 [assetReader cancelReading];
    
                 break;
             }
         }
     }];
    

    【讨论】:

      【解决方案2】:

      我已经用下面的方法解决了:

      1. 在我的解决方案中导入了这个文件ExtAudioFileConvert.cpp。 (https://developer.apple.com/library/ios/samplecode/iPhoneExtAudioFileConvertTest/Listings/ExtAudioFileConvert_cpp.html) 此外,还导入了所有其他必需的文件,即PublicUtility Folder

      2. 调用这个函数DoConvertFile

      示例代码

      CFURLRef sourceURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)sourcefilePath, kCFURLPOSIXPathStyle, false);
      
      CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false);
      
      OSStatus error = DoConvertFile((sourceURL, destinationURL, kAudioFormatAppleIMA4, 16000.0 );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-04
        相关资源
        最近更新 更多