AVAssetResourceLoader's dataRequest requestedLength

We are trying to implement custom decryption of an AVPlayerItem. We use AVAssetResourceLoaderDelegate for manual request to the server which has byte range support. First request which we intercepts in the resource loader is contentInformationRequest, and second and the third one are dataRequests. First dataRequest contains requestedLength of 65536 B and if we manually forward it to the server we gets 65536 B as expected. We than return that data to the resourceLoader and finish loadingRequest. When next dataRequest comes to the resourceLoader delegate, it contains requestedLength for the entire remaining length of the resource. Why resourceLoader set requestedLength to the entire remaining length of the resource? (prior to second data request, requestsAllDataToEndOfResource becomes true)



First dataRequest
current offset: 0, requested length: 65536, requested offset 0

request: Optional(["Accept": "*/*", "Range": "bytes=0-65535"])
 { URL: http://cdn.blabla.com/HRA040827496/v01/HRA040827496.mp3 } { Status Code: 206, Headers {
    "Cache-Control" =     (
        "max-age=7776000"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        65536
    );
    "Content-Range" =     (
        "bytes 0-65535/9828342"
    );
    "Content-Type" =     (
        "audio/mpeg"
    );
    Date =     (
        "Fri, 09 Nov 2018 12:04:17 GMT"
    );
    Etag =     (
        "\"5ae2f3b4-95f7f6\""
    );
    Expires =     (
        "Thu, 07 Feb 2019 12:04:17 GMT"
    );
    "Last-Modified" =     (
        "Fri, 27 Apr 2018 09:56:04 GMT"
    );
    Server =     (
        "nginx/1.10.2"
    );
} }


Second dataRequest
current offset: 65536, requested length: 9762806, requested offset 65536

request: Optional(["Accept": "*/*", "Range": "bytes=65536-9828341"])
 { URL: http://cdn.blabla.com/HRA040827496/v01/HRA040827496.mp3 } { Status Code: 206, Headers {
    "Cache-Control" =     (
        "max-age=7776000"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        9762806
    );
    "Content-Range" =     (
        "bytes 65536-9828341/9828342"
    );
    "Content-Type" =     (
        "audio/mpeg"
    );
    Date =     (
        "Fri, 09 Nov 2018 12:04:18 GMT"
    );
    Etag =     (
        "\"5ae2f3b4-95f7f6\""
    );
    Expires =     (
        "Thu, 07 Feb 2019 12:04:18 GMT"
    );
    "Last-Modified" =     (
        "Fri, 27 Apr 2018 09:56:04 GMT"
    );
    Server =     (
        "nginx/1.10.2"
    );
} }

Replies

I'm not sure why you think this behavior is wrong.


Here is the documentation for AVAssetResourceLoadingDataRequest:


https://developer.apple.com/documentation/avfoundation/avassetresourceloadingdatarequest


It says:


"[T]he resource loading delegate is informed of the range of bytes within the resource that are required by the underlying media system. In response, the data is provided by one or more invocations of respond(with:) as required to provide the requested data. The data can be provided in increments determined by the resource loading delegate according to convenience or efficiency."


In other words, you don't have to provide all 9762806 bytes of the last request at once. Download and decode it in chunks of whatever size you want, and pass them back to the resource loader as you finish with each one.

No I don't think it's wrong behaviour. I know I can request (download) chunks of data by manually set byte range in dataRequest, and it's working exactly as that. But problem is that I should "hardcode" some chunk value which I want to download and use it in every dataRequest. And I don't want to do this way because I want to request chunks of data in consider of network speed (E, 3G, LTE). I expect AVPlayer does this network magic in background, so I don't need to do this by myself. I conceive that requestedLength in dataRequest is value which AVPlayer calculates by network speed and other parameters.. Obviously I misunderstood something.