如何在全屏模式下显示自定义视频控件

How to display custom video controls even in fullscreen

更新:无法在 Firefox 中正常运行:(

如何在现代浏览器的全屏模式下显示自定义视频控件?

我一进入全屏,它们就消失了。我希望它们可用,然后我会写一些 JavaScript 以在不活动时隐藏它们并在有人摆动鼠标时显示它们。

HTML:

<video#video src="vid.mp4" preload poster="/images/poster.jpg">
  <iframe src="https://youtube.com/embed/id" frameborder="0" allowfullscreen>
</video>

JS:

var bigPlayButton = document.getElementById('big-play-button')
var video = document.getElementById('video')
var playPauseButton = document.getElementById('play-pause')
var fullscreen = document.getElementById('fullscreen')

function toggleFullScreen() {
  if (!document.fullscreenElement) {
      document.documentElement.requestFullscreen()
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen()
    }
  }
}

fullscreen.addEventListener('click', function (event) {
  if (!video.classList.contains('fullscreen')) {
    video.requestFullscreen()
  } else {
    document.exitFullscreen()
  }
}, false)

// Detect FullScreen changes and adjust button
document.addEventListener('fullscreenchange', function (event) {
  if (document.fullscreenElement) {
    fullscreen.children[0].src = '/images/nofullscreen.svg'
    video.classList.add('fullscreen')
  } else {
    fullscreen.children[0].src = '/images/fullscreen.svg'
    video.classList.remove('fullscreen')
  }
}, false)

CSS

video::-webkit-media-controls {
  display: none !important;
}
#custom-video-controls {
  z-index: 2147483648;
}

我正在使用这个 polyfill:https://github.com/neovov/Fullscreen-API-Polyfill

编辑

重大变化是针对父标签:.vidFrame 全屏而不是凯多评论中的 <video> 标签。


HTML5 如果您想覆盖视频控件,则需要对其进行特殊处理。我假设您想这样做,因为控件中已经内置了全屏功能。该演示实现:

  • classList 用于切换 .on.offbutton#fullScreen 状态以及 .play.pausebutton#playPause 状态.
  • :fullscreen 伪 class 以确保 .vidBar 在全屏模式下位于底部。
  • Shadow DOM CSS 覆盖本机播放器控件所需的样式。
  • Fullscreen API 当然是供应商特定的进入和退出全屏模式的方法。
  • 没有音量滑块、静音按钮或进度条,只有全屏按钮 (button#fullScreen) 和播放按钮 (button#playPause)。如果你想要它们,请再问一个问题。
  • 详细信息在源代码中进行了注释。

该代码段似乎功能不全,所以这里有一个功能性的 Plunker. If that version cannot be reached, then review the embedded Plunker,然后单击完整视图按钮:


演示

注意:SO 沙箱已更改,因此该演示无法完全正常运行,请转到前面提到的链接或将演示复制并粘贴到文本编辑器中。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Full Screen Video Toggle</title>
<style>
.vidFrame { position: relative; top: 10%; width: 320px; height: auto; min-height: 180px; outline: 1px dashed red; }
.vidBar { position: absolute; bottom: 0; right: 0; left: 0; height: 40px; width: 99%; }

#fullScreen { position: absolute; bottom: 0; right: 0; width: 36px; height: 36px; outline: none; border: 1px solid transparent; border-radius: 6px; display: block; cursor: pointer; }

#fullScreen:hover { border: 1px groove #0ef; }
.on, .off { background: url('https://i.imgur.com/0FTwh6M.png') no-repeat; width: 36px; height: 36px; }
.off { background-position: 0 0 }
.on { background-position: -1px -50px }

#playPause { position: absolute; bottom: 0; left: 0; width: 36px; height: 36px; background: none; font-size: 36px; color: #0ff; line-height: 1; border: 1px solid transparent; display: block; cursor: pointer; outline: none; }
#playPause.play:before { content: 'b6'; }
#playPause.pause:before { content: '5a5a'; }

.vid { position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: auto; display: block; z-index: 1; outline: 1px dotted blue; }
/* 
Fullscreen Pseudo-class: 
https://developer.mozilla.org/en-US/docs/Web/CSS/:fullscreen 
*/
.vidBar:-moz-full-screen { position: fixed; }
.vidBar:-webkit-full-screen { position: fixed; }
.vidBar:-ms-fullscreen { position: fixed; }
.vidBar:fullscreen { position: fixed; }
/* 
Special Shadow DOM Settings to Override Default Controls: 
https://css-tricks.com/custom-controls-in-html5-video-full-screen/ 
*/
video::-webkit-media-controls-enclosure { display:none !important; }
.vidBar { z-index: 2147483648; }
</style>
</head>

<body>
<figure class="vidFrame">
  <video id="vid1" class="vid" src="http://techslides.com/demos/sample-videos/small.mp4"></video>
  <figcaption class="vidBar">
    <button id='playPause' class="play" title="Play/Pause Video"></button>
    <button id='fullScreen' class="on" title="Enter/Exit Full Screen"></button>
  </figcaption>
</figure>
<script>

/* 
Toggle Button with classList: 
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList 
*/
var fullBtn = document.getElementById('fullScreen');
var playBtn = document.getElementById('playPause');

playBtn.addEventListener('click', function(event) {
  var player = document.getElementById('vid1');

  if(player.paused) {
    playBtn.classList.remove('play');
    playBtn.classList.add('pause');
    player.play();
  } else {
    playBtn.classList.add('play');
    playBtn.classList.remove('pause');
    player.pause();
  }
}, false);

fullBtn.addEventListener('click', function(event) {
  var tgtEle = document.querySelector('.vidFrame');
  var  onOrOff = fullBtn.classList.contains('on');

  if (onOrOff) {
    enterFS(tgtEle);
    fullBtn.classList.remove('on');
    fullBtn.classList.add('off');
  } else {
    exitFS();
    fullBtn.classList.add('on');
    fullBtn.classList.remove('off');
  }
}, false);

/*
Fullscreen API:
https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
*/
function enterFS(element) {
  if (element.requestFullscreen) {
    element.requestFullscreen();
  } else if (element.msRequestFullscreen) {
    element.msRequestFullscreen();
  } else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen();
  } else if (element.webkitRequestFullscreen) {
    element.webkitRequestFullscreen();
  }
}

function exitFS() {
  if (document.exitFullscreen) {
    document.exitFullscreen();
  } else if (document.msExitFullscreen) {
    document.msExitFullscreen();
  } else if (document.mozCancelFullScreen) {
    document.mozCancelFullScreen();
  } else if (document.webkitExitFullscreen) {
    document.webkitExitFullscreen();
  }
}
</script>
</body>
</html>

在容器元素上使用全屏API,而不是在视频上

正如@Kaiido 在评论中所说:

You have to call the enterFS method on the container element, not on the video one.

所以答案是在容器元素上使用 Fullscreen API 而不是 <video> 元素。这允许在该容器中提供自定义控件,该容器现在全屏显示。

供参考,即问题中现有的 enterFS() 函数:

function enterFS(element) {
  if (element.requestFullscreen) {
    element.requestFullscreen();
  } else if (element.msRequestFullscreen) {
    element.msRequestFullscreen();
  } else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen();
  } else if (element.webkitRequestFullscreen) {
    element.webkitRequestFullscreen();
  }
}

我发布这个答案是因为我必须阅读该页面三遍才能弄清楚这里发生了什么。

@zer00ne 的回答中有很多信息与其他有类似问题的人相关,但它没有直接回答@Costa 的原始问题,该问题以前只在评论中回答过。