davidliu
Committed by GitHub

Fallback for camera choosing (#76)

@@ -200,38 +200,37 @@ constructor( @@ -200,38 +200,37 @@ constructor(
200 context: Context, 200 context: Context,
201 enumerator: CameraEnumerator, 201 enumerator: CameraEnumerator,
202 options: LocalVideoTrackOptions 202 options: LocalVideoTrackOptions
203 - ): Pair<VideoCapturerWithSize, LocalVideoTrackOptions>? {  
204 - val deviceNames = enumerator.deviceNames 203 + ): Pair<VideoCapturer, LocalVideoTrackOptions>? {
205 var targetDeviceName: String? = null 204 var targetDeviceName: String? = null
206 - var targetVideoCapturer: VideoCapturer? = null  
207 - for (deviceName in deviceNames) {  
208 - if ((options.deviceId != null && deviceName == options.deviceId)  
209 - || (enumerator.isFrontFacing(deviceName) && options.position == CameraPosition.FRONT)  
210 - ) {  
211 - LKLog.v { "Creating front facing camera capturer." }  
212 - val videoCapturer = enumerator.createCapturer(deviceName, null)  
213 - if (videoCapturer != null) {  
214 - targetDeviceName = deviceName  
215 - targetVideoCapturer = videoCapturer  
216 - break  
217 - }  
218 - } else if ((options.deviceId != null && deviceName == options.deviceId)  
219 - || (enumerator.isBackFacing(deviceName) && options.position == CameraPosition.BACK)  
220 - ) {  
221 - LKLog.v { "Creating back facing camera capturer." }  
222 - val videoCapturer = enumerator.createCapturer(deviceName, null)  
223 - if (videoCapturer != null) {  
224 - targetDeviceName = deviceName  
225 - targetVideoCapturer = videoCapturer  
226 - break  
227 - } 205 + val targetVideoCapturer: VideoCapturer?
  206 +
  207 + // Prioritize search by deviceId first
  208 + if (options.deviceId != null) {
  209 + targetDeviceName = enumerator.findCamera { deviceName -> deviceName == options.deviceId }
  210 + }
  211 +
  212 + // Search by camera position
  213 + if (targetDeviceName == null && options.position != null) {
  214 + targetDeviceName = enumerator.findCamera { deviceName ->
  215 + enumerator.getCameraPosition(deviceName) == options.position
228 } 216 }
229 } 217 }
230 218
  219 + // Fall back by choosing first available camera.
  220 + if (targetDeviceName == null) {
  221 + targetDeviceName = enumerator.findCamera { true }
  222 + }
  223 +
  224 + if (targetDeviceName == null) {
  225 + return null
  226 + }
  227 +
  228 + targetVideoCapturer = enumerator.createCapturer(targetDeviceName, null)
  229 +
231 // back fill any missing information 230 // back fill any missing information
232 val newOptions = options.copy( 231 val newOptions = options.copy(
233 deviceId = targetDeviceName, 232 deviceId = targetDeviceName,
234 - position = enumerator.getCameraPosition(targetDeviceName!!) 233 + position = enumerator.getCameraPosition(targetDeviceName)
235 ) 234 )
236 if (targetVideoCapturer is Camera1Capturer) { 235 if (targetVideoCapturer is Camera1Capturer) {
237 // Cache supported capture formats ahead of time to avoid future camera locks. 236 // Cache supported capture formats ahead of time to avoid future camera locks.
@@ -253,6 +252,26 @@ constructor( @@ -253,6 +252,26 @@ constructor(
253 ) 252 )
254 } 253 }
255 254
  255 + LKLog.w { "unknown CameraCapturer class: ${targetVideoCapturer.javaClass.canonicalName}. Reported dimensions may be inaccurate." }
  256 + if (targetVideoCapturer != null) {
  257 + return Pair(
  258 + targetVideoCapturer,
  259 + newOptions
  260 + )
  261 + }
  262 +
  263 + return null
  264 + }
  265 +
  266 + fun CameraEnumerator.findCamera(predicate: (deviceName: String) -> Boolean): String? {
  267 + for (deviceName in deviceNames) {
  268 + if (predicate(deviceName)) {
  269 + val videoCapturer = createCapturer(deviceName, null)
  270 + if (videoCapturer != null) {
  271 + return deviceName
  272 + }
  273 + }
  274 + }
256 return null 275 return null
257 } 276 }
258 277