Android WebView中拦截HTML5视频源请求

发布于 2024-12-28 23:57:45 字数 1193 浏览 2 评论 0原文

我有一个应用程序,它在 WebView 中显示带有视频元素的 HTML5 页面。我花了一段时间才弄清楚如何让视频正常工作,但最终我成功地在 Samsung 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, CustomViewCallbackcallback) 仅当我在视频已经播放时单击 HTML5 页面上的全屏控制按钮时才会调用,但当我单击 HTML5 页面上的全屏控制按钮时才会调用单击播放按钮。 (此方法的实际目的是什么?)

是否有人建议我使用另一种方法来捕获对视频文件的请求,或者有人可以向我解释当我单击视频元素上的播放按钮时实际发生的情况吗?

I have an app which shows a HTML5 page with a video element in a WebView. It took me a while to figure out how to get the video working, but finally I succeeded to play the video embedded in a WebView on an Samsung Galaxy Tab (Android 3.1). I used the following code for the video tag:

<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>

The video element has multiple sources and now I'm trying to capture the selected video source (and format) before the video starts to play. When I click the play button, I see a HTTP request for the video file arriving at the web server where the video files are stored, but I don't succeed in intercepting this request at the app-side.

I looked at several methods to see whether the request for the video file passes there, but I didn't saw it pass in any of them.

  • In shouldOverrideUrlLoading(WebView view, String url) in my WebViewClient only the initial HTML5 page request passes.
  • In shouldInterceptRequest (WebView view, String url) in my WebViewClient I see only passing the initial HTML5 page request and a request for the video poster image, but not for the video file.
  • onShowCustomView(View view, CustomViewCallback callback) in my WebChromeClient is only called when I click the fullscreen control button on the HTML5 page when the video is already playing, but not when I click the play button. (What is actually the purpose of this method?)

Does anyone have a suggestion for another method where I can capture the request for the video file or can anyone explain me what actually happens when I click the play button on the video element?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

街道布景 2025-01-04 23:57:45

我使用 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/consistency-event-firing-with-html5-video

I solved the problem using a javascript approach. When the HTML page is loaded, a loadedmetadata event is fired when the video metadata has been loaded. From that moment on you can get the selected video source from the currentSrc attribute of the video element and pass it via a JavascriptInterface to the Android native code.

Below is the code of the HTML5 video element. "Android" is the name by which the JavascriptInterface can be accessed in javascript.

<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>

The code of the 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
    }
}

And finally add the JavascriptInterface to the WebView at Activity creation time

mWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");

It’s important to catch the loadedmetadata event by adding the onloadedmetadata attribute to the HTML5 video element and not by registering an event listener at page load via addEventListener("loadedmetadata",...) because on a fast network the loadedmetadata event may be fired before the listener is registered (see http://dev.opera.com/articles/view/consistent-event-firing-with-html5-video)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文