Проблема воспроизведения видео и его адаптация под iPhone и iPad. HTML5
- четверг, 18 мая 2023 г. в 00:00:16
Недавно, в процессе реализации одного из модулей проекта, над которым я работаю - возникла проблема воспроизведения видео на web странице, а также возникли проблемы с его адаптацией под iPhone и iPad.
Проблема была в следующем:
Создал веб-страницу HTML5, на которой есть небольшое видео, создал свою control-panel для плейера, и все отлично работает в Chrome и FireFox, но совсем не работает ни на iPhone, ни на iPad. Получаю просто пустую страницу.
Реализация была следующей:
<div>
<div data-tag="loader"> </div>
<video preload="none" loop playsinline="false" muted="true" data-tag="player"
src="" type="video/mp4"></video>
<div type="button" data-tag="playMobile" </div>
<div class="player__control-panel">
<button type="button"data-tag="play"></button>
<button type="button"data-tag="pause"></button>
<div class="player__progress" data-tag="progress"></div>
<button type="button" data-tag="muted"></button>
<button type="button" data-tag="unmuted"></button>
<button data-tag="enterFullScreen" ></button>
</div>
</div>
Проблема иногда решаться атрибутом playsinline
в теге video
(Примечание для тех, кто использует React, вам нужно будет использовать playsInline
, в camelCase). Но в моем случае это не сработало, тем более я хотел чтобы видео не воспроизводилось при загрузке страницы а только когда наживаем кнопку play и видео переходит в полноэкранный режим.
Если вы хотите перейти в полноэкранный режим то придется написать код для проверки браузера, так как каждый браузер поддерживает свой метод. В том числе и Safari для IOS (Safari для iPhone не поддерживают некоторые фичи старшего брата):
enterFullScreen() {
const elem = this.view.player;
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.webkitRequestFullscreen) {
/* Safari */
elem.webkitRequestFullscreen();
} else if (elem.webkitEnterFullscreen) {
/* Safari */
elem.webkitEnterFullscreen();
} else if (elem.msRequestFullscreen) {
/* IE11 */
elem.msRequestFullscreen();
} else if (elem.mozRequestFullScreen) {
/* Mozila */
elem.mozRequestFullScreen();
}
if (elem.fullscreenElement === null) {
this.view.player.pause();
this.view.player.controls = false;
}
}
Чтобы выйти из полноэкранного режима на iPhone и iPad через свайп назад, то придется также написать функцию для остановки видео при выходе. Если вы хотите чтобы не было видно панель с управлением видео, то при выходе из полноэкранного режима вам нужно указать playsinline="false"
, иначе будут видны стандартные элементы управления:
checkFullScreen() {
if (isTouch) {
if (document.fullscreenElement) {
this.view.player.play();
} else {
this.view.player.pause();
}
} else {
if (document.fullscreenElement) {
this.view.player.controls = true;
} else {
this._checkPaused();
this._checkMute();
this.view.player.controls = false;
}
}
}
Также ниже код для реализации панели с управлением видео:
start() {
const playPromise = this.view.player.play();
if (playPromise !== undefined) {
playPromise
.then(() => {
// Automatic playback started!
// Show playing UI.
})
.catch((e: any) => {
// Auto-play was prevented
// Show paused UI.
if (e.code === 9) {
this.view.loader.classList.add('hide');
this.handleVideoError();
}
});
}
this.view.pause.style.display = 'block';
this.view.play.style.display = 'none';
this.startEvent.emit(null);
}
startMobile() {
this.enterFullScreen();
this.view.player.play();
this.startEvent.emit(null);
}
stop() {
this.view.player.pause();
this.view.play.style.display = 'block';
this.view.pause.style.display = 'none';
this.stopEvent.emit(null);
}
rewind(percent: number) {
this.view.player.currentTime = percent * this.view.player.duration;
}
mute() {
this.view.player.muted = true;
this.view.unmuted.style.display = 'none';
this.view.muted.style.display = 'block';
}
unmute() {
this.view.player.muted = false;
this.view.muted.style.display = 'none';
this.view.unmuted.style.display = 'block';
}
trackingTime() {
this.view.value.style.width = `${(100 * this.view.player.currentTime) / this.view.player.duration}%`;
}
rewindClick(e: MouseEvent) {
this.rewind(this._getDistance(e.clientX));
}
getDistance(x: number): number {
return (x - this.view.progress.getBoundingClientRect().x) / this.view.progress.getBoundingClientRect().width;
}
Вот и все, проблема решена.