This is the archived version of Roland Weigelt's weblog that ran from 2003 to 2023 at weblogs.asp.net

Contents tagged with WebView2

  • Using a Video Device with getUserMedia in WebView2 in a Kiosk Scenario (Update)

    Back in July I wrote about my experiments with using a video capture device on a web page loaded into the WebView2 component. Since then, WebView2 has received a few updates. I am not sure when or how things have changed (or which version exactly I was using back then), but the workaround I described for using getUserMedia() without HTTPS no longer worked when I revisited this topic recently.

    While switching to HTTPS is my goal in the long run, I encountered problems with certificates that look like they could be solved by WebView2 feedback item #624, so I shelved the work on this for my application for now. Fortunately, there is a way to “fake” HTTPS in WebView2 that is good enough to meet the requirements for getUserMedia().

    The CoreWebView2.SetVirtualHostNameToFolderMapping() function allows you to map a server name to a local folder. This way navigating to e.g. https://someServer/somePage.html will load the local file somePage.html contained in that folder. If the server part and the display part of your application run on different computers, you will obviously have transfer the files e.g. to a temporary folder.

    The Microsoft documentation contains everything you need to know, so I will not go into further detail here. As usual, when working with WebView2, make sure yourWebView.EnsureCoreWebView2Async() has been executed before calling yourWebView.CoreWebView2.SetVirtualHostNameToFolderMapping().

    See also

  • Using a Video Device with getUserMedia in WebView2 in a Kiosk Scenario

    I use Microsoft’s WebView2 control for a digital signage desktop application running in fullscreen mode (“kiosk client”). All visible content is HTML coming from a server (on a private network), so the kiosk client itself has to be updated very rarely.

    Right now, I am exploring how to display the output of another computer that is (physically) standing nearby, but on a different network, using a video capture device. Showing the video stream in HTML is pretty straightforward using navigator.mediaDevices.getUserMedia(). I will not go into detail on this, as a web search for “webcam video getUserMedia” gives you helpful information on how to get things up and running very quickly.

    Instead, the focus of this article is on two problems that I ran into:

    How to avoid the request for permission to use the camera

    When browsing the web with a normal browser, nobody wants a web page to be able to simply switch on a webcam or a microphone without the user’s consent. That is why it is a good thing that getUserMedia() opens a prompt asking the use for permission.

    For an unattended kiosk display, though, such a prompt is a no-go. The request for permission must be handled programmatically. Fortunately, the WebView2 control offers a way to do this.

    Let’s say you followed the first steps of the “Get started with WebView2 in WPF” tutorial in the Microsoft documentation, so you have WebView2 control called “webView” in your application window. Now, instead of setting the Source property in XAML, you add an event handler for the Loaded event. After calling EnsureCoreWebView2Async() you can add an event handler for the PermissionRequested event, where things work pretty much as expected: If the requested permission is for the camera, your code allows it.

    public partial class MainWindow : Window
    {
    	public MainWindow()
    	{
    		InitializeComponent();
    		Loaded += HandleLoaded;
    	}
    	
    	private async void HandleLoaded(object sender, RoutedEventArgs e)
    	{
    		await webView.EnsureCoreWebView2Async(); // important
    		webView.CoreWebView2.PermissionRequested += HandlePermissionRequested;
    		webView.Source = new Uri("...URI of your page...");
    	}
    	
    	private void HandlePermissionRequested(object? sender, CoreWebView2PermissionRequestedEventArgs e)
    	{
    		if (e.PermissionKind == CoreWebView2PermissionKind.Camera)
    		{
    			e.State = CoreWebView2PermissionState.Allow;
    		}
    	}
    }

    If you want, you can check the Uri property of the CoreWebView2PermissionRequestedEventArgs to lock down the automatic permission to specific URIs.

    How to circumvent the requirement for HTTPS for getUserMedia() - for the purposes of this scenario

    My digital signage solution is currently using HTTP. A web page loaded into Edge/WebView2 this way cannot use navigator.mediaDevices.getUserMedia()What does work is using a file URI, both for a local file or a file a remote file share.

    A local file deployed with the setup for the kiosk application could require more frequent update installations, though. And a file share for this sole purpose is not exactly an elegant solution.

    So what I did was to use WebClient.DownloadFile to download the HTML file on startup via HTTP from the server to a local file in a temporary folder. Then I could navigate to that file using a file URI.

    At some point in the future, I will move my application to HTTPS. But until then, this solution is good enough.

    Update 2021-12-29: The approach described above no longer works. Please see my other blog post for updated information on a workaround.