所以我面临着一个非常奇怪的问题,想知道是否有其他人遇到过这个问题。我从手机音乐库中的 MPMediaItem 获取原始数据,然后通过 HTTP 将其发送到其他地方播放。我的问题出现的地方是当我从 .m4a 类型的文件中获取原始数据时,它似乎缺少一些片段。例如,如果我从 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 时,它似乎缺少一些部分。
再次感谢您花时间帮助我。
我遇到了同样的问题。 AVAssetReader 仅返回原始音频数据。它适用于 .mp3,因为文件格式只是一堆帧,其中包含播放器播放文件所需的所有内容。您可能会注意到导出的文件中缺少所有 id3 信息。
.m4a 音频文件是包装 aac 音频数据的容器。您仅收到音频数据,没有进一步的信息,即采样率或搜索表。
解决您的问题的方法可能是使用 AVAssetExportSession 将 AVAssetTrack 导出到手机上的文件并从那里流式传输文件。我确实尝试了这一点,并编写了一个有效的 .m4a 文件。
以下代码基于苹果示例如何导出修剪后的音频资源 http://developer.apple.com/library/ios/#qa/qa1730/_index.html:
// 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);
}
}];
该解决方案的缺点是,必须将 while 文件写入磁盘。我仍在寻找更好的方法来处理 .m4a 文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)