@@ -153,69 +153,82 @@ class ViewController: UIViewController {
153
153
checkForMicrophoneCaptureAccess ( andThen: self . reallyStart)
154
154
}
155
155
156
+ let sessionQueue = DispatchQueue ( label: " sessionQueue " )
156
157
func reallyStart( ) {
157
158
if self . sess != nil && self . sess. isRunning {
158
159
self . sess. stopRunning ( )
159
160
self . previewLayer. removeFromSuperlayer ( )
160
161
self . sess = nil
161
162
return
162
163
}
163
- self . iv? . removeFromSuperview ( )
164
164
165
165
self . sess = AVCaptureSession ( )
166
-
167
- do {
168
- self . sess. beginConfiguration ( )
169
166
170
- guard self . sess. canSetSessionPreset ( self . sess. sessionPreset) else { return }
171
- self . sess. sessionPreset = . photo
167
+ self . sessionQueue. async {
168
+ do {
169
+ self . sess. beginConfiguration ( )
170
+
171
+ guard self . sess. canSetSessionPreset ( self . sess. sessionPreset) else { return }
172
+ self . sess. sessionPreset = . photo
173
+
174
+ let output = AVCapturePhotoOutput ( )
175
+ guard self . sess. canAddOutput ( output) else { return }
176
+ self . sess. addOutput ( output)
177
+
178
+ self . sess. commitConfiguration ( )
179
+ }
180
+
181
+ guard let cam = AVCaptureDevice . default ( for: . video) ,
182
+ let input = try ? AVCaptureDeviceInput ( device: cam)
183
+ else { return }
184
+ self . sess. addInput ( input)
172
185
173
- let output = AVCapturePhotoOutput ( )
174
- guard self . sess. canAddOutput ( output) else { return }
175
- self . sess. addOutput ( output)
186
+ self . sess. startRunning ( )
176
187
177
- self . sess. commitConfiguration ( )
188
+ DispatchQueue . main. async {
189
+ self . iv? . removeFromSuperview ( )
190
+ let lay = AVCaptureVideoPreviewLayer ( session: self . sess)
191
+ lay. frame = self . previewRect
192
+ self . view. layer. addSublayer ( lay)
193
+ self . previewLayer = lay // keep a ref so we can remove it later
194
+ }
178
195
}
179
-
180
- guard let cam = AVCaptureDevice . default ( for: . video) ,
181
- let input = try ? AVCaptureDeviceInput ( device: cam)
182
- else { return }
183
- self . sess. addInput ( input)
184
-
185
- let lay = AVCaptureVideoPreviewLayer ( session: self . sess)
186
- lay. frame = self . previewRect
187
- self . view. layer. addSublayer ( lay)
188
- self . previewLayer = lay // keep a ref so we can remove it later
189
-
190
- self . sess. startRunning ( )
191
196
}
192
197
193
198
@IBAction func doSnap ( _ sender: Any ) {
194
199
guard self . sess != nil && self . sess. isRunning else {
195
200
return
196
201
}
197
- let settings = AVCapturePhotoSettings ( )
198
- settings. flashMode = . auto
199
- // let's also ask for a preview image
200
- let pbpf = settings. availablePreviewPhotoPixelFormatTypes [ 0 ]
201
- let len = max ( self . previewLayer. bounds. width, self . previewLayer. bounds. height)
202
- settings. previewPhotoFormat = [
203
- kCVPixelBufferPixelFormatTypeKey as String : pbpf,
204
- kCVPixelBufferWidthKey as String : len,
205
- kCVPixelBufferHeightKey as String : len
206
- ]
207
- // let's also ask for a thumnail image
208
- settings. embeddedThumbnailPhotoFormat = [
209
- AVVideoCodecKey : AVVideoCodecType . jpeg
210
- ]
202
+
203
+ self . sessionQueue. async {
204
+ guard let output = self . sess. outputs [ 0 ] as? AVCapturePhotoOutput else { return }
205
+ let settings = AVCapturePhotoSettings ( )
206
+ // let's also ask for a preview image
207
+ let pbpf = settings. availablePreviewPhotoPixelFormatTypes [ 0 ]
208
+ let len = max ( self . previewLayer. bounds. width, self . previewLayer. bounds. height)
209
+ settings. previewPhotoFormat = [
210
+ kCVPixelBufferPixelFormatTypeKey as String : pbpf,
211
+ kCVPixelBufferWidthKey as String : len,
212
+ kCVPixelBufferHeightKey as String : len
213
+ ]
214
+ // let's also ask for a thumnail image
215
+ settings. embeddedThumbnailPhotoFormat = [
216
+ AVVideoCodecKey : AVVideoCodecType . jpeg
217
+ ]
211
218
212
- guard let output = self . sess. outputs [ 0 ] as? AVCapturePhotoOutput else { return }
213
- // how to deal with orientation; stolen from Apple's AVCam example!
214
- if let conn = output. connection ( with: . video) {
215
- let orientation = UIDevice . current. orientation. videoOrientation!
216
- conn. videoOrientation = orientation
219
+
220
+ let supported = output. supportedFlashModes
221
+ if supported. contains ( . auto) {
222
+ settings. flashMode = . auto
223
+ }
224
+
225
+ // how to deal with orientation; stolen from Apple's AVCam example!
226
+ if let conn = output. connection ( with: . video) {
227
+ let orientation = UIDevice . current. orientation. videoOrientation!
228
+ conn. videoOrientation = orientation
229
+ }
230
+ output. capturePhoto ( with: settings, delegate: self )
217
231
}
218
- output. capturePhoto ( with: settings, delegate: self )
219
232
}
220
233
221
234
}
0 commit comments