2013-01-15 10 views
9

Sto cercando aiuto con un problema di prestazioni in un'app iOS basata su Objective-C.Come posso registrare lo schermo con prestazioni accettabili pur mantenendo l'interfaccia utente reattiva?

Ho un'applicazione iOS che cattura i contenuti dello schermo utilizzando il metodo renderInContext di CALayer. Tenta di catturare un numero sufficiente di frame per creare un video usando AVFoundation. La registrazione dello schermo viene quindi combinata con altri elementi per scopi di ricerca sull'usabilità. Mentre lo schermo viene acquisito, l'app potrebbe anche visualizzare i contenuti di un UIWebView, uscire dalla rete per recuperare i dati, ecc ... Il contenuto della visualizzazione Web non è sotto il mio controllo: è un contenuto arbitrario del Web.

Questa configurazione funziona ma, come potete immaginare, non è liscia. Dal momento che il livello deve essere reso sul thread principale, c'è più contesa dell'interfaccia utente di quanto vorrei. Quello che mi piacerebbe fare è avere una configurazione in cui la reattività dell'interfaccia utente è prioritaria rispetto alla cattura dello schermo. Ad esempio, se l'utente sta scorrendo la visualizzazione Web, preferisco rilasciare frame sulla registrazione piuttosto che avere un'esperienza di scorrimento terribile.

Ho sperimentato diverse tecniche, da dispatch_source coalescing all'invio delle richieste di acquisizione frame come blocchi alla coda principale a CADisplayLink. Finora sembra che tutti si comportino allo stesso modo. L'acquisizione di fotogrammi viene attualmente attivata nel drawRect della vista principale dello schermo.

Quello che sto chiedendo qui è: dato quanto sopra, quali tecniche suggeriresti di provare a raggiungere i miei obiettivi? Mi rendo conto che la risposta potrebbe essere che non c'è una grande risposta ... ma mi piacerebbe provare qualsiasi cosa, per quanto possa sembrare strano.

NOTA: qualsiasi tecnica deve essere compatibile con App Store. Non è possibile utilizzare qualcosa come l'hacking CoreSurface utilizzato/utilizzato da Display Recorder.

Grazie per il vostro aiuto!

+0

Questo viene fatto in Objective-C? Indipendentemente da ciò, sarebbe possibile scandire il tempo del processo di registrazione e se l'ultima richiesta richiedesse troppo tempo interrompere la registrazione per i fotogrammi X (scegli un numero)? Non ho iOS, ma questa è la prima cosa che mi viene in mente. – Jared

+0

Ciao - sì, tutto Obj-C ... Poiché 'troppo lungo' varia significativamente tra i dispositivi a causa delle differenze della CPU, questo potrebbe finire per essere meno preciso del necessario. – Hunter

+0

Forse fare qualcosa di simile a un antirimbalzo javascript? https://github.com/pixelspring/NKBlueprint-Obj-C-Mix-Edition o eventualmente monitorare l'utilizzo della CPU prima della chiamata? http://stackoverflow.com/questions/12889422/ios-cpu-usage-for-each-process-using-sysctl – Jared

risposta

1

"Poiché il livello deve essere visualizzato sul thread principale" questo non è vero, a condizione che non si tocchi UIKit.

Si prega di vedere https://stackoverflow.com/a/12844171/136305

+0

Hai già usato questo metodo con successo? – Hunter

+0

I miei test iniziali suggeriscono che renderInContext di CALayer: * non * funziona in modo affidabile su un thread in background. Arresti anomali casuali abbondano. – Hunter

+0

Non ho avuto problemi di rendering in un thread in background. In effetti, il rendering di un CALayer in un thread in background è una pratica standard per l'approccio CATiledLayer, utilizzato in molte app. Assicurati solo di attenersi ai metodi CG ... ed evita i metodi dell'interfaccia utente ... Ma poi di nuovo, non ho mai fatto un video in background. – fishinear

0

Forse è possibile registrare a metà risoluzione per accelerare le cose, se questo soddisfa i requisiti?

+0

Come si cattura lo schermo a metà risoluzione? – Hunter

+0

@Hunter: se non si chiama 'UIGraphicsBeginImageContextWithOptions' prima di chiamare' UIGraphicsGetCurrentContext', quindi si sta già acquisendo un'immagine non retina (cioè a metà risoluzione) quando si esegue su un dispositivo retina. – MusiGenesis

+0

@MusiGenesis Ti stai riferendo alla proprietà della scala? I miei test sembrano indicare che mentre il contesto può ottenere contenuti diversi, il renderingInContext di CALayer sembra eseguire lo stesso sia per 1.0 che per 2.0 quando impostato per la scala. Hai informazioni diverse? – Hunter

Problemi correlati