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

Xamarin Forms Android:WebView拦截媒体请求替换本地视频失败求助

问题描述

我正在开发一个Xamarin Forms Android项目,项目中的WebView用于加载自有网站播放视频。在加载WebView前,我已将MP4文件从服务器下载至应用数据目录,随后通过重写ShouldInterceptRequest方法拦截视频请求并替换为本地文件,代码如下:

public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
{
    string url = request.Url.ToString();

    if (IsRemoteVideo(url))
    {
        String relativeUrl = url.Replace(HOSTNAME, string.Empty);

        if (App._downloadedMediaFiles.Any(m => m.Key == relativeUrl))
        {
            string localVideoPath = App._downloadedMediaFiles.FirstOrDefault(m => m.Key == relativeUrl).Value;

            FileStream fileStream = new FileStream(localVideoPath, FileMode.Open, FileAccess.Read);

            return new WebResourceResponse("video/mp4", "UTF-8", fileStream);
        }
    }

    return base.ShouldInterceptRequest(view, request);
}

但WebView无法加载视频,开发者工具显示文件大小为0kb。请问该方案是否可行?若可行,正确的实现方式是什么?

解决方案

这个方案是可行的,你的代码存在几个关键问题导致视频加载失败,以下是修正后的实现思路和代码:

问题分析

  1. 编码参数错误:视频是二进制资源,不能使用UTF-8编码,传入该参数会导致WebView解析流异常,最终显示文件大小为0。
  2. 字典查询冗余:先用Any判断再用FirstOrDefault查询,属于冗余操作,直接用TryGetValue更高效。
  3. 文件存在性校验缺失:未验证本地文件是否真实存在,若路径错误会返回空流。

修正后的代码

public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
{
    string url = request.Url.ToString();

    if (IsRemoteVideo(url))
    {
        string relativeUrl = url.Replace(HOSTNAME, string.Empty);
        
        // 直接通过TryGetValue获取本地路径,避免重复查询字典
        if (App._downloadedMediaFiles.TryGetValue(relativeUrl, out string localVideoPath) && File.Exists(localVideoPath))
        {
            try
            {
                // 二进制资源不需要字符编码,第二个参数传null
                var fileStream = new FileStream(localVideoPath, FileMode.Open, FileAccess.Read);
                return new WebResourceResponse("video/mp4", null, fileStream);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("加载本地视频失败:" + ex.Message);
            }
        }
    }

    return base.ShouldInterceptRequest(view, request);
}

额外注意事项

  • WebView基础配置:确保开启必要的权限和设置,否则即使流正确返回也无法播放:
    webView.Settings.JavaScriptEnabled = true;
    webView.Settings.AllowFileAccess = true;
    webView.Settings.MediaPlaybackRequiresUserGesture = false; // 如需自动播放可启用
    
  • 文件权限:如果视频存储在外部目录,Android 10及以上需使用Scoped Storage,低版本需申请READ_EXTERNAL_STORAGE权限。
  • 视频格式兼容性:确认MP4采用WebView支持的编码(H.264视频+AAC音频),特殊编码的视频可能无法正常播放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:43:21