停止在三星设备上的科尔多瓦 webview 中无休止地缓冲 html5 视频
Posted
技术标签:
【中文标题】停止在三星设备上的科尔多瓦 webview 中无休止地缓冲 html5 视频【英文标题】:Stop endless buffering of html5 video in cordova webview on Samsung devices 【发布时间】:2014-03-06 23:58:03 【问题描述】:我正在使用 Cordova (PhoneGap 3.0.0-0.14.4) 构建一个跨平台移动应用程序,并将 android 作为目标平台之一。
该应用程序的一个(主要但不仅是)部分功能是播放视频。
我选择了 html5 <video>
标签作为实现视频播放器的首选方法。
这些视频托管在 Vimeo 上。
该应用程序以单个 html 文档的形式实现,其中导航是通过使用 javascript 更改内容来实现的。
我使用的视频标签看起来像:
<video autoplay controls id="videotag">
<source id="videosrc" src="http://player.vimeo.com/external/..."/>
Din apparat stöder inte denna video.
</video>
只需将视频标签添加到 html 即可开箱即用地播放视频。 在 HTC One mini (Android 4.3) 上,这个解决方案没有问题。 在三星 Galaxy S4 mini (Android 4.2.2) 上,视频也会播放,但会出现另一个问题: 视频正在由 MediaPlayer 组件缓冲,并且这种缓冲永远不会停止。 日志由以下消息填充,无限重复:
01-25 13:45:36.698: V/MediaPlayer(2814): message received msg=3, ext1=34, ext2=0
01-25 13:45:36.698: V/MediaPlayer(2814): buffering 34
01-25 13:45:36.698: V/MediaPlayer(2814): callback application
01-25 13:45:36.698: V/MediaPlayer(2814): back from callback
即使在播放停止、视频标签被移除并且用户退出(暂停)应用后,这种缓冲也会继续。 暂停应用程序不会停止缓冲,但会终止应用程序。 缓冲达到 100% 时甚至不会停止,而是显然无限期地继续。 没有声音在后台播放,但互联网连接保持打开状态,电池电量耗尽并且设备发热。 这对我们来说是个大问题,因为我们不愿意发布会导致过热的应用程序。
三星 Galaxy S3 的 Beta 测试人员也报告了与检测到的问题类似的症状。 该问题可能仅限于三星,因为它不会出现在 HTC 设备上。
即使不再需要视频,MediaPlayer 组件似乎也没有收到停止缓冲的消息。
我尝试了以下方法,但没有成功:
观看完毕后,我已将视频标签从 DOM 中完全移除。 我使用 javascript 通过调用 pause() 来停止播放 移除前的视频元素。 关注HTML5 Video: Force abort of buffering 我尝试使用 javscript 清除视频标签内的 src url,然后在视频标签上调用 load()。 根据对上述问题的评论,我尝试将视频标签放在 iframe 中,完成后会从 DOM 中删除 观看。 我已尝试将以上所有内容结合起来。 我曾尝试将视频标签放在一个单独的页面上,该页面被导航离开。这与 single-page-with-js 背道而驰 其他使用的模型。 我尝试过通过oEmbed使用Vimeo播放器,而不是直接使用html5视频标签。这已经用尽了我能够找到的与平台无关的技巧。 有一些基于原生Android代码的方法
Stop Android MediaPlayer automatically launched by webpage within WebView 提供了一个潜在的解决方案,但根据问题作者的评论,接受的解决方案只会停止播放音频,但不会杀死 MediaPlayer。 Android WebView Playing HTML5/h.264/mp4 Video, How to get at the MediaPlayer 似乎是一个类似的问题,但使用自定义 web 视图而不是 cordova。我不知道如何尝试将其应用于科尔多瓦。我正在寻找任何解决方案,以解决允许播放视频而不会导致过热的问题。 这应该是其他人需要解决的问题,所以希望有一个cordova插件已经解决了这个问题。 有这样的插件吗? 如果没有,上面提到的两种 Android 原生方法中的任何一种都可以在 cordova 中实现吗?它们能解决问题吗?
一个潜在的解决方法是在应用暂停时将其终止。 这很丑陋,不符合 Android 指南。 实现这一目标的最不丑陋的方法是什么?
【问题讨论】:
【参考方案1】:在类似的事情上挣扎了一天多之后,我发现您可以通过将WebView
发送到带有 HTML5 视频标签和错误视频 URL 的页面来使 WebView
内的 MediaPlayer
崩溃。下面的示例是具有有效视频标签的主要活动。如果您按下播放键,MediaPlayer
将接管并开始永远运行...但是当您单击返回或主页并离开应用程序时,onPause()
被触发,WebView
被重定向到一个错误的页面视频网址并告诉自动播放。尝试玩游戏会使MediaPlayer
崩溃,瞧! MediaPlayer
已不复存在。
package com.test.webviewtest;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
webView = new WebView(this);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());
String html = "<video width=\"320\" height=\"240\" controls>" +
"<source src=\"http://www.w3schools.com/html/movie.mp4\" " +
"type=\"video/mp4\"></video>";
webView.loadData(html, "text/html", null);
setContentView(webView);
@Override
protected void onPause()
super.onPause();
// attempt to kill the MediaPlayer here...
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient()
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon)
String js = "javascript:document.getElementsByTagName('video')[0].play();";
webView.loadUrl(js);
);
String html = "<video width=\"320\" height=\"240\" controls>" +
"<source src=\"http://www.w3schools.com/html/" +
"NOT_A_MOVIE.mp4" +
"\" type=\"video/mp4\"></video>";
webView.loadData(html, "text/html", null);
注意日志:
02-26 13:19:13.010 220-25370/? V/MediaPlayerService﹕ [607] notify (0x43a3aeb8, 100, 1, -1004)
02-26 13:19:13.010 25262-25274/com.test.webviewtest V/MediaPlayer﹕ message received msg=100, ext1=1, ext2=-1004
02-26 13:19:13.010 25262-25274/com.test.webviewtest E/MediaPlayer﹕ error (1, -1004)
02-26 13:19:13.010 25262-25274/com.test.webviewtest V/MediaPlayer﹕ callback application
02-26 13:19:13.020 25262-25274/com.test.webviewtest V/MediaPlayer﹕ back from callback
02-26 13:19:13.020 25262-25262/com.test.webviewtest E/MediaPlayer﹕ Error (1,-1004)
然后是没有更多MediaPlayer
日志的幸福沉默......
更多讨论请见Android WebView HTML5 Video Spawns MediaPlayer that lives forever on Samsung S4 [Hacked answer found]。
【讨论】:
我可以确认这确实解决了三星设备上的问题,因此我接受您的回答。但是,您对自己的问题发表了评论:“它确实破坏了其他设备,因此这不是一个好的解决方案。在其他设备上(经过 Nexus 7 测试),此代码将使 WebView 对任何未来的调用都无用。”,所以我会要么继续寻找解决方案,要么将其作为三星特有的解决方案(呃,越来越丑……)以上是关于停止在三星设备上的科尔多瓦 webview 中无休止地缓冲 html5 视频的主要内容,如果未能解决你的问题,请参考以下文章