risposta

29

è possibile ottenere i dati del elemento multimediale in modo tale:

-(void)mediaItemToData 
{ 
    // Implement in your project the media item picker 

    MPMediaItem *curItem = musicPlayer.nowPlayingItem; 

    NSURL *url = [curItem valueForProperty: MPMediaItemPropertyAssetURL]; 

    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil]; 

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset 
             presetName: AVAssetExportPresetPassthrough]; 

    exporter.outputFileType = @"public.mpeg-4"; 

    NSString *exportFile = [[self myDocumentsDirectory] stringByAppendingPathComponent:   
                   @"exported.mp4"]; 

    NSURL *exportURL = [[NSURL fileURLWithPath:exportFile] retain]; 
    exporter.outputURL = exportURL; 

    // do the export 
    // (completion handler block omitted) 
    [exporter exportAsynchronouslyWithCompletionHandler: 
    ^{ 
    NSData *data = [NSData dataWithContentsOfFile: [[self myDocumentsDirectory] 
            stringByAppendingPathComponent: @"exported.mp4"]]; 

    // Do with data something 

    }]; 
} 

Questo codice funziona solo su iOS 4.0 e versioni successive

Buona fortuna!

+0

i prova questo codice in ios 4.0 ma non funziona qui sotto è la fonte del codice – GhostRider

+0

Questa soluzione è molto complicata, dai uno sguardo al mio qui sotto (non hai bisogno di una sessione di esportazione per questo). –

+0

ottenere null in nsdata – Rajneesh071

-3

Non è possibile e non ci sono soluzioni alternative. Un MPMediaItem non è il vero supporto, sono solo i metadati relativi all'elemento multimediale comunicato all'applicazione tramite RPC da un altro processo. I dati per l'oggetto stesso non sono accessibili nello spazio degli indirizzi.

Si noti che anche se si dispone di MPMediaItem, i suoi dati probabilmente non vengono caricati nella memoria del dispositivo. Il flash su iPhone è lento e la memoria è scarsa. Mentre Apple potrebbe non volere che tu abbia accesso ai dati grezzi che supportano un MPMediaItem, è altrettanto probabile che non si siano preoccupati di gestirli perché non volevano investire il tempo necessario per gestire le API. Se fornissero l'accesso a una cosa del genere, quasi certamente non sarebbe come un NSData, ma più probabilmente come un NSURL daranno all'applicazione che gli consentirebbe di aprire il file e lo streaming attraverso i dati.

In ogni caso, se si desidera la funzionalità, è necessario fornire una segnalazione di errore a file.

Inoltre, come nota a margine, non menzionare la tua età in una segnalazione di bug che invii ad Apple. Penso che sia molto bello che tu stia scrivendo app per il telefono, quando avevo la tua età amavo sperimentare con i computer (a quei tempi stavo lavorando su cose scritte in Lisp). Il fatto è che non è possibile accettare legalmente un contratto negli Stati Uniti, motivo per cui l'accordo degli sviluppatori vieta espressamente di aderire. Dal primo paragrafo della agreement:

Si attesta, inoltre, che vi sono delle maggiore età nel giurisdizione in cui risiede (ad almeno 18 anni in molti paesi) e si rappresenta che tu sono legalmente autorizzati a diventare uno sviluppatore iPhone registrato .

Se si parla di un rappresentante WWDR che non ha raggiunto la maggiore età, potrebbe rendersi conto che si sta violando l'accordo ed essere obbligato a chiudere il proprio account sviluppatore. Solo un avvertimento amichevole.

+3

Mio padre ha fatto tutto questo e tecnicamente, è lo sviluppatore dell'iPhone, quindi è tutto ok – conradev

+0

Potrebbe essere stato corretto al momento della scrittura (2009). Ma ora nel 2017 c'è un'API per questo e la risposta è almeno obsoleta (se fosse corretta nel 2009: non sono uno storico delle previsioni, non ricordo se c'era una AVAssetExportSession nel novembre 2009) –

18

Naturalmente è possibile accedere ai dati di un MPMediaItem. Non è cristallino allo stesso tempo, ma funziona.Ecco come:

  • ottenere l'URL del elemento multimediale da esso è MPMediaItemPropertyAssetURL proprietà
  • inizializzare un AVURLAsset con questo URL
  • inizializzare un AVAssetReader con questo asset
  • Fetch la AVAssetTrack che si desidera leggere dal AVURLAsset
  • Creare un con questa traccia
  • Aggiungi questo output a AVAssetReader creato prima e -startReading
  • recuperare tutti i dati con AVAssetReaderTrackOutput s' -copyNextSampleBuffer
  • UTILE!

Ecco alcuni esempi di codice da un mio progetto (non si tratta di un gioiello di codice di mine, l'ha scritto qualche tempo fa nei miei codifica secoli bui):

typedef enum { 
    kEDSupportedMediaTypeAAC = 'aac ', 
    kEDSupportedMediaTypeMP3 = '.mp3' 
} EDSupportedMediaType; 

- (EDLibraryAssetReaderStatus)prepareAsset { 
    // Get the AVURLAsset 
    AVURLAsset *uasset = [m_asset URLAsset]; 

    // Check for DRM protected content 
    if (uasset.hasProtectedContent) { 
    return kEDLibraryAssetReader_TrackIsDRMProtected; 
    } 

    if ([uasset tracks] == 0) { 
    DDLogError(@"no asset tracks found"); 
    return AVAssetReaderStatusFailed; 
    } 

    // Initialize a reader with a track output 
    NSError *err = noErr; 
    m_reader = [[AVAssetReader alloc] initWithAsset:uasset error:&err]; 
    if (!m_reader || err) { 
    DDLogError(@"could not create asset reader (%i)\n", [err code]); 
    return AVAssetReaderStatusFailed; 
    } 

    // Check tracks for valid format. Currently we only support all MP3 and AAC types, WAV and AIFF is too large to handle 
    for (AVAssetTrack *track in uasset.tracks) { 
    NSArray *formats = track.formatDescriptions; 
    for (int i=0; i<[formats count]; i++) { 
     CMFormatDescriptionRef format = (CMFormatDescriptionRef)[formats objectAtIndex:i]; 

     // Check the format types 
     CMMediaType mediaType = CMFormatDescriptionGetMediaType(format); 
     FourCharCode mediaSubType = CMFormatDescriptionGetMediaSubType(format); 

     DDLogVerbose(@"mediaType: %s, mediaSubType: %s", COFcc(mediaType), COFcc(mediaSubType)); 
     if (mediaType == kCMMediaType_Audio) { 
     if (mediaSubType == kEDSupportedMediaTypeAAC || 
      mediaSubType == kEDSupportedMediaTypeMP3) { 
      m_track = [track retain]; 
      m_format = CFRetain(format); 
      break; 
     } 
     } 
    } 
    if (m_track != nil && m_format != NULL) { 
     break; 
    } 
    } 

    if (m_track == nil || m_format == NULL) { 
    return kEDLibraryAssetReader_UnsupportedFormat; 
    } 

    // Create an output for the found track 
    m_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:m_track outputSettings:nil]; 
    [m_reader addOutput:m_output]; 

    // Start reading 
    if (![m_reader startReading]) { 
    DDLogError(@"could not start reading asset"); 
    return kEDLibraryAssetReader_CouldNotStartReading; 
    } 

    return 0; 
} 

- (OSStatus)copyNextSampleBufferRepresentation:(CMSampleBufferRepresentationRef *)repOut { 
    pthread_mutex_lock(&m_mtx); 

    OSStatus err = noErr; 
    AVAssetReaderStatus status = m_reader.status; 

    if (m_invalid) { 
    pthread_mutex_unlock(&m_mtx); 
    return kEDLibraryAssetReader_Invalidated; 
    } 
    else if (status != AVAssetReaderStatusReading) { 
    pthread_mutex_unlock(&m_mtx); 
    return kEDLibraryAssetReader_NoMoreSampleBuffers; 
    } 

    // Read the next sample buffer 
    CMSampleBufferRef sbuf = [m_output copyNextSampleBuffer]; 
    if (sbuf == NULL) { 
    pthread_mutex_unlock(&m_mtx); 
    return kEDLibraryAssetReader_NoMoreSampleBuffers; 
    } 

    CMSampleBufferRepresentationRef srep = CMSampleBufferRepresentationCreateWithSampleBuffer(sbuf); 
    if (srep && repOut != NULL) { 
    *repOut = srep; 
    } 
    else { 
    DDLogError(@"CMSampleBufferRef corrupted"); 
    EDCFShow(sbuf); 
    err = kEDLibraryAssetReader_BufferCorrupted; 
    } 
    CFRelease(sbuf); 

    pthread_mutex_unlock(&m_mtx); 

    return err; 
} 
+0

Avete un codice di esempio di questo metodo? – coder

+0

Aggiornato con il codice di esempio –

+0

@ErikAigner sono in grado di elencare i brani in nslog utilizzando Media Picker .. Ma voglio riprodurre quei brani con il mio lettore (Codificato utilizzando Avplayer). Come posso riprodurre entrambe le canzoni – NextStep