5
目標:我想從MP3格式的視頻中提取音頻。視頻可以在任何iOS版支持的格式從MP3格式的視頻中提取音頻
我曾嘗試以下技術來實現上述目標,我用蹩腳的庫:
第1步:通過將源文件的URL到它創建一個AVURLAsset對象。
第2步:使用源資源創建AVAssetExportSession對象,將其outputfileType設置爲m4a。
第3步:提取其音頻,然後我嘗試將其轉換成MP3格式。
下面是代碼,我已經使用:
NSURL *videoFileUrl = [NSURL fileURLWithPath:originalVideoPath];
AVURLAsset *anAsset = [[AVURLAsset alloc] initWithURL:videoFileUrl options:nil];
exportSession=[AVAssetExportSession exportSessionWithAsset:anAsset presetName:AVAssetExportPresetPassthrough];
[exportSession determineCompatibleFileTypesWithCompletionHandler:^(NSArray *compatibleFileTypes) {
NSLog(@"compatiblefiletypes: %@",compatibleFileTypes);
}];
NSURL *furl = [NSURL fileURLWithPath:tmpVideoPath];
exportSession.outputURL = furl;
exportSession.outputFileType=AVFileTypeAppleM4A;
CMTime duration = anAsset.duration;
CMTimeRange range = CMTimeRangeMake(kCMTimeZero, duration);
exportSession.timeRange = range;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
switch (exportSession.status)
{
case AVAssetExportSessionStatusCompleted:
{
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD showProgress:0 status:@"Converting..." maskType:SVProgressHUDMaskTypeGradient];
[self performSelector:@selector(convertToMp3) withObject:nil afterDelay:0.3f];
});
break;
}
case AVAssetExportSessionStatusFailed:
{
dispatch_async(dispatch_get_main_queue(), ^{
[MyUtility showAlertViewWithTitle:kAlertTitle msg:exportSession.error.localizedDescription];
});
break;
}
case AVAssetExportSessionStatusCancelled:
NSLog(@"Export canceled");
break;
default:
break;
}
}];
__weak AVAssetExportSession *weakSession = exportSession;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
while (weakSession.status == AVAssetExportSessionStatusWaiting
|| weakSession.status == AVAssetExportSessionStatusExporting) {
dispatch_sync(dispatch_get_main_queue(), ^{
[SVProgressHUD showProgress:exportSession.progress status:@"Extracting..." maskType:SVProgressHUDMaskTypeGradient];
});
}
});
- (void)convertToMp3
{
NSURL *extractedAudioFileURL = [[NSURL alloc] initWithString:tmpVideoPath];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:extractedAudioFileURL error:&error];
float noOfChannels = [[audioPlayer.settings objectForKey:AVNumberOfChannelsKey] floatValue];
float sampleRate = [[audioPlayer.settings objectForKey:AVSampleRateKey] floatValue];
float bitRate = 16;//[[audioPlayer.settings objectForKey:AVLinearPCMBitDepthKey] floatValue];
@try {
int read, write;
FILE *pcm = fopen([tmpVideoPath cStringUsingEncoding:1], "rb"); //source
fseek(pcm, 4*1024, SEEK_CUR); //skip file header
FILE *mp3 = fopen([tmpMp3FilePath cStringUsingEncoding:1], "wb"); //output
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE*2];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, sampleRate);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
long long fileSize = [[[[NSFileManager defaultManager] attributesOfItemAtPath:tmpVideoPath error:nil] objectForKey:NSFileSize] longLongValue];
long duration = (fileSize * 8.0f)/(sampleRate * noOfChannels);
lame_set_num_samples(lame, (duration * sampleRate));
lame_get_num_samples(lame);
int percent = 0;
int totalframes = lame_get_totalframes(lame);
do {
read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
if (read == 0)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
int frameNum = lame_get_frameNum(lame);
if (frameNum < totalframes)
percent = (int) (100. * frameNum/totalframes + 0.5);
else
percent = 100;
[SVProgressHUD showProgress:percent status:@"Converting..." maskType:SVProgressHUDMaskTypeGradient];
NSLog(@"progress: %d",percent);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
}
@finally {
[SVProgressHUD dismiss];
}
}
所產生的音頻,我得到了什麼,但噪聲,其持續時間也是錯誤的。 我搜索了一下,發現「libmp3lame」只能理解線性PCM音頻,因爲m4a是壓縮音頻格式。
現在我怎樣才能將音頻轉換成MP3格式從m4a或任何其他方式直接從視頻以MP3格式提取音頻。
謝謝。
謝謝您的回答,但不幸的是我的應用程序崩潰,如果我的outputfiletype設置爲AVFileTypeAIFF和原因是這樣的格式與.mov影片兼容 –
嗯...我從來沒有過的情況下出口會話couldn」不會導出到它支持的特定格式。如果它可以讀取數據,它應該能夠導出數據。不知道那裏發生了什麼,對不起。 – nsdebug
@MuhammadZeeshan我面臨着同樣的問題。你有沒有找到解決辦法? –