You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.NET Maui Blazor中,能否通过HTML5 Video直接播放本地文件系统视频?

问题解答:.NET Maui Blazor中播放用户本地视频文件的可行方案

直接将HTML5 video元素的src指向用户文件系统的绝对路径不可行。

原因分析

.NET Maui Blazor基于WebView运行,遵循浏览器同源安全策略:

  • 项目wwwroot目录下的文件属于应用静态资源,通过相对路径访问时,WebView从应用资源容器加载,属于同源访问,因此可以正常播放。
  • 直接使用本地文件系统绝对路径(如C:\videos\testvideo.mp4)会被WebView安全机制拦截,禁止跨源访问本地文件,避免潜在安全风险。

可行实现方案

要实现用户选择本地视频并播放,需通过FilePicker获取文件,再将文件内容转换为WebView可访问的格式(Base64 Data URI或Object URL)。

方案1:Base64 Data URI(适合小体积视频)

读取视频文件内容并转换为Base64编码,生成Data URI作为video的src:

@page "/videoplayer"
@inject IFilePicker FilePicker

<h3>本地视频播放器</h3>

<video controls width="800" height="462">
    <source src="@VideoSource" type="video/mp4" />
    您的浏览器不支持HTML5视频播放。
</video>

<button @onclick="PickVideoFile">选择本地视频</button>

@code {
    private string? VideoSource { get; set; }

    private async Task PickVideoFile()
    {
        var pickResult = await FilePicker.PickAsync(new PickOptions
        {
            FileTypes = FilePickerFileType.Videos,
            PickerTitle = "选择MP4视频文件"
        });

        if (pickResult != null)
        {
            using var fileStream = await pickResult.OpenReadAsync();
            var fileBytes = new byte[fileStream.Length];
            await fileStream.ReadAsync(fileBytes, 0, (int)fileStream.Length);
            
            // 生成Base64格式的Data URI
            VideoSource = $"data:video/mp4;base64,{Convert.ToBase64String(fileBytes)}";
        }
    }
}

方案2:Object URL(适合大体积视频,节省内存)

通过IJSRuntime将文件流传递给前端,创建Blob Object URL,避免Base64的内存开销:

  1. 在wwwroot/js目录下创建video-utils.js脚本:
window.createVideoObjectURL = async (dotNetStream) => {
    const stream = await dotNetStream.stream();
    const videoBlob = new Blob([stream], { type: 'video/mp4' });
    return URL.createObjectURL(videoBlob);
};

window.revokeVideoObjectURL = (url) => {
    URL.revokeObjectURL(url);
};
  1. 在wwwroot/index.html中引用该脚本:
<script src="js/video-utils.js"></script>
  1. Razor页面代码:
@page "/videoplayer"
@inject IJSRuntime JSRuntime
@inject IFilePicker FilePicker
@implements IDisposable

<h3>本地视频播放器</h3>

<video controls width="800" height="462">
    <source src="@VideoSource" type="video/mp4" />
    您的浏览器不支持HTML5视频播放。
</video>

<button @onclick="PickVideoFile">选择本地视频</button>

@code {
    private string? VideoSource { get; set; }

    private async Task PickVideoFile()
    {
        // 先释放之前的Object URL,避免内存泄漏
        if (!string.IsNullOrEmpty(VideoSource))
        {
            await JSRuntime.InvokeVoidAsync("revokeVideoObjectURL", VideoSource);
        }

        var pickResult = await FilePicker.PickAsync(new PickOptions
        {
            FileTypes = FilePickerFileType.Videos,
            PickerTitle = "选择MP4视频文件"
        });

        if (pickResult != null)
        {
            using var fileStream = await pickResult.OpenReadAsync();
            var streamReference = new DotNetStreamReference(fileStream);
            VideoSource = await JSRuntime.InvokeAsync<string>("createVideoObjectURL", streamReference);
        }
    }

    public void Dispose()
    {
        // 组件销毁时释放Object URL
        if (!string.IsNullOrEmpty(VideoSource))
        {
            _ = JSRuntime.InvokeVoidAsync("revokeVideoObjectURL", VideoSource);
        }
    }
}

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 06:01:37