ios上传音频文件到服务器,IOS开发:iPod的音乐库中的音频如何上传到服务器中...
最近在做的項目里有一個功能,就是拿到手機媒體庫中的音頻文件,并實現APP中的播放,已經轉成MP3格式上傳到服務器上。
首先是要能獲取到ipod library中的音頻。這里我用的是MPMediaQuery,在這里有一個坑,可以拿到的歌曲中有很多歌曲的AssetURL為nil,這是因為MPMediaQuery只能拿到用戶通過itunes倒入進去的歌曲url。
代碼如下:
// 1.創建媒體選擇隊列(從ipod庫中讀出音樂文件)
MPMediaQuery*everything = [[MPMediaQueryalloc]init];
// 2.創建讀取條件(類似于對數據做一個篩選) Value:作用等同于MPMediaType枚值
MPMediaPropertyPredicate*albumNamePredicate =
[MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypeMusic ] forProperty: MPMediaItemPropertyMediaType];
//3.給隊列添加讀取條件
[everythingaddFilterPredicate:albumNamePredicate];
//4.從隊列中獲取符合條件的數組集合
NSArray*itemsFromGenericQuery = [everythingitems];
//5.便利解析數據
for(MPMediaItem*songinitemsFromGenericQuery) {
//歌曲名字
> NSString *songTitle = [song valueForProperty: MPMediaItemPropertyTitle];
//歌曲路徑
NSString *url = [song valueForProperty: MPMediaItemPropertyAssetURL];
//歌手
NSString *songer = [song valueForProperty: MPMediaItemPropertyArtist];
}
拿到后肯定是實現APP中的播放,這個就很簡單了。采用AVAudioPlayer就好了
經過一番查閱,最終找到一個辦法,就是先把它轉為caf 寫到內存里,然后再把.caf轉為.mp3 就可以上傳了。這里caf轉mp3需要使用第三方庫:lame (lame三庫的資源)
代碼如下:
1.導出成caf格式,這種導出方式,文件名必須以.caf作為后綴
- (void)convertToCAF:(NSString *)songUrl name:(NSString *)songName
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[UsingHUD showInView:self.view text:@"正在處理,請稍等..."];
});
NSURL *url = [NSURL URLWithString:songUrl];
//由于中文歌名不行 這邊采用時間戳
NSString *fileName = [NSString stringWithFormat:@"%@.caf",[self getTimestamp]];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url 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];
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
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:44100.0], 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: ^
{
// NSLog (@"top of block");
while (assetWriterInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
if (nextBuffer) {
// append buffer
[assetWriterInput appendSampleBuffer: nextBuffer];
// NSLog (@"appended a buffer (%d bytes)",
// CMSampleBufferGetTotalSampleSize (nextBuffer));
convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
} else {
// done!
[assetWriterInput markAsFinished];
[assetWriter finishWriting];
[assetReader cancelReading];
NSDictionary *outputFileAttributes = [[NSFileManager defaultManager]
attributesOfItemAtPath:exportPath
error:nil];
//實現caf 轉mp3
[self audioCAFtoMP3:exportPath];
NSLog (@"done. file size is %lld",
[outputFileAttributes fileSize]);
break;
}
}
}];
}
2.caf >mp3
- (void)audioCAFtoMP3:(NSString *)wavPath {
NSString *cafFilePath = wavPath;
NSString *mp3FilePath = [NSString stringWithFormat:@"%@.mp3",[NSString stringWithFormat:@"%@",[cafFilePath substringToIndex:cafFilePath.length - 4]]];
@try {
int read, write;
FILE *pcm = fopen([cafFilePath cStringUsingEncoding:1], "rb"); //source 被轉換的音頻文件位置
fseek(pcm, 4*1024, SEEK_CUR); //skip file header
FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb"); //output 輸出生成的Mp3文件位置
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_num_channels(lame,1);//設置1為單通道,默認為2雙通道
lame_set_in_samplerate(lame, 44100.0);
lame_set_VBR(lame, vbr_default);
lame_set_brate(lame,8);
lame_set_mode(lame,3);
lame_set_quality(lame,2);
lame_init_params(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);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
}
@finally {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[UsingHUD hideInView:self.view];
//主線程上傳到oss
[self localdispose:mp3FilePath];
});
}
}
到此,大功告成~~
總結
以上是生活随笔為你收集整理的ios上传音频文件到服务器,IOS开发:iPod的音乐库中的音频如何上传到服务器中...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逆序输出(数组练习)
- 下一篇: 找出一个数组中出现次数最多的那个元素