2011-02-04 19 views
24

Mi aplicación descarga un mp3 de nuestro servidor y lo reproduce para el usuario. El archivo es de 64 kbps (que está dentro del rango aceptable para iPhone si lo entiendo correctamente). He mirado cómo hacer esto en docenas de sitios y todos ellos sugieren que hago exactamente esto:iPhone: tipo de archivo no compatible con AVAudioPlayer

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://.../file.mp3"]]; 
NSError *e = nil; 
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:data error&e]; 
[player setDelegate:self]; 

Cuando ejecuto el código, el jugador vuelve nula y me sale este error:

2011-02-04 10:44:46.176 MyApp[6052:207] Error loading audio: Error Domain=NSOSStatusErrorDomain Code=1954115647 "The operation couldn’t be completed. (OSStatus error 1954115647.)" 
2011-02-04 10:44:49.647 MyApp[6052:207] unsupported file type 

He comprobado el archivo y sé que funciona. Jugará sin problemas en Windows Media Player y Quicktime en Mac. También he subido el archivo al emulador de iPhone y funciona sin problemas. El archivo está bien, pero por alguna razón AVAudioPlayer no le gusta.

¿Hay algo que deba cambiar? ¿Existe algún tipo de ajuste para que NSData especifique qué tipo de archivo es? ¿Alguien tiene alguna idea?

Respuesta

28

¡Por fin he encontrado una solución a este problema! En lugar de inicializar el reproductor de audio con el objeto NSData, ahorré el archivo en la carpeta de documentos y, a continuación, inicializado el jugador con la URL del archivo

//download file and play from disk 
NSData *audioData = [NSData dataWithContentsOfURL:someURL]; 
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
NSString *filePath = [NSString stringWithFormat:@"%@/%@.mp3", docDirPath , fileName]; 
[audioData writeToFile:filePath atomically:YES]; 

NSError *error; 
NSURL *fileURL = [NSURL fileURLWithPath:filePath]; 
player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error]; 
if (player == nil) { 
    NSLog(@"AudioPlayer did not load properly: %@", [error description]); 
} else { 
    [player play]; 
} 

Cuando la aplicación se realiza con el archivo, se puede eliminar. ¡Espero que él ayude más que a mí!

12

Estábamos lidiando con el mismo problema: primero teníamos que escribir el archivo en el disco. Finalmente, descubrí que los datos que estábamos descargando tenían bytes adicionales en blanco al principio. Al leer desde el disco usando initWithContentsOfURL, AVAudioPlayer supo cómo tratar con esto, pero cuando carga desde NSData usando initWithData, no lo hizo. Recortar esos bytes lo solucionó.

+0

Oh, eso es muy interesante. Tal vez eso debería enviarse a Apple como un error? Al final opté por el archivo guardado de todos modos porque encajaba mejor con lo que estábamos tratando de hacer. ¡Gracias por el consejo! – mtmurdock

+2

¿Cómo sabe exactamente qué bytes cortar y cómo lo hizo? – typeoneerror

+2

@typeoneerror: tomé un archivo específico, lo miré con un editor hexadecimal y leí las especificaciones mp3 para ver cómo se definió el encabezado. Fue entonces cuando noté la discrepancia. No muy general, lo sé ... Programáticamente, podría ver los primeros bytes de NSData y omitir cualquiera que sea 0. – Don

1

Si el nombre de su producto contiene espacio, recibirá el error.
El nombre del producto de mi proyecto era: Panorama 1453 TR. El método initWithContentsOfURL no puede recuperar la ruta del archivo. así que no estaba funcionando. puede poner un breakPoint en NSURL *fileURL =. Después de un paso, puede ver los archivos URL que tienen los datos.
Cambié a Panorama1453TR, funcionó.

11

Desde iOS 7 AVAudioPlayer tiene nueva inicializador

NSError *error; 
[[AVAudioPlayer alloc] initWithData:soundData fileTypeHint:AVFileTypeMPEGLayer3 error:&error] 

La UTI apoyado

NSString *const AVFileType3GPP; 
NSString *const AVFileType3GPP2; 
NSString *const AVFileTypeAIFC; 
NSString *const AVFileTypeAIFF; 
NSString *const AVFileTypeAMR; 
NSString *const AVFileTypeAC3; 
NSString *const AVFileTypeMPEGLayer3; 
NSString *const AVFileTypeSunAU; 
NSString *const AVFileTypeCoreAudioFormat; 
NSString *const AVFileTypeAppleM4V; 
NSString *const AVFileTypeMPEG4; 
NSString *const AVFileTypeAppleM4A; 
NSString *const AVFileTypeQuickTimeMovie; 
NSString *const AVFileTypeWAVE; 
+0

gracias. Funcionó. – DHEERAJ

+0

Gracias. ¡Me has ayudado mucho con tu respuesta! – Alexander

+0

Brillante respuesta, gracias! Parece que rescata la solución con iOS 9 de alguna manera ... – Resty

Cuestiones relacionadas