iphone - informacion - itunes online sin descargar
MPMediaItems datos de canciones en bruto (3)
Me preguntaba cómo acceder a los datos en bruto de un MPMediaItem.
¿Algunas ideas?
No puedes, y no hay solución. Un MPMediaItem no es la pieza real de los medios, son solo los metadatos sobre el elemento de medios comunicado a la aplicación a través de RPC desde otro proceso. Los datos para el artículo en sí no son accesibles en su espacio de direcciones.
Debo tener en cuenta que incluso si tiene el MPMediaItem, es probable que sus datos no estén cargados en la memoria del dispositivo. El flash en el iPhone es lento y la memoria es escasa. Si bien es posible que Apple no quiera que usted tenga acceso a los datos en bruto que respaldan un MPMediaItem, es muy probable que no se molesten en tratar con ellos porque no quieren invertir el tiempo necesario para lidiar con las API. Si proporcionaran acceso a tal cosa, es casi seguro que no sería como un NSData, sino más bien como un NSURL darían a su aplicación que le permitiría abrir el archivo y transmitirlo a través de los datos.
En cualquier caso, si desea la funcionalidad, debe file un informe de error solicitando.
Además, como nota al margen, no mencione su edad en un informe de error que envíe a Apple. Creo que es genial que escribas aplicaciones para el teléfono, cuando tenía tu edad, me encantaba experimentar con computadoras (en ese entonces estaba trabajando en cosas escritas en Lisp). La cosa es que no puede aceptar legalmente un contrato en los Estados Unidos, razón por la cual el acuerdo de desarrollador le prohíbe específicamente unirse. Del primer párrafo del agreement :
También certifica que tiene la mayoría de edad legal en la jurisdicción en la que reside (al menos 18 años en muchos países) y declara que está legalmente autorizado para convertirse en un Desarrollador de iPhone registrado.
Si menciona a un representante de WWDR que no es mayor de edad, pueden darse cuenta de que está violando el acuerdo y estar obligado a cancelar su cuenta de desarrollador. Sólo una advertencia amistosa.
Por supuesto que puede acceder a los datos de un MPMediaItem
. No es muy claro a la vez, pero funciona. Así es cómo:
- Obtenga la URL del elemento multimedia desde su propiedad
MPMediaItemPropertyAssetURL
- Inicializa un
AVURLAsset
con esta URL - Inicialice un
AVAssetReader
con este activo -
AVAssetTrack
elAVAssetTrack
que desea leer delAVURLAsset
- Cree 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 ejemplo de un proyecto mío (esto no es un código mío mío, lo escribí hace algún tiempo en mis edades oscuras de codificación):
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;
}
Puede obtener los datos del elemento de medios de esta 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 versiones posteriores
¡Buena suerte!