Необработанные данные .m4a из библиотеки iPod не воспроизводятся

Итак, я столкнулся с очень странной и странной проблемой, и мне было интересно, сталкивался ли кто-нибудь еще с этой проблемой. Я беру необработанные данные из MPMediaItem из музыкальной библиотеки телефона, а затем отправляю их через HTTP для воспроизведения в другом месте. Моя проблема возникает, когда я беру необработанные данные из файла типа .m4a, кажется, что отсутствуют части. Например, если исходный файл, который я проверяю из iTunes, имеет размер 7,4 МБ, то, что я получу из моего кода, имеет размер 7,3 МБ. Я провел некоторое исследование и обнаружил, что файл .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, в нем, похоже, отсутствуют некоторые части.

Еще раз спасибо, что нашли время, чтобы помочь мне.


person Krzemienski    schedule 11.05.2012    source источник


Ответы (1)


Я столкнулся с той же проблемой. AVAssetReader возвращает только необработанные аудиоданные. Это работает для .mp3, потому что формат файла — это просто набор кадров, содержащих все, что нужно проигрывателю для воспроизведения файла. Вы можете заметить, что вся информация id3 отсутствует в экспортированном файле.

Аудиофайлы .m4a представляют собой контейнеры, в которые помещаются аудиоданные формата aac. Вы получили только аудиоданные, без дополнительной информации, т.е. частоты дискретизации или таблицы поиска.

Обходной путь для вашей проблемы может заключаться в использовании AVAssetExportSession для экспорта AVAssetTrack в файл на телефоне и потоковой передачи файла оттуда. Я пробовал именно это и был написан рабочий файл .m4a.

Следующий код основан на примере Apple, как экспортировать обрезанный аудиоресурс< /а>:

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

person melle    schedule 01.02.2013
comment
Это то, что я в конце концов сделал, не уверенный, есть ли способ избежать записи на диск. - person Krzemienski; 20.02.2013
comment
@melle, я реализовал ваше решение, и теперь оно включает информацию заголовка, но когда я перехожу к загрузке на s3 с помощью AmazonS3Client, я сталкиваюсь с проблемой, когда данные просто не загружаются. Любые идеи? Может в исходном шапке что-то мешает загрузить? - person user592419; 02.05.2013
comment
Извините, я понятия не имею, в чем может быть проблема с клиентом Amazon. Вы должны сравнить файл из сеанса экспорта с исходным файлом, который был синхронизирован с вашим устройством iOS. - person melle; 06.05.2013