.m4a来自iPod库的原始数据无法播放 [英] .m4a raw data from iPod Library not playing

查看:135
本文介绍了.m4a来自iPod库的原始数据无法播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我面临一个非常奇怪和奇怪的问题,并且想知道是否还有其他人遇到过此问题.我正在从手机音乐库中的MPMediaItem中获取原始数据,然后通过HTTP发送出去以在其他地方播放.问题出在哪里,当我从.m4a类型的文件中获取原始数据时,它似乎丢失了.例如,如果我从itunes检查的原始文件为7.4mb,那么从我的代码中获取的文件的大小为7.3mb.我已经进行了一些研究,发现.m4a文件实际上是封装文件,我认为我没有得到仅是原始音乐数据的文件封装文件,因此无法识别.这是我的代码,该代码为我提供了MPMediaItem中的原始音乐数据

So I am faced with a very weird and strange problem and was wondering if anyone else has come across this issue. I am grabbing the raw data from MPMediaItem from the phones music library and then sending it out via HTTP to be played elsewhere. Where my issue is arising is when I am grabbing the raw data from a file of type .m4a it seems to be missing pieces. For example if the original file that I check from itunes is 7.4mb what ill get from my code is of size 7.3mb. Ive done some research and found that a .m4a file is actually an encapsulation and I think I am not getting the encapsulation of the file just the raw music data so therefor it is non recognizable. Here is my code that gives me the raw music data from the 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时,似乎缺少了某些部分.

I do and will get the correct data for .mp3 files that are in the phones library but when it comes to .m4a it seems to be missing some parts.

再次感谢您抽出宝贵的时间来帮助我.

Thanks again for taking your time to help me out.

推荐答案

我遇到了同样的问题. AVAssetReader仅返回原始音频数据.它适用于.mp3,因为文件格式只是一堆帧,其中包含播放器播放文件所需的所有内容.您可能会注意到,导出的文件中缺少所有id3信息.

I ran into the same problem. AVAssetReader returns only the raw audio data. It works for .mp3 because the file format is just a bunch of frames that contain everything a player needs to playback the file. You may note that all of the id3 information is missing in the exported file.

.m4a音频文件是包装aac音频数据的容器.您仅接收了音频数据,没有进一步的信息,例如采样率或查找表.

.m4a audio files are containers that wrap around aac audio data. You received only the audio data, without further information i.e. samplerate or the seek-table.

解决此问题的方法可能是使用AVAssetExportSession将AVAssetTrack导出到手机上的文件并从那里流式传输文件.我正好尝试了这一点,并编写了一个有效的.m4a文件.

A workaround for your problem could be to use an AVAssetExportSession to export the AVAssetTrack to a file on the phone and stream the file from there. I tried exactly this and a working .m4a file was written.

以下代码基于 Apples示例如何导出修剪的音频资产:

// 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文件.

The downside of this solution is, that the while file had to be written on the disk. I'm still searching for a better way to handle .m4a files.

这篇关于.m4a来自iPod库的原始数据无法播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆