6

Sto utilizzando AVFoundation per registrare dalla fotocamera del dispositivo a un filmato, utilizzando AVCaptureMovieFileOutput. Voglio consentire all'utente di passare dalla modalità a frame rate elevato a quella ad alta risoluzione prima che inizi la registrazione, ma non riesco a capire come si suppone di sapere quale sia lo standard AVCaptureDeviceFormat che offre la massima risoluzione adatta per la registrazione video.Come trovare la massima risoluzione AVCaptureDeviceFormat adatta per la registrazione su un file?

Per esempio, su iPod touch che sto testando su, elenca i seguenti formati di dispositivi per la fotocamera posteriore:

<AVCaptureDeviceFormat: 0x13108e260 'vide'/'420v' 192x 144, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @17.00), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310911a0 'vide'/'420f' 192x 144, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @17.00), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310afa60 'vide'/'420v' 352x 288, { 2- 30 fps}, HRSI:2992x2448, fov:49.745, max zoom:153.00 (upscales @8.50), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310af9b0 'vide'/'420f' 352x 288, { 2- 30 fps}, HRSI:2992x2448, fov:49.745, max zoom:153.00 (upscales @8.50), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x131092ad0 'vide'/'420v' 480x 360, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @6.80), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x13108f1c0 'vide'/'420f' 480x 360, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @6.80), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310af300 'vide'/'420v' 640x 480, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @5.10), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x131021990 'vide'/'420f' 640x 480, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @5.10), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310ac0f0 'vide'/'420v' 960x 540, { 2- 30 fps}, HRSI:3264x1836, fov:54.267, supports vis, max zoom:104.38 (upscales @3.09), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310ac180 'vide'/'420f' 960x 540, { 2- 30 fps}, HRSI:3264x1836, fov:54.267, supports vis, max zoom:104.38 (upscales @3.09), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x131091550 'vide'/'420v' 1280x 720, { 2- 30 fps}, HRSI:3264x1836, fov:54.267, supports vis, max zoom:95.62 (upscales @2.32), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310ab800 'vide'/'420f' 1280x 720, { 2- 30 fps}, HRSI:3264x1836, fov:54.267, supports vis, max zoom:95.62 (upscales @2.32), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x13100a350 'vide'/'420v' 1280x 720, { 3-120 fps}, fov:54.267, binned, supports vis, max zoom:52.12 (upscales @1.16), AF System:1, ISO:24.0-768.0, SS:0.000025-0.333333> 
<AVCaptureDeviceFormat: 0x131090270 'vide'/'420f' 1280x 720, { 3-120 fps}, fov:54.267, binned, supports vis, max zoom:52.12 (upscales @1.16), AF System:1, ISO:24.0-768.0, SS:0.000025-0.333333> 
<AVCaptureDeviceFormat: 0x131021510 'vide'/'420v' 1920x1080, { 2- 30 fps}, HRSI:3264x1836, fov:54.267, supports vis, max zoom:95.62 (upscales @1.55), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x1310a2130 'vide'/'420f' 1920x1080, { 2- 30 fps}, HRSI:3264x1836, fov:54.267, supports vis, max zoom:95.62 (upscales @1.55), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x12fe17b90 'vide'/'420v' 2592x1936, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @1.26), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x13108e010 'vide'/'420f' 2592x1936, { 2- 30 fps}, HRSI:3264x2448, fov:54.267, max zoom:153.00 (upscales @1.26), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x12fe17be0 'vide'/'420v' 3264x2448, { 2- 30 fps}, fov:54.267, max zoom:153.00 (upscales @1.00), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 
<AVCaptureDeviceFormat: 0x12fe17c40 'vide'/'420f' 3264x2448, { 2- 30 fps}, fov:54.267, max zoom:153.00 (upscales @1.00), AF System:1, ISO:24.0-768.0, SS:0.000024-0.500000> 

Selezionando il più alto frame rate è abbastanza banale (e un esempio è dato in la documentazione); hai semplicemente bisogno di scorrere i formati e i loro intervalli di frequenza fotogrammi supportati per trovare quello con il frame rate più alto. Per quanto posso dire, il formato con il frame rate più alto può sempre essere utilizzato per registrare su un file video.

Il problema si verifica quando si tenta di trovare il formato con la massima risoluzione. 1080p è, in questo caso, il più alto a cui è possibile registrare, ma i formati sono elencati fino a 2448 p; Posso cambiare l'hardware della fotocamera in questo formato ma si rifiuta di registrare su un file con qualcosa di più alto di 1080p. Naturalmente potrei hardcode utilizzare solo 1080p, ma ora abbiamo dispositivi che supportano la registrazione in 4K.

La mia domanda è, come posso filtrare questo elenco in modo che mostri solo i formati adatti per la registrazione? Ho esaminato la documentazione per AVCaptureDeviceFormat e CMFormatDescription, ma non riesco a trovare nulla che indica se il formato indicato è registrabile. Ho visto this question che è simile, ma il passaggio costante tra i formati fino a isActive è vero sembra un cattivo modo di farlo.

È possibile trovare il formato corretto da utilizzare senza doverli provare tutti per vedere quali funzionano?

risposta

1

Nella maggior parte dei casi l'impostazione di AVCaptureSession.sessionPreset in uno di AVCaptureSessionPreset... dovrebbe essere sufficiente. Utilizzare canSetSessionPreset(preset:) per verificare se il preset è supportato dal dispositivo corrente.

Volevo ottenere la massima risoluzione (larghezza) possibile; indipendentemente dal frame-rate, ecc Qui è la mia soluzione:

captureSession.sessionPreset = AVCaptureSessionPresetInputPriority // Required for the "activeFormat" of the device to be used 
let highresFormat = (device.formats as! [AVCaptureDeviceFormat]) 
    .filter { CMFormatDescriptionGetMediaSubType($0.formatDescription) == 875704422 } // Full range 420f 
    .maxElement { a, b in CMVideoFormatDescriptionGetDimensions(a.formatDescription).width < CMVideoFormatDescriptionGetDimensions(b.formatDescription).width } 
if let format = highresFormat { 
    device.activeFormat = format 
} 

Certo, ricevendo il "420 f" (in contrapposizione a "420 v") variante è un po 'strano ...

Poiché ogni dispositivo restituisce diversi formati per AVCaptureDevice.formats, suppongo che tutti i formati restituiti funzionino sul dispositivo corrente. Alcune informazioni possono essere trovate in questo technical note da Apple.

Problemi correlati