2012-05-11 33 views
3

因此,我面對的是一個非常奇怪,奇怪的問題,並想知道是否有人遇到這個問題。我從手機音樂庫抓取MPMediaItem的原始數據,然後通過HTTP將其發送到別處播放。當我從一個類型爲.m4a的文件中抓取原始數據時,我的問題就出現了,它似乎缺少一些部分。例如,如果我從itunes中檢查的原始文件是7.4mb,那麼從我的代碼中得到的內容大小爲7.3mb。我已經做了一些研究,發現.m4a文件實際上是一個封裝,我認爲我沒有獲得原始音樂數據的封裝,因此它不可識別。這裏是我的代碼,讓我的原始音樂數據從MPMediaItem.m4a的原始數據不打

    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]; 

我做,會得到對於那些在手機圖書館,但是當涉及到.M4A這似乎是.mp3文件的正確性缺少一些部分。再次

感謝你的時間來幫助我。

回答

1

我遇到了同樣的問題。 AVAssetReader僅返回原始音頻數據。它適用於.mp3,因爲文件格式只是一堆包含播放器播放文件所需的所有內容的幀。您可能會注意到導出的文件中缺少所有id3信息。

的.m4a音頻文件容器周圍的AAC音頻數據包。您只收到音頻數據,而沒有進一步的信息,即採樣率或查找表。

用於你的問題的解決方法可能是使用一個AVAssetExportSession到AVAssetTrack導出到文件在手機上,並從那裏流的文件。我嘗試了這一點,並編寫了一個工作的.m4a文件。

下面的代碼是基於Apples example how to export a trimmed audio asset

// 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); 
    } 
}]; 

這種解決方案的缺點是,該文件的同時必須在磁盤上寫入。我仍然在尋找更好的方式來處理.m4a文件。

+0

這是我最終沒有,不知道是否有避免寫入磁盤的方式。 – Krzemienski

+0

@melle,我實現了你的解決方案,它包含了標題信息,但是當我使用AmazonS3Client上傳到s3時,我遇到了一個數據只是不上載的問題。有任何想法嗎?原始標題中是否有可阻止其上傳的內容? – user592419

+0

對不起,我不知道Amazons客戶端可能會出現什麼問題。您應該將導出會話中的文件與同步到iOS設備的原始文件進行比較。 – melle