Datos de canciones sin procesar de MPMediaItems

Me preguntaba cómo acceder a los datos brutos de un MPMediaItem.

¿Algunas ideas?

puede obtener los datos del elemento de medios de esa manera:

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

Este código solo funcionará en ios 4.0 y posterior

¡Buena suerte!

Por supuesto, puede acceder a los datos de un MPMediaItem . No es claro como el cristal de una vez, pero funciona. Así es cómo:

  • Obtener la URL del elemento multimedia de su propiedad MPMediaItemPropertyAssetURL
  • Inicializa un AVURLAsset con esta URL
  • Inicializar un AVAssetReader con este activo
  • AVAssetTrack el AVAssetTrack que desea leer desde el AVURLAsset
  • Crea un AVAssetReaderTrackOutput con esta pista
  • Agregue esta salida al AVAssetReader creado antes y -startReading
  • Obtenga todos los datos con AVAssetReaderTrackOutput ‘s -copyNextSampleBuffer
  • ¡LUCRO!

Aquí hay un código de muestra de un proyecto mío (esta no es una joya del código, la escribí hace algún tiempo en mi encoding de las edades oscuras):

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

No puedes, y no hay ninguna solución. Un MPMediaItem no es la pieza de medios real, solo son los metadatos sobre el elemento multimedia comunicado a la aplicación a través de RPC desde otro proceso. No se puede acceder a los datos del artículo en su espacio de direcciones.

Debo señalar que incluso si tiene el MPMediaItem, sus datos probablemente no se carguen en la memoria del dispositivo. El flash en el iPhone es lento y la memoria escasa. Si bien es posible que Apple no quiera que tenga acceso a los datos brutos que respaldan un MPMediaItem, es muy probable que no se hayan molestado en tratar con él porque no quisieron invertir el tiempo necesario para manejar las API. Si proporcionan acceso a tal cosa, es casi seguro que no será como un NSData, sino más bien como un NSURL que le daría a su aplicación que le permitiría abrir el archivo y transmitir a través de los datos.

En cualquier caso, si desea la funcionalidad, debe presentar un informe de error solicitando.

Además, como nota al margen, no menciones tu edad en un informe de error que envías a Apple. Creo que es genial que estés escribiendo aplicaciones para el teléfono, cuando tenía tu edad me encantaba experimentar con las computadoras (en aquel entonces estaba trabajando en cosas escritas en Lisp). Lo que ocurre es que no puede aceptar un contrato legal en los Estados Unidos, por lo que el acuerdo de desarrollador le prohíbe expresamente unirse. Del primer párrafo del acuerdo :

También certifica que es mayor de edad en la jurisdicción en la que reside (por lo menos 18 años de edad en muchos países) y declara que está legalmente autorizado a convertirse en Desarrollador de iPhone registrado.

Si menciona a un representante de WWDR que no tiene la mayoría de edad, es posible que se dé cuenta de que está infringiendo el acuerdo y se verá obligado a cancelar su cuenta de desarrollador. Solo una amistosa advertencia.