.m4a来自iPod Library的原始数据不能播放
所以我面临一个非常奇怪的问题,并想知道是否有其他人遇到这个问题。 我从手机音乐库抓取MPMediaItem的原始数据,然后通过HTTP将其发送到别处播放。 当我从一个.m4atypes的文件中抓取原始数据的时候,我的问题就出现了。 例如,如果我从iTunes检查的原始文件是7.4MB,从我的代码得到的是7.3MB的大小。 我做了一些研究,发现一个.m4a文件实际上是一个封装,我想我没有得到封装的文件只是原始音乐数据,因此它是不可识别的。 这里是我的代码,给我从MPMediaItem原始音乐数据
NSError * error = nil; MPMediaQuery *query = [MPMediaQuery albumsQuery]; NSArray * songs = query.items; MPMediaItem * song = [songs objectAtIndex:socket_data_index]; AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:[song valueForProperty:MPMediaItemPropertyAssetURL] options:nil]; AVAssetReader * reader = [[AVAssetReader alloc] initWithAsset:songAsset error:&error]; AVAssetTrack * songTrack = [songAsset.tracks objectAtIndex:0]; AVAssetReaderTrackOutput * output = [[AVAssetReaderTrackOutput alloc] initWithTrack:songTrack outputSettings:nil]; [reader addOutput:output]; [output release]; [reader startReading]; while (reader.status == AVAssetReaderStatusReading) { AVAssetReaderTrackOutput * trackOutput = (AVAssetReaderTrackOutput *)[reader.outputs objectAtIndex:0]; CMSampleBufferRef sampleBufferRef = [trackOutput copyNextSampleBuffer]; if (sampleBufferRef) { CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBufferRef); size_t length = CMBlockBufferGetDataLength(blockBufferRef); NSMutableData * data = [[NSMutableData alloc] initWithLength:length]; CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, data.mutableBytes); [data_to_return appendData:data]; [data release]; CMSampleBufferInvalidate(sampleBufferRef); CFRelease(sampleBufferRef); } } if (reader.status == AVAssetReaderStatusFailed || reader.status == AVAssetReaderStatusUnknown) { // Something went wrong. Handle it. } if (reader.status == AVAssetReaderStatusCompleted) { return [[[HTTPDataResponse alloc] initWithData:data_to_return] autorelease]; } [reader release];
我会,并会得到正确的数据.mp3文件是在手机库,但涉及。M4A似乎缺less一些部分。
再次感谢您花时间帮助我。
我遇到了同样的问题。 AVAssetReader仅返回原始audio数据。 它适用于.mp3,因为文件格式只是一堆包含播放器播放文件所需的一切帧。 您可能会注意到导出的文件中缺less所有的id3信息。
.m4aaudio文件是环绕aacaudio数据的容器。 您只收到audio数据,没有进一步的信息,即采样率或查找表。
解决您的问题的方法可能是使用AVAssetExportSession将AVAssetTrack导出到电话上的文件,然后从那里stream式传输文件。 我试了这个和一个工作.m4a文件被写入。
下面的代码是基于苹果示例如何导出修剪的audio资产 :
// create the export session AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset: songAsset presetName:AVAssetExportPresetAppleM4A]; if (nil == exportSession) NSLog(@"Error"); // configure export session output with all our parameters NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; NSString *filePath = [NSString stringWithFormat: @"%@/export.m4a", basePath]; exportSession.outputURL = [NSURL fileURLWithPath: filePath]; // output path exportSession.outputFileType = AVFileTypeAppleM4A; // output file type [exportSession exportAsynchronouslyWithCompletionHandler:^{ if (AVAssetExportSessionStatusCompleted == exportSession.status) { NSLog(@"AVAssetExportSessionStatusCompleted"); } else if (AVAssetExportSessionStatusFailed == exportSession.status) { // a failure may happen because of an event out of your control // for example, an interruption like a phone call comming in // make sure and handle this case appropriately NSLog(@"AVAssetExportSessionStatusFailed"); } else { NSLog(@"Export Session Status: %d", exportSession.status); } }];
这个解决scheme的缺点是,while文件必须写在磁盘上。 我仍然在寻找更好的方式来处理.m4a文件。