我使用AudioFileReadPacketData连接了2个音频文件,以读取现有文件并使用AudioFileWritePackets将数据写入第三个文件。源文件似乎包含有关其持续时间的信息。我可以使用下面的代码访问它,传递文件url
-(float)lengthForUrl:(NSURL *)url
{
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:url options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
return audioDurationSeconds;
}
当我对我的新组合文件进行相同的调用时,我的持续时间为0。
如何设置新文件的持续时间? 或者在转移过程中保留它?
答案 0 :(得分:0)
我没弄明白如何在我的合并文件中设置持续时间,但确实如此 弄清楚如何在持续时间不变的情况下创建它。 我从使用AssetReader / Writer切换到使用ExtFileReader / Writer - 工作代码在
之下- (BOOL)combineFilesFor:(NSURL*)url
{
dispatch_async(dispatch_get_main_queue(), ^{
activity.hidden = NO;
[activity startAnimating];
});
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *soundOneNew = [documentsDirectory stringByAppendingPathComponent:Kcombined];
NSLog(@"%@",masterUrl);
NSLog(@"%@",url);
// create the url for the combined file
CFURLRef out_url = (__bridge CFURLRef)[NSURL fileURLWithPath:soundOneNew];
NSLog(@"out file url : %@", out_url);
ExtAudioFileRef af_in;
ExtAudioFileRef af_out = NULL;
Float64 existing_audioDurationSeconds = [self lengthForUrl:masterUrl];
NSLog(@"duration of existing file : %f", existing_audioDurationSeconds);
Float64 new_audioDurationSeconds = [self lengthForUrl:url];
NSLog(@"duration of existing file : %f", new_audioDurationSeconds);
Float64 combined_audioDurationSeconds = existing_audioDurationSeconds + new_audioDurationSeconds;
NSLog(@"duration of combined : %f", combined_audioDurationSeconds);
// put the urls of the files to combine in to an array
NSArray *sourceURLs = [NSArray arrayWithObjects:(__bridge id)((__bridge CFURLRef)
AudioStreamBasicDescription inputFileFormat;
AudioStreamBasicDescription converterFormat;
UInt32 thePropertySize = sizeof(inputFileFormat);
AudioStreamBasicDescription outputFileFormat;
#define BUFFER_SIZE 4096
UInt8 *buffer = NULL;
for (id in_url in sourceURLs) {
NSLog(@"url in = %@",in_url);
OSStatus in_stat = ExtAudioFileOpenURL ( (__bridge CFURLRef)(in_url), &af_in);
NSLog(@"in file open status : %d", (int)in_stat);
bzero(&inputFileFormat, sizeof(inputFileFormat));
in_stat = ExtAudioFileGetProperty(af_in, kExtAudioFileProperty_FileDataFormat,
&thePropertySize, &inputFileFormat);
NSLog(@"in file get property status : %d", (int)in_stat);
memset(&converterFormat, 0, sizeof(converterFormat));
converterFormat.mFormatID = kAudioFormatLinearPCM;
converterFormat.mSampleRate = inputFileFormat.mSampleRate;
converterFormat.mChannelsPerFrame = 1;
converterFormat.mBytesPerPacket = 2;
converterFormat.mFramesPerPacket = 1;
converterFormat.mBytesPerFrame = 2;
converterFormat.mBitsPerChannel = 16;
converterFormat.mFormatFlags = kAudioFormatFlagsNativeEndian |kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
in_stat = ExtAudioFileSetProperty(af_in, kExtAudioFileProperty_ClientDataFormat,
sizeof(converterFormat), &converterFormat);
NSLog(@"in file set property status : %d", (int)in_stat);
if (af_out == NULL) {
memset(&outputFileFormat, 0, sizeof(outputFileFormat));
outputFileFormat.mFormatID = kAudioFormatMPEG4AAC;
outputFileFormat.mFormatFlags = kMPEG4Object_AAC_Main;
outputFileFormat.mSampleRate = inputFileFormat.mSampleRate;
outputFileFormat.mChannelsPerFrame = inputFileFormat.mChannelsPerFrame;
// create the new file to write the combined file 2
OSStatus out_stat = ExtAudioFileCreateWithURL(out_url, kAudioFileM4AType, &outputFileFormat,
NULL, kAudioFileFlags_EraseFile, &af_out);
NSLog(@"out file create status : %d", out_stat);
out_stat = ExtAudioFileSetProperty(af_out, kExtAudioFileProperty_ClientDataFormat,
sizeof(converterFormat), &converterFormat);
NSLog(@"out file set property status : %d", out_stat);
}
// Buffer to read from source file and write to dest file
buffer = malloc(BUFFER_SIZE);
assert(buffer);
AudioBufferList conversionBuffer;
conversionBuffer.mNumberBuffers = 1;
conversionBuffer.mBuffers[0].mNumberChannels = inputFileFormat.mChannelsPerFrame;
conversionBuffer.mBuffers[0].mData = buffer;
conversionBuffer.mBuffers[0].mDataByteSize = BUFFER_SIZE;
while (TRUE) {
conversionBuffer.mBuffers[0].mDataByteSize = BUFFER_SIZE;
UInt32 frameCount = INT_MAX;
if (inputFileFormat.mBytesPerFrame > 0) {
frameCount = (conversionBuffer.mBuffers[0].mDataByteSize / inputFileFormat.mBytesPerFrame);
}
// Read a chunk of input
OSStatus err = ExtAudioFileRead(af_in, &frameCount, &conversionBuffer);
if (err) {
NSLog(@"error read from input file : %d", (int)err);
}else{
NSLog(@"read %d frames from inout file", frameCount);
}
// If no frames were returned, conversion is finished
if (frameCount == 0)
break;
// Write pcm data to output file
err = ExtAudioFileWrite(af_out, frameCount, &conversionBuffer);
if (err) {
NSLog(@"error write out file : %d", (int)err);
}else{
NSLog(@"wrote %d frames to out file", frameCount);
}
}
ExtAudioFileDispose(af_in);
}
ExtAudioFileDispose (af_out);
NSLog(@"combined file duration =: %f", [self lengthForUrl:[NSURL fileURLWithPath:soundOneNew]]);
// move the new file into place
[self deleteFileWithName:KUpdate forType:@""];
[self deleteFileWithName:KMaster forType:@""];
player = nil;
[self replaceFileAtPath:KMaster withData:[NSData dataWithContentsOfFile:soundOneNew]];
[self deleteFileWithName:Kcombined forType:@""];
[self pauseRecording];
dispatch_async(dispatch_get_main_queue(), ^{
activity.hidden = YES;
[activity stopAnimating];
record.enabled = YES;
});
return YES;
}