dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.89k stars 1.69k forks source link

WebView2 - Html Audio Control: Can't set currentTime #14964

Open Terrence77 opened 1 year ago

Terrence77 commented 1 year ago

Description

Following this tutorial

https://learn.microsoft.com/en-us/aspnet/core/blazor/hybrid/tutorials/windows-forms?view=aspnetcore-7.0

WinForms with Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView

When adding an html control to a razor page in a WinForms app, you are NOT able to advance the time bar, which corresponds to the audio.currentTime property.

When you try and advance the time, it goes back to the original time.

The same bug exists in a Maui Blazor App

The bug does NOT exist in a regular Blazor Server App.

The Pause, Volume and Playback Speed work just fine

Here are the dll versions I am using.

image

image

Steps to Reproduce

Follow this tutorial to get WebView2 running in a Winforms App. [(https://learn.microsoft.com/en-us/aspnet/core/blazor/hybrid/tutorials/windows-forms?view=aspnetcore-7.0)]

Link to public reproduction project repository

https://github.com/Terrence77/WinFormsAudio

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

I am running Windows 10 (21H2 OS build 19044.2846)

Project Sdk="Microsoft.NET.Sdk.Razor"> WinExe net7.0-windows "Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="7.0.81" WebView2 (1.0.1370.28)

Did you find any workaround?

No.

Relevant log output

ghost commented 1 year ago

Hi @Terrence77. We have added the "s/needs-repro" label to this issue, which indicates that we require steps and sample code to reproduce the issue before we can take further action. Please try to create a minimal sample project/solution or code samples which reproduce the issue, ideally as a GitHub repo that we can clone. See more details about creating repros here: https://github.com/dotnet/maui/blob/main/.github/repro.md

This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

Terrence77 commented 1 year ago

@jsuarezruiz , I have posted a GitHub Repo.
Tester should run the code, click LoadAudio button and then try and advance the timeline. https://github.com/Terrence77/WinFormsAudio

ghost commented 1 year ago

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

Terrence77 commented 1 year ago

So I guess I should build my commercial product with something other than WebView2? Is there any feedback from a developer that might be looking into this bug?

XamlTest commented 9 months ago

Verified this on Visual Studio Enterprise 17.8.0 Preview 5.0(8.0.0-rc.2.9373). Repro on Windows 11 with provided project.

Eilon commented 7 months ago

Confirmed here as well. I'm guessing this has to do with the media being served via the WebResourceRequested event. In the case of the <audio> element the first request comes with a Range: bytes=0- header, which means all data should be loaded - and it seems like it is. While seeking I would have expected it to already have all the data (which it said it loaded) and so seeking should be 'free' or at least it should send another web request with the desired range (which doesn't happen either).

This could also be due to the various 'no-cache' headers that are sent in the WebResourceRequested response, which is something we might consider changing anyway.

Eilon commented 7 months ago

BTW the repro can be even simpler with just this HTML and no dynamic loading/changing via Blazor:

<audio controls autoplay id="audioplayer">
    <source src="/audio/hm887.mp3">
</audio>
Eilon commented 6 months ago

OK so I'm almost certain it's that the various WebView integrations in BlazorWebView don't support 'range requests,' which is what the HTML audio element uses when seeking. The initial media request has to return an Accept-Ranges: bytes response header, and then the 'server' must support subsequent Range requests. Right now we support none of those, but no doubt .NET has various utilities to make adding such support possible, such as the RangeHeaderValue type, and other things related to HTTP ranges and multi-part messages.

Eilon commented 6 months ago

Another way to look at thinks is that when BlazorWebView serves a static file asset it should behave as close as possible to what ASP.NET's StaticFileMiddleware does in terms of headers/ranges.

Terrence77 commented 6 months ago

@Eilon Any idea if this might get fixed before .net 20 ? :)

Eilon commented 6 months ago

@Eilon Any idea if this might get fixed before .net 20 ? :)

Hopefully before then 😄 We're starting to establish priorities for what we plan to do for .NET 9, so we will need to see where this fits in.

This issue is limited to a case where an HTML audio (or presumably video) element is used in a BlazorWebView to play back media that comes from a Static Web Asset that is part of the app. We'll need to consider how likely that is in comparison to other related scenarios that probably do work: playback of remote media (e.g. over HTTPS), and playback of other local media, but not media that is part of the app (e.g. from the local file system).

Eilon commented 6 months ago

Jotting down some notes to future self:

I thought that maybe on Windows with Edge WebView2 we could use SetVirtualHostNameToFolderMapping to have certain static files be loaded directly by WebView2 and that with any luck it would use all the right headers. Alas, while it did work for audio, it did not do the Range header, so seeking did not work. I tried it by adding temporary code such as _webview.CoreWebView2.SetVirtualHostNameToFolderMapping("blazorlocalfiles", @"C:\app_location\wwwroot", CoreWebView2HostResourceAccessKind.Allow);, and audio loaded, but no seeking.

Amusingly, the doc for that API says:

Due to a current implementation limitation, media files accessed using virtual host name can be very slow to load.

Which I'm not sure is exactly referring to the problem we have here, but perhaps something else. What I saw in some cases is that it seems to try to load the entire file at once, but I'm not sure.

Anyway, aside from this attempt not working, another downside is that it would require a per-platform solution (assuming other platforms didn't support seeking).

If we change the static file serving in BlazorWebView to always support Range headers, then it should just always work everywhere.