AVPLAyeri allalaaditud andmete vahemälu vahemällu salvestamine

tl; dr
Kui soovite lihtsalt lahendust, vaadake minu loodud teeki. Selles artiklis selgitan rakendamist.

Nõuded

Meie rakenduses koosneb sisuvoog peamiselt piltidest ja videost. Piltide vahemällu salvestamiseks kasutame SDWebImage. Videote jaoks laadime video kõigepealt alla täielikult ja siis algab taasesitus. See lähenemisviis töötab lühikeste videote puhul, kuid pikemate videote jaoks võib kogu faili allalaadimine enne taasesituse algust võtta tohutult palju aega, isegi WiFi-ühenduse korral.

Lähenemisviisid

Minu esimene idee oli AVAsset-objektide salvestamine mudelikihti. See töötab sama rakenduse seansi jooksul (AVPlayer ei laadi sama faili mitu korda), kuid rakenduse seansside vahel ei tööta.

Seejärel proovisin AVAsset teisendada NSData-ks AVAssetExportSession abil. Ekspordiseanss toimis kohalike failide korral hästi, kuid proovisin kaug-URL-iga loodud AVURLAssetti eksportida alati veateatega:

Vea domeen = AVFoundationErrorDomain Code = -11800 “Toimingut ei õnnestunud lõpule viia” UserInfo = {NSLocalizedFailureReason = Tundmatu viga (-16974), NSLocalizedDescription = Toimingut ei saanud lõpule viia, NSUnderlyingError = 0x60000025a940 {Error Domain = NSOSSDtat 16974 “(null)”}}

Kolmas lahendus oli kasutada AVURLAsset'i ressursiLoader omadust. See lahendus töötas minu jaoks, kuid selle rakendamisel leidsin palju probleeme.

Rakendamine

Vastavalt Apple'i dokumentatsioonile:

AVAssetResourceLoader vahendab AVURLAssetis nõutavate ressursside laadimise taotlusi, paludes volitatud objektilt teie abi. Kui on vaja ressurssi, mida AVURLAsset ise ei saa laadida, nõuab ressursi laadur oma delegaadilt selle laadimist ja jätkub vastavalt delegaadi vastusele.

Niisiis, esimene asi, mida peate tegema, on veenduda, et AVURLAsset ei saa andmeid ise laadida, ja kutsub selle asemel iga päringu jaoks ressursi laadija. Selle saavutamiseks võite asendada AVURLAsset URL-i HTTP (S) skeemi mõne kohandatud skeemiga. Ärge unustage originaalskeemi kuskile salvestada; vajate seda hiljem.

NSURLComponents * components = [[NSURLComponents alloc] initWithURL: URL resolvingAgainstBaseURL: NO]; komponendid.scheme = @ “tollimoodul”; AVURLAsset * vara = [[AVURLAsset alloc] initWithURL: [komponentide URL] suvandid: suvandid];

Kui ressursilaadur ei saa päringut ise laadida, kutsub ta delegaadi meetodit:

- (BOOL) ressursi laadija: (AVAssetResourceLoader *) ressursi laadija peaksWaitForLoadingOfRequestedResource: (AVAssetResourceLoadingRequest *) loadingRequest;

Kui selle meetodi järgi JAH naasete, ütleb ressursilaadur, et vastutate selle päringu laadimise eest. NO tagastamise korral ilmneb AVURLAssetis tõrge, kuna ei ressursi laadija ega volitatud ei saa seda taotlust laadida.

Sellest hetkest alates töötate argumendiga AVAssetResourceLoadingRequest. Saate andmeid laadida sünkroonselt või asünkroonselt (ärge unustage laadimistaotlust kuskile salvestada, kui soovite seda teha asünkroonselt). Kui laadimine on lõpule viidud, peaksite sõltuvalt tulemusest helistama kas finishLoading või finishLoadingWithError:

Laadimistaotlusi on kahte tüüpi: andmepäring ja sisuteave. Tüübi määramiseks kontrollige atribuute:

@omadus (mitteatomaatiline, ainult lugemiseks, tühistatav) AVAssetResourceLoadingContentInformationRequest * contentInformationRequest; @property (mitteatomaatiline, ainult lugemiseks, tühistatav) AVAssetResourceLoadingDataRequest * dataRequest;

Sisu teabe päringu korral peaksite vastama sisutüübi (UTI), sisu pikkusega ja vastama, kui baitide vahemiku päist toetatakse. Olen selle laadimistaotluse HTTP HEAD-päringuga rakendanud. Selle teabe saamisel peaksite täitma sisuInformationRequesti atribuudid ja helistama finishLoadingule.

Andmepäringu saamiseks peaksite vastama andmetega, kasutades URL-i, nihke ja dataRequest'i pikkust. Kui otsustate selle ise rakendada, lugege hoolikalt AVAssetResourceLoadingDataRequesti dokumentatsiooni. Olen rakendanud dataRequest HTTP GET ja vahemiku päisega.

Samuti avastasin vahemiku päisega taotluste rakendamisel veidrat käitumist. NSURLSessiooni andmete ülesande taotlus ja vastusevahemikud võivad erineda. See niit kinnitab, et see on viga NSURLCache'is. Vahemiku päist ignoreeritakse NSURLCache'is ja vastuseks võite saada vale andmemahu. Suutsin seda reprodutseerida ainult iOS ≤10 korral.

Peaksite dataRequest täitma laaditud andmetega, kasutades responWithData :. Saate salvestada samad andmed oma vahemällu.

Laaduri täieliku juhendi rakendamise leiate siit. Minu teek AVURLAsset'i vahemällu salvestamiseks on siin. Tutvuge saadaolevate meetodite dokumentatsiooniga. PR- ja funktsioonitaotlused on teretulnud.

Kui see artikkel teile meeldib, ärge unustage plaksutada. Kui soovite, siis võtke mulle joon alla. Sotsiaalsed profiilid tuleks siduda keskmise kontoga. @vdugnist