How to switch between webcams when using CaptureElement/MediaCapture? [closed]

拥有回忆 提交于 2019-12-06 08:56:08

I don't have a tablet, and I have very little Metro experience... but I do have a lot of asynchronous programming experience.

One thing you have to be aware of is that async programs don't play well with state. You don't have race conditions per se, but you do have to consider reentrancy. In examples like this, reentrancy can cause a sort of single-threaded "race condition".

If I'm right, one easy way to avoid reentrancy on events is to have a boolean "reentrancy guard" variable (which I call switchingMedia below). Try this:

MediaCapture mediaCapture;
DeviceInformationCollection devices;
int currentDevice = 0;
bool switchingMedia = false;

private async void LayoutRoot_Tapped(object sender, Windows.UI.Xaml.Input.TappedEventArgs e)
{
    if (devices != null)
    {
        InitializeWebCam();
    }
}

private async void InitializeWebCam()
{
    if (switchingMedia)
        return;
    switchingMedia = true;

    if (devices == null)
    {
        devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
        ListDeviceDetails();
    }
    else
    {
        currentDevice = (currentDevice + 1) % devices.Count;
    }

    if (mediaCapture != null)
    {
        await mediaCapture.StopPreviewAsync();
        this.captureElement.Source = null;
    }

    mediaCapture = new MediaCapture();
    await mediaCapture.InitializeAsync(
        new MediaCaptureInitializationSettings
        {
            VideoDeviceId = devices[currentDevice].Id
        });

    this.captureElement.Source = mediaCapture;
    await mediaCapture.StartPreviewAsync();
    switchingMedia = false;
}

I also recommend that you have your async methods return Task rather than void (unless they're event handlers, of course). This allows them to be composable. e.g., if InitializeWebCam returns Task, then you can put the reentrancy guard code in the event handler instead:

private async void LayoutRoot_Tapped(object sender, Windows.UI.Xaml.Input.TappedEventArgs e)
{
    if (devices != null && !switchingMedia)
    {
        currentDevice = (currentDevice + 1) % devices.Count;
        switchingMedia = true;
        await InitializeWebCam();
        switchingMedia = false;
    }
}

By defining all your async methods to return Task by default, you have more composability options.

after getting all list of devices try like below

var rearCamera = devices.FirstOrDefault(item => item.EnclosureLocation != null &&
                                                        item.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);

I think the problem must have been with the Developer Preview build. I have no problem switching between 3 web cams in the Consumer Preview one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!