Видео для Android HTML5 - работает при нажатии на воспроизведение, но не video.play()
Я понимаю, что видео html5 на Android не может воспроизводиться автоматически. В моем нынешнем виде видео работает на устройстве только тогда, когда пользователь нажимает кнопку воспроизведения.
<video width="640px" height="360px" 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()
?
Ответы
Ответ 1
Он не будет работать по той же причине, что браузеры блокируют вызовы window.open()
, потому что это разрешит веб-разработчикам отклонять предпочтения пользователя, а не автоматически воспроизводить медиа (или открывать всплывающие окна).
Разница между нажатием кнопки воспроизведения и использованием этого метода - это именно то, что вы сказали: клик. Такие вызовы разрешены в событиях кликов, но не в целом.
Ответ 2
После нескольких часов поиска и тестирования "решений" это то, что сработало для меня! Решено Angry Fridges (большое спасибо за это).
<video id="video" class="video" autoplay muted >
заметил как автозапуск, так и приглушенный, они оба нужны.
Это позволило видео воспроизводить как на компьютере, так и на телефоне Android.
Ответ 3
Я получил его на работу! Теперь он может воспроизводить видео в формате HTML5 с использованием "autoplay"! Черт побери! Хорошо, вот что я сделал:
<div id=content>
<video width="1280px" height="720px" 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>
Я надеюсь, что это может помочь любому, я боролся с этим уже неделю!
Просто, чтобы быть ясным:
работает над:
Android 4.0.4
Планшет Samsung 10.1
Собственный браузер устройств
Ответ 4
Я сделал следующие открытия о видео HTML5 на Android 4. 0+.
Для выполнения этих тестов я создал приложение-песочницу, которое состояло из HTML-страницы, сохраненной в /assets.
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.
К счастью, это не повлияло на воспроизведение видео.
Ответ 5
Я нашел на kitkat, что Firefox позволит вам воспроизводить видео программно.
Кроме того, Chrome будет, если вы перейдете в флагов chrome://и включите опцию "Отключить жест для воспроизведения мультимедиа".
Ответ 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, однако мне все еще приходилось настраивать, чтобы получить хороший опыт... Вот основные моменты
- загрузите
audio
теги, как упомянул @JenniferG - используйте соответствующий метод для получения доступа к элементам DOM, для React используйте
refs
- включить звук и установить громкость перед игрой
- метод
play()
возвращает обещание (по крайней мере, в 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>