Android HTML5 视频 - 单击播放时有效,但 video.play() 无效
Posted
技术标签:
【中文标题】Android HTML5 视频 - 单击播放时有效,但 video.play() 无效【英文标题】:Android HTML5 video - works when clicking play, but not video.play() 【发布时间】:2013-01-31 11:34:09 【问题描述】:我了解 android 上的 html5 视频无法自动播放。就目前而言,我的视频只有在用户点击播放按钮时才能在设备上播放。
<video src="media/video/Moments_of_Everyday_Life.mp4" controls id="video"></video>
<script type="text/javascript">
$(function()
var video = document.getElementById('video');
video.play();
);
</script>
不过,它可以在我的桌面上运行。
为什么这不起作用?还有点击播放和使用.play()
有什么区别?
【问题讨论】:
我很困惑。你是说这行得通,还是行不通? 我说当你点击播放控制时它可以工作。但是使用调用 video.play() 不起作用。 也就是说,手动播放视频作品。以编程方式播放它不会 @Harry 我来晚了,但请在下面查看我的新答案... 【参考方案1】:由于浏览器阻止调用 window.open()
的原因相同,它不会起作用,因为允许它允许 Web 开发人员颠覆用户偏好而不是自动播放媒体(或打开弹出窗口)。
点击播放和使用这个方法的区别正是你所说的:点击。此类调用在点击事件中是允许的,但一般情况下是不允许的。
【讨论】:
所以你的意思是视频无法自动播放? o 你有什么建议吗? 您桌面上的浏览器是否阻止自动播放?您的浏览器是否存在开放缺陷like this one?我的建议是:不要让您的应用依赖自动播放(或等效的脚本),这不是您可以依赖的功能,因为浏览器将继续实施功能来阻止它。 我终于搞定了!我想我会发布我的答案,因为网上大多数人都没有答案。现在让我们希望这对其他人有用 @Harry 你什么时候发布你的答案? 这是正确的删节答案;我用下面的例子进行了修饰。从我这里点赞!【参考方案2】:我让它工作了!现在它可以播放带有“自动播放”功能的 HTML5 视频!该死的,这需要时间!好的,这就是我所做的:
<div id=content>
<video src="file:///android_asset/videos/Moments_of_Everyday_Life.mp4"></video>
</div>
注意:有些人说他们在添加海报和/或预加载时可以使用它。我得到了这个工作和没有。
Javascript 自动播放视频:
<script type="text/javascript">
$(function()
function callback ()
document.querySelector('video').src = document.querySelector('video').src
document.querySelector('video').play();
window.addEventListener("load", callback, false);
);
</script>
我希望这可以帮助任何人,我已经为此苦苦挣扎了一周!
要明确一点:
工作:
安卓 4.0.4 三星 10.1 平板电脑 原生设备浏览器
【讨论】:
我使用了相同的代码。它不适用于安卓。我正在使用带有 phonegap 的 SAPUI5。 老兄苦苦挣扎了 4 天,能否详细说明您的 HTML 和代码。请发帖 我如何使用这个 javascript snip for android ?您可以编辑相同的答案吗? 这不适用于我在 moto 4g plus 中的 android marshmallow。我挣扎了 2 天。解释更多【参考方案3】:经过数小时的搜索和测试“解决方案”,这对我有用!由Angry Fridges 解决(非常感谢)。
<video id="video" class="video" autoplay muted >
注意到自动播放和静音,它们都是必需的。
这允许视频在电脑和安卓手机上播放。
【讨论】:
【参考方案4】:我在 kitkat 上发现 Firefox 将允许您以编程方式播放视频。
此外,如果您进入 chrome://flags 并启用“禁用媒体播放的手势要求”选项,Chrome 也会这样做。
【讨论】:
【参考方案5】:我对 Android 4.0+ 上的 HTML5 视频有以下发现。
为了执行这些测试,我制作了一个沙盒应用程序,其中包含一个保存在 /assets 中的 HTML 页面。
HTML:
<!DOCTYPE html>
<html>
<head>
<title>HTML5 Video Test</title>
</head>
<body>
<video preload="metadata"><source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4"></video>
<script>
var myvideo = document.getElementsByTagName('video')[0];
myvideo.addEventListener('loadeddata', function()
console.log("** RECEIVED loadeddata **");
myvideo.play();//this first play is needed for Android 4.1+
, false);
myvideo.addEventListener('canplaythrough', function()
console.log("** RECEIVED canplaythrough **");
myvideo.play();//this second play is needed for Android 4.0 only
, false);
</script>
</body>
</html>
JAVA: ("/assets/html5video.html")
private WebView mWebView;
private ProgressBar mProgressBar;
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.videotest);
// progress bar
mProgressBar = (ProgressBar) findViewById(R.id.videotest_progressbar);
mProgressBar.setProgress(0);
mProgressBar.setVisibility(View.VISIBLE);
// webview
mWebView = (WebView) findViewById(R.id.videotest_webview);
mWebView.getSettings().setJavaScriptEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
//NOTE: this is required only for Android 4.2.2+
mWebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
mWebView.setWebChromeClient(new WebChromeClient()
public void onProgressChanged(WebView view, int progress)
Log.i(TAG, "Progress = "+progress);
mProgressBar.setProgress(progress);
);
mWebView.setWebViewClient(new WebViewClient()
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
Toast.makeText(TestActivity.this, "Problem loading webpage", Toast.LENGTH_LONG).show();
mProgressBar.setVisibility(View.GONE);
public void onPageFinished(WebView view, String url)
mProgressBar.setVisibility(View.GONE);
);
@Override
protected void onResume()
super.onResume();
mWebView.loadUrl("file:///android_asset/html5video.html");
Android 4.0.3 注意
我一直遇到烦人的异常java.lang.Throwable: EventHub.removeMessages(int what = 107) is not supported before the WebViewCore is set up.
谢天谢地,它并没有影响视频播放。
【讨论】:
它适用于我尝试过的所有手机......直到一位同事给我带来了一台运行 Android 4.1.2 的 HTC One。相比之下,我拥有的三星 Note 2 也运行 Android 4.1.2 并且它会自动播放!我想指定“海报”属性是个好主意。【参考方案6】:或者你可以初始化你的 WebView 来轻松完成,如下:
webview.setWebViewClient(new WebViewClient()
// autoplay when finished loading via javascript injection
public void onPageFinished(WebView view, String url) mMessageContentView.loadUrl("javascript:(function() document.getElementsByTagName('video')[0].play(); )()");
);
以上对我来说很好。
【讨论】:
【参考方案7】:我在这里接受了一些建议,尤其是来自@JenniferG,但我仍然需要调整以获得良好的体验......这里是要点
加载@JenniferG 提到的audio
标签
使用适当的方法来访问 DOM 元素,对于 React,使用 refs
取消静音,并在播放前设置音量
play()
方法返回一个承诺(at least in Chrome);使用catch
适当地处理错误
注意不要在声音正在播放时调用play()
,否则会失败
用户必须与页面交互才能正常播放(请参阅下面的注释)
注意:如果你没有让用户点击某个按钮,你会得到这样的错误
play() 失败,因为用户没有先与文档交互。
总而言之,这是一个示例 React 组件,它应该作为一个不错的起点(它是人为的,但应该说明可能性)
class AudioPlayer extends React.Component
constructor(props)
super(props);
this.audioRef = React.createRef();
this.state =
interacted: false,
firstSoundPlayed: false,
secondSoundPlayed: false,
;
playAudio = () =>
const node = this.audioRef.current;
node.muted = false;
node.volume = 1.0;
node
.play()
.catch((e) =>
console.error('caught audio error: ', e.message);
);
handleClick = () =>
this.setState(
interacted: true,
);
setTimeout(() =>
this.playAudio();
this.setState(
firstSoundPlayed: true,
);
setTimeout(() =>
this.playAudio();
this.setState(
secondSoundPlayed: true,
);
, 6000);
, 4000);
renderStartup = () => (
<p>
Please give me permission to play sounds...
<button onClick=this.handleClick>Grant permission</button>
</p>
)
renderScreen = () => (
<div>
<p>I will play a sound as many times as I want now!</p>
<p>A sound is about to play...</p>
</div>
)
renderSecondSound = () => (
<div>
<p>Soon it will play again...</p>
</div>
)
renderSummary = () => (
<div>
<p>Hope you found this demo useful...</p>
</div>
)
render = () =>
const
interacted,
firstSoundPlayed,
secondSoundPlayed,
= this.state;
return (
<div>
<audio
autoPlay
muted
src="https://freesound.org/data/previews/33/33245_65091-lq.mp3"
ref=this.audioRef
/>
interacted === false ? this.renderStartup() : null
interacted === true && firstSoundPlayed === false ? this.renderScreen() : null
interacted === false || firstSoundPlayed === false || secondSoundPlayed === true ? null : this.renderSecondSound()
secondSoundPlayed === false ? null : this.renderSummary()
</div>);
ReactDOM.render(
<AudioPlayer />,
document.getElementById('react')
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.0/umd/react-dom.production.min.js"></script>
【讨论】:
以上是关于Android HTML5 视频 - 单击播放时有效,但 video.play() 无效的主要内容,如果未能解决你的问题,请参考以下文章
在 Android HTML5 播放器中开始播放所需的用户手势