AVAssetResourceLoaderDelegate: solo solicita los primeros dos bytes?

Estoy implementando un AVAssetResourceLoaderDelegate , y estoy teniendo problemas para llegar a comportarme correctamente. Mi objective es interceptar cualquier request realizada por AVPlayer, hacer la request yo mismo, escribir los datos en un file y luego responder a AVPlayer con los datos del file.

El problema que estoy viendo : puedo interceptar la primera request, que solo está pidiendo dos bytes, y responder a ella. Después de eso, no recibo más requestes que golpeen mi AVAssetResourceLoaderDelegate .

Cuando intercepto la primera AVAssetResourceLoadingRequest del AVPlayer se ve así:

 <AVAssetResourceLoadingRequest: 0x17ff9e40, URL request = <NSMutableURLRequest: 0x17f445a0> { URL: fakeHttp://blah.com/blah/blah.mp3 }, request ID = 1, content information request = <AVAssetResourceLoadingContentInformationRequest: 0x17ff9f30, content type = "(null)", content length = 0, byte range access supported = NO, disk caching permitted = NO>, data request = <AVAssetResourceLoadingDataRequest: 0x17e0d220, requested offset = 0, requested length = 2, current offset = 0>> 

Como puede ver, esta es solo una request para los primeros dos bytes de datos. Estoy tomando el protocolo fakeHttp en la URL, reemplazándolo con solo http , y haciendo la request yo mismo.

Entonces, así es como respondo a la request una vez que tengo algunos datos:

 - (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest { //Make the remote URL request here if needed, omitted CFStringRef contentType = UTTypeCreatePrefernetworkingIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)([self.response MIMEType]), NULL); loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES; loadingRequest.contentInformationRequest.contentType = CFBridgingRelease(contentType); loadingRequest.contentInformationRequest.contentLength = [self.response expectedContentLength]; //Where responseData is the appropriate NSData to respond with [loadingRequest.dataRequest respondWithData:responseData]; [loadingRequest finishLoading]; return YES; } 

Pasé esto y comprobé que todo en contentInformationRequest se ha completado correctamente y que los datos que estoy enviando son NSData con la longitud adecuada (en este caso, dos bytes).

No se envían más requestes a mi delegado y el jugador no juega (presumiblemente porque solo tiene dos bytes de datos y no ha solicitado más).

¿Alguien tiene experiencia con esto para apuntarme hacia un área en la que pueda estar haciendo algo mal? Estoy ejecutando iOS 7.

Editar: Aquí se ve cómo se ve mi request completa, después de que finishedLoading :

 <AVAssetResourceLoadingRequest: 0x16785680, URL request = <NSMutableURLRequest: 0x166f4e90> { URL: fakeHttp://blah.com/blah/blah.mp3 }, request ID = 1, content information request = <AVAssetResourceLoadingContentInformationRequest: 0x1788ee20, content type = "public.mp3", content length = 7695463, byte range access supported = YES, disk caching permitted = NO>, data request = <AVAssetResourceLoadingDataRequest: 0x1788ee60, requested offset = 0, requested length = 2, current offset = 2>> 

 - (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest { loadingRequest.contentInformationRequest.contentType = @"public.aac-audio"; loadingRequest.contentInformationRequest.contentLength = [self.fileData length]; loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES; NSData *requestedData = [self.fileData subdataWithRange:NSMakeRange((NSUInteger)loadingRequest.dataRequest.requestedOffset, (NSUInteger)loadingRequest.dataRequest.requestedLength)]; [loadingRequest.dataRequest respondWithData:requestedData]; [loadingRequest finishLoading]; return YES; } 

Esta implementación funciona para mí. Siempre pide los dos primeros bytes y luego los datos completos. Si no obtiene otra callback, significa que hubo algo incorrecto con la primera respuesta que ha realizado. Creo que el problema es que está utilizando el tipo de contenido MIME en lugar de UTI.

Dando vueltas para responder a mi propia pregunta en caso de que alguien tuviera curiosidad.

El problema se networkingucía a subprocesss. Aunque no está explícitamente documentado en ninguna parte, AVAssetResourceLoaderDelegate hace cosas raras con hilos.

Básicamente, mi problema era que estaba creando AVPlayerItem y AVAssetResourceLoaderDelegate en el hilo principal, pero respondiendo a las llamadas de delegado en un hilo de background (ya que eran el resultado de llamadas de networking). Al parecer, AVAssetResourceLoader ignora por completo las respuestas que entran en un hilo diferente de lo que esperaba.

AVPlayerItem esto simplemente haciendo todo, incluida la creación de AVPlayerItem , en el mismo hilo.