在Android WebView中拦截HTML5视频源请求

7

我有一个应用程序,通过WebView显示一个带有视频元素的HTML5页面。我花了一些时间才弄清楚如何让视频正常播放,但最终我成功地在三星Galaxy Tab(Android 3.1)上嵌入了WebView中的视频。我使用以下代码来定义视频标签:

<video controls poster="img/poster.jpg" height="240" width="360">
        <source src="video/BigBuck.m4v">
        <source src="video/BigBuck.theora.ogv" type="video/ogg">
        <source src="video/BigBuck.webm" type="video/webm">
        HTML5 video not supported.
</video>

视频元素有多个来源,现在我正试图在视频开始播放之前捕获所选的视频源(和格式)。当我点击播放按钮时,我看到一个HTTP请求到达存储视频文件的Web服务器,但我没有成功地在应用端拦截这个请求。
我查看了几种方法,看看视频文件的请求是否经过了它们,但我没有在任何一个方法中看到它通过。
  • 在我的WebViewClientshouldOverrideUrlLoading(WebView view, String url)中,只有初始的HTML5页面请求通过。
  • 在我的WebViewClientshouldInterceptRequest (WebView view, String url)中,我只看到传递初始的HTML5页面请求和视频海报图像的请求,但没有视频文件的请求。
  • 在我的WebChromeClient中的onShowCustomView(View view, CustomViewCallback callback)仅在我单击HTML5页面上的全屏控件按钮并且视频已经播放时才调用,而不是在我单击播放按钮时。(这个方法的实际目的是什么?)
有人有另一种方法可以捕获视频文件的请求吗,或者有人可以解释一下当我点击视频元素的播放按钮时实际发生了什么吗?

你能发布一下你使用的视频标签代码吗?我最近处理过这个问题,shouldOverrideUrlLoading(WebView view, String url) 对我有用(尽管是在 Gingerbread 上)。 - Boris Strandjev
1个回答

4
我使用了JavaScript方法解决了这个问题。当HTML页面加载时,视频元数据加载后会触发一个"loadedmetadata"事件。从那时起,您可以通过视频元素的 "currentSrc" 属性获取所选视频源,并通过 "JavascriptInterface" 将其传递给Android原生代码。
以下是HTML5视频元素的代码。 "Android" 是JavaScript中可以访问 "JavascriptInterface" 的名称。
<video poster="image/poster.jpg" height="240" width="360" onloadedmetadata="Android.interceptPlay(this.currentSrc);">
    <source src="video/BigBuck.m4v">
    <source src="video/BigBuck.webm" type="video/webm">
    <source src="video/BigBuck.theora.ogv" type="video/ogg">
    HTML5 video not supported.
</video>

JavascriptInterface的代码

private class JavaScriptInterface {
    Context mContext;

    /* Instantiate the interface and set the context */
    JavaScriptInterface(Context c) {
        mContext = c;
    }

    public void interceptPlay(String source) {
        // do something
    }
}

最后,在Activity创建时,将JavascriptInterface添加到WebView中。
mWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");

重要的一点是,我们需要通过在HTML5视频元素中添加onloadedmetadata属性来捕获loadedmetadata事件,而不是在页面加载时通过addEventListener("loadedmetadata",...)注册事件侦听器,因为在快速网络上,loadedmetadata事件可能会在侦听器注册之前被触发(参见http://dev.opera.com/articles/view/consistent-event-firing-with-html5-video)。

谢谢你的解决方案,Erika;这看起来正是我所需要的。 - FractalBob
我说得太早了。我需要在第一次按下播放按钮时拦截它(我只下载视频一次)。你看有什么简单的方法可以做到这一点吗? - FractalBob
你是否曾经找到了一个“真正”的解决方案?因为在我的情况下,事件永远不会被触发,所以我真的需要拦截URL。 - Iharob Al Asimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接