2012-07-19 71 views
1

我正在使用this教程將音樂庫中的歌曲傳到我指定的目錄。它對我來說工作正常,但其他人報告說,這首歌永遠不會到達那裏。起初我認爲有設備限制,但似乎與我具有相同設備的人有問題。這有點令人討厭,因爲我無法重現他們的問題。AVAssetReader/Writer只能在某些設備上工作?

這裏是我的代碼:

{ 
    NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL]; 
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil]; 

    NSError *assetError = nil; 
    AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset 
                   error:&assetError] 
            retain]; 
    if (assetError) { 
     NSLog (@"error: %@", assetError); 
     return; 
    } 

    AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput 
               assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks 
               audioSettings: nil] 
               retain]; 
    if (! [assetReader canAddOutput: assetReaderOutput]) { 
     NSLog (@"can't add reader output... die!"); 
     return; 
    } 
    [assetReader addOutput: assetReaderOutput]; 


    NSString *exportPath = @"Library/PreferenceBundles/MyAlarmSettings.bundle/export.m4a"; 
    if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) { 
     [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil]; 
    } 

    NSURL *exportURL = [NSURL fileURLWithPath:exportPath]; 
    AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportURL 
                  fileType:AVFileTypeAppleM4A 
                   error:&assetError] 
            retain]; 
    if (assetError) { 
     NSLog (@"error: %@", assetError); 
     return; 
    } 
    AudioChannelLayout channelLayout; 
    memset(&channelLayout, 0, sizeof(AudioChannelLayout)); 
    channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; 

    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
            [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey, 
            [ NSNumber numberWithInt: 2 ], AVNumberOfChannelsKey, 
            [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, 
            [ NSData dataWithBytes:&channelLayout length: sizeof(AudioChannelLayout) ], AVChannelLayoutKey, 
            [ NSNumber numberWithInt: 320000 ], AVEncoderBitRateKey, 
            nil];     


    AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio 
                       outputSettings:outputSettings] 
              retain]; 
    if ([assetWriter canAddInput:assetWriterInput]) { 
     [assetWriter addInput:assetWriterInput]; 
    } else { 
     NSLog (@"can't add asset writer input... die!"); 
     return; 
    } 

    assetWriterInput.expectsMediaDataInRealTime = NO; 

    [assetWriter startWriting]; 
    [assetReader startReading]; 

    AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0]; 
    CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale); 
    [assetWriter startSessionAtSourceTime: startTime]; 

    __block UInt64 convertedByteCount = 0; 

    dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL); 
    [assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue 
              usingBlock:^
    { 
     // NSLog (@"top of block"); 
     while (assetWriterInput.readyForMoreMediaData) { 
      CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer]; 
      if (nextBuffer) { 
       // append buffer 
       [assetWriterInput appendSampleBuffer: nextBuffer]; 
       //    NSLog (@"appended a buffer (%d bytes)", 
       //     CMSampleBufferGetTotalSampleSize (nextBuffer)); 
       convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer); 
       // oops, no 
       // sizeLabel.text = [NSString stringWithFormat: @"%ld bytes converted", convertedByteCount]; 

       NSNumber *convertedByteCountNumber = [NSNumber numberWithLong:convertedByteCount]; 
       [self performSelectorOnMainThread:@selector(updateSizeLabel:) 
             withObject:convertedByteCountNumber 
            waitUntilDone:NO]; 
      } else { 
       // done! 

       NSString *songtitle = [[NSString alloc]initWithFormat:@"Alarm sound set to '%@' \n \n Press OK to respring. ",[song valueForProperty:MPMediaItemPropertyTitle]]; 

       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Done!" message:songtitle delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
       [alert show]; 
       [alert release]; 



       [assetWriterInput markAsFinished]; 
       [assetWriter finishWriting]; 
       [assetReader cancelReading]; 
       NSDictionary *outputFileAttributes = [[NSFileManager defaultManager] 
                 attributesOfItemAtPath:exportPath 
                 error:nil]; 
       NSLog (@"done. file size is %llu", 
         [outputFileAttributes fileSize]); 
       NSNumber *doneFileSize = [NSNumber numberWithLong:[outputFileAttributes fileSize]]; 
       [self performSelectorOnMainThread:@selector(updateCompletedSizeLabel:) 
             withObject:doneFileSize 
            waitUntilDone:NO]; 
       // release a lot of stuff 


       [assetReader release]; 
       [assetReaderOutput release]; 
       [assetWriter release]; 
       [assetWriterInput release]; 
       [exportPath release]; 
       break; 
      } 
     } 

    }]; 

    NSLog (@"bottom of convertTapped:"); 
} 
+0

你能對你的意思是「什麼闡述這首歌永遠不會有「?我知道用戶可以是非特定的,但如果還有什麼可以告訴我們關於症狀的信息,那將會有所幫助。謝謝。 – Nate 2012-07-20 22:48:02

+0

喜歡這首歌永遠不會被導出到我想要的路徑。對我來說,它工作正常,並在Library/PreferenceBundles/MyAlarmSettings.bundle /我找到音頻文件,但對於其他一些export.m4a不存在。無論如何,我現在正在使用一種新方法,所以我不在乎。 – Fire30 2012-07-21 02:24:04

回答

1

如果您正在訪問來自用戶的iPod庫mediaItems他們也許在雲中。使用

[self.mediaItem valueForProperty:MPMediaItemPropertyIsCloudItem]

據我知道你不能訪問這些資產,或迫使他們流

相關問題