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.98k stars 1.71k forks source link

On Android, Maui Blazor app can't play HTML5 video when source comes from an IFileProvider #15647

Open cvalerio opened 1 year ago

cvalerio commented 1 year ago

Description

My MAUI Blazor app is supposed to download a bunch of videos from the internet and then play them in a <video /> element. I download the videos to FileSystem.Current.AppDataDirectory (but changing folder does not make any difference), and I extended BlazorWebView to serve those files through a custom IFileProvider.

On Windows there are no issues, but on Android my application cannot play any of the videos.

Using the inspector and attaching to the onerror event of the <video /> element, I've seen that the error reported is:

DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed

I also noticed from the DevTools Network tab that that the response is as follows:

Status Code: 200 OK
Referrer Policy: strict-origin-when-cross-origin

Cache-Control: no-cache, max-age=0, must-revalidate, no-store
Client-Via: shouldInterceptRequest
Content-Length: 0
Content-Type: video/mp4, video/mp4

If I put a remote address for the same video, it plays normally. It plays without issues also if I do the following, instead of setting directly the src attribute:

    const blob = await fetch("videos/mov_bbb.mp4").then(r => r.blob());
    const url = URL.createObjectURL(blob);
    videoEl.src = url;

At this point the video is pre-fetched and plays happily. Please note that response from the fetch is exactly the same as above.

I have prepare a small app to reproduce the issue (see below).

Steps to Reproduce

  1. Clone the repo at https://github.com/cvalerio/CleanMauiBlazorVideoPlayerExample
  2. Start the app on Android emulator or device
  3. Click the "Play remote" button: the video plays correctly.
  4. Click the "Play local" button: the video does not play.
  5. Click the "Play local with prefetch" button: the video plays correctly.

Expected behavior: the video should be playing normally by just setting the src attribute.

Link to public reproduction project repository

https://github.com/cvalerio/CleanMauiBlazorVideoPlayerExample

Version with bug

7.0.81

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 11

Did you find any workaround?

Only pre-fetching the video file with window.fetch and set the src of the video element to the ObjectUrl from the obtained blob works.

Relevant log output

No response

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.

mahdirastegari commented 10 months ago

When I tried with Windows over the huge video file, I could see it was trying to load the whole video into memory. I guess your issue might related to the memory limitations in Android. However, this is not something ordinary in Blazor MAUI.

Inside the sample file attached to the main question if you slightly change the VideoFileProvider to:

internal class VideoFileProvider : IFileProvider
{
    public IDirectoryContents GetDirectoryContents(string subpath)
    {
        throw new NotImplementedException();
    }

    public IFileInfo GetFileInfo(string subpath)
    {
        if (subpath.StartsWith("videos"))
        {
            return new PhysicalFileInfo(new(@"C:\Users\Mahdi\myHugeVideo.mp4"));
        }

        return new NotFoundFileInfo(subpath);
    }

    public IChangeToken Watch(string filter)
    {
        throw new NotImplementedException();
    }
}

you will see this:

Animation

XamlTest commented 9 months ago

Verified this on Visual Studio Enterprise 17.9.0 Preview 1(8.0.3). Repro on Android 13.0-API33, not repro on Windows 11, iOS 17.0 and MacCatalyst with below Project: CleanMauiBlazorVideoPlayerExample.zip