androidblazormauiblazorwebview

Blazor Maui Hybrid Android unable to show videos in app data directory-even with custom file provider


I have been using the suggested solution here, to display audio and video stored in the app data directory in a BlazorWebView. The files render correctly on Windows, but on Android they are unable to be found. Is there something I'm missing for Android specifically for this method?

Custom Blazor Webview:

public class MyCustomWebview : BlazorWebView
{
    public override IFileProvider CreateFileProvider(string contentRootDir)
    {
        var contentPath = Path.Combine(FileSystem.Current.AppDataDirectory, FolderConstants.ContentFolder);
        Directory.CreateDirectory(contentPath);
        var lPhysicalFiles = new PhysicalFileProvider(Path.Combine(FileSystem.Current.AppDataDirectory, FolderConstants.ContentFolder));
        return new CompositeFileProvider(lPhysicalFiles, base.CreateFileProvider(contentRootDir));
    }
}

MainPage XAML

<local:MyCustomWebview x:Name="blazorWebView" HostPage="wwwroot/index.html">
    <BlazorWebView.RootComponents>
        <RootComponent Selector="#app" ComponentType="{x:Type local:Routes}" />
    </BlazorWebView.RootComponents>
</local:MyCustomWebview>

I confirmed the file is saved in the App Data Directory, as in: /data/user/0/com.mypackage.whatever/files/Content/VideoContent/MyVideo.mp4 And then in my Blazor component it's being rendered as:

<video controls="" style="width:100%;" controlslist="nodownload"><source src="/VideoContent/MyVideo.mp4"><!--!-->
                    Your browser does not support the video tag
                </video>

But, it's giving a 404 error like it can't find the file.


Solution

  • Did you check the comment of the CreateFileProvider method? It is used to call into the platform-specific code to get that platform's asset file provider not the local storage file.

    Actually, for the android webview, the scr for the loacl stroage file usually is such as file:\\\xxx\xxx\xxx and so on. But this is not work for the blazor webview. You can report this as a new issue on the repo.

    And for a workaround, you can set the source for the video by the JS function on the android platform.

    Give an id to the video:

    <video id="video" controls="" style="width:100%;" controlslist="nodownload">
        <source src="/VideoContent/MyVideo.mp4">
    </video>
    

    Declare the js function in the index.html:

    <script>
         async function playvideo(videoId, videoStream) {
             const arrayBuffer = await videoStream.arrayBuffer();
             const blob = new Blob([arrayBuffer]);
             const url = URL.createObjectURL(blob);
             document.getElementById(videoId).src = url;
         }
     </script>
    

    Override the OnInitializedAsync() method:

    @inject IJSRuntime js;
    
    ...
    
    protected override async Task OnInitializedAsync()
     {
         #if ANDROID
         using(var steam = new FileStream("/data/user/0/com.mypackage.whatever/files/Content/VideoContent/MyVideo.mp4",
         FileMode.Open, FileAccess.Read, FileShare.None))
         {
             var dotnetstream = new DotNetStreamReference(steam);
             await js.InvokeVoidAsync("playvideo", "video", dotnetstream);
         }  
         #endif
     }