简体   繁体   English

使用AVAssetWriter转换为Caf格式

[英]Wave to Caf format using AVAssetWriter

Wave to Caf format using AVAssetWriter. 使用AVAssetWriter转换为Caf格式。 I have a wave file. 我有一个wave文件。 I want to convert it to a Core Audio format. 我想将其转换为核心音频格式。

This is the code i've been trying and found nowhere to go. 这是我一直在尝试的代码,无处可去。 Tried searching all forums but there is no working code which anyone's found. 尝试搜索所有论坛,但没有任何人找到的有效代码。

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;

It'll be really helpful if anyone can point in the right direction. 如果任何人都可以指出正确的方向,那将非常有帮助。

Try this, 尝试这个,

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;
         }
     }
 }];

I had solved using the following method: 我已经使用以下方法解决了:

  1. Imported this file ExtAudioFileConvert.cpp in my solution. 在我的解决方案中导入了此文件ExtAudioFileConvert.cpp ( https://developer.apple.com/library/ios/samplecode/iPhoneExtAudioFileConvertTest/Listings/ExtAudioFileConvert_cpp.html ) Also, Imported all the other required files also along with it ie PublicUtility Folder . https://developer.apple.com/library/ios/samplecode/iPhoneExtAudioFileConvertTest/Listings/ExtAudioFileConvert_cpp.html )此外,还导入了所有其他所需文件,即PublicUtility Folder

  2. Calling this function DoConvertFile 调用此函数DoConvertFile

Sample Code 样例代码

CFURLRef sourceURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)sourcefilePath, kCFURLPOSIXPathStyle, false);

CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false);

OSStatus error = DoConvertFile((sourceURL, destinationURL, kAudioFormatAppleIMA4, 16000.0 );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM