My UWP store app that uses the webcam to scan QR code images does not work on certain laptops. I am using the MediaCapture class to preview and scan. I had reports from various users that certain devices just don't show any image(and no error message) in the app while others show the camera preview just fine. Below is a list of devices to help narrow down where the issue might be. Some of these I tested by going into a big box retailer that has laptops on display.
These work:
- Dell E5450 (tested myself)
- Lenovo u310 (tested myself)
- Lenovo u310 with additional webcam attached (tested myself)
- Lenovo tablet (reported by user, not verified, has multiple cameras)
- HP elitebook 850 g5 (tested myself, has Windows Hello)
- Multiple generic high end laptops
These don't work:
- Surface Go (reported by user, verified myself, has Windows Hello)
- Surface Laptop (reported by user, unsure which model, has Windows Hello)
- Dell Latitude 7275 (reported by user, not verified, has RealSense camera)
Initially, I thought this was caused by multiple camera's being connected or their higher resolution, but after more reports and testing, I think it might be these 'special' camera's that are causing trouble.
This is the initialization code:
mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync();
List<VideoEncodingProperties> availableResolutions = null;
try {
availableResolutions = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoPreview).Where(properties=>properties is VideoEncodingProperties).Select(properties=>(VideoEncodingProperties)properties).ToList();
}
catch(Exception ex)
{
MessageManager.ShowMessageToUserAsync("No resolutions could be detected, trying default mode.");
}
VideoEncodingProperties bestVideoResolution = this.findBestResolution(availableResolutions);
VideoEncodingProperties bestPhotoResolution = this.findBestResolution(availableResolutions);
if (bestVideoResolution != null)
{
await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, bestVideoResolution);
}
if (bestPhotoResolution != null)
{
await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, bestPhotoResolution);
}
displayRequest.RequestActive();
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
previewWindowElement.Source = mediaCapture;
await mediaCapture.StartPreviewAsync();
The entire file is here: https://github.com/matthiasduyck/WifiQRCodeReader/blob/b774cbca4f9dc58f9aed53ebdb827666f4924bb2/Wifi%20QR%20code%20scanner/Managers/QRCameraManager.cs
And this is the full project at the revision currently in the store: https://github.com/matthiasduyck/WifiQRCodeReader/tree/b774cbca4f9dc58f9aed53ebdb827666f4924bb2
This is the app in the store: https://www.microsoft.com/en-us/p/wifi-qr-code-scanner/9pnhnrbg9wlh
Does anyone know what is going on and how I can resolve this issue?
Edit: I have update the app to try and filter out non-color style camera's(depth, infrared, etc). It looks like my updated code does not do this properly. This is the code that tries to find all color cameras only:
var videoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
var groups = await MediaFrameSourceGroup.FindAllAsync();
// Filter out color video preview and video record type sources and remove duplicates video devices.
var _frameSourceGroups = groups.Where(g => g.SourceInfos.Any(s => s.SourceKind == MediaFrameSourceKind.Color &&
(s.MediaStreamType == MediaStreamType.VideoPreview || s.MediaStreamType == MediaStreamType.VideoRecord))
&& g.SourceInfos.All(sourceInfo => videoDevices.Any(vd => vd.Id == sourceInfo.DeviceInformation.Id))).ToList();
availableColorCameras = _frameSourceGroups.SelectMany(x => x.SourceInfos.Select(y => y.DeviceInformation));
This is the dropdown that a user with a windows hello style camera got: camera dropdown options, 6 cameras listed