我正在尝试使用QTKit将两个.mp3组合成一个.wav文件。它似乎工作,但第二个文件的最后几秒被截断。有什么想法吗?
- (IBAction)combineSelectedFilesAndOutputAsWAV {
QTMovie *movie = [QTMovie movieWithFile:fileOne error:NULL];
[movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
QTMovie *segmentTwo = [QTMovie movieWithFile:fileTwo error:NULL];
QTTimeRange range = { .time = QTZeroTime, .duration = [segmentTwo duration] };
[segmentTwo setSelection:range];
[movie appendSelectionFromMovie:segmentTwo];
while([[movie attributeForKey:QTMovieLoadStateAttribute] longValue] != 100000L) {
//wait until QTMovieLoadStateComplete
}
NSDictionary *exportAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], QTMovieExport,
[NSNumber numberWithLong:kQTFileTypeWave], QTMovieExportType, nil];
NSString *outputFile = [NSString stringWithFormat:@"%@.wav", outputFilename];
NSString *filepath = [destinationDirectory stringByAppendingPathComponent:outputFile];
if (![movie writeToFile:filepath withAttributes:exportAttributes]) {
//ERROR
}
}
(忽略等待QTMovieLoadStateComplete的while循环。我将来会切换到使用通知。但是现在,它应该没关系......)
答案 0 :(得分:2)
1)通常,无法快速获得任意MP3文件的确切持续时间。唯一可靠的方法 - 解码整个文件。即使对于CBR文件也是如此(某些MP3编码器无法提供准确的比特率)。因此,[段持续时间]可能不适合需要精确持续时间的情况。对于你的pupposes,你可以尝试使用[段持续时间] + delta,甚至MaxDuration而不是[段持续时间]。
2)在某些情况下(至少如果合并文件的格式相同),您可以简单地将文件合并为二进制数据(不使用QTKit)。更为谨慎:为目标文件写入RIFF-WAV标头;从第一个文件中追出声音流(即源文件,如果存在,则排除标题和尾部标记);从第二个文件中追出声音流;更新RIFF-WAV标题。
答案 1 :(得分:0)
看起来真正的问题是我在QTMovie对象创建后立即对其进行查询。在请求QTMovie对象的持续时间之前,您应该确保它已完全加载。我添加了以下内容:
- (void)pasteSegmentToConcatenatedFile:(QTMovie *)segment {
NSLog(@"LoadStateChanged for movie : %@", segment);
if ([[segment attributeForKey:QTMovieLoadStateAttribute] longValue] >= kMovieLoadStateComplete) {
NSLog(@"The movie is fully loaded.");
QTTimeRange range = { .time = QTZeroTime, .duration = [segment duration] };
[segment setSelection:range];
[concatenatedFile appendSelectionFromMovie:segment];
[self convertAndOutputConcatenatedMovie];
}
}
只要QTMovie对象的LoadState发生更改,就会调用此方法:
QTMovie *segmentTwo = [QTMovie movieWithFile:fileTwo error:NULL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pasteSegmentToConcatenatedFile:) name:QTMovieLoadStateDidChangeNotification object:segmentTwo];
答案 2 :(得分:0)
您也可以简单地将movie / mp3加载程序设置为同步而不是异步 像这样使用QTMovieOpenAsyncOKAttribute:
NSDictionary *movieAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO] , QTMovieOpenAsyncOKAttribute,
@"path to file", QTMovieFileNameAttribute,
[NSNumber numberWithBool:YES], QTMovieEditableAttribute,
nil];
QTMovie *myMovie = [QTMovie movieWithAttributes:movieAttributes error:nil];
这样,当您检查时,持续时间应该是正确的:
[[myMovie attributeForKey:QTMovieDurationAttribute] QTTimeValue].timeValue;