目标:我想从mp3格式的视频中提取音频.视频可以采用任何iOS支持的格式
我尝试了以下技术来实现上述目标,我使用的是lame库:
步骤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格式的视频中提取音频.
谢谢.