由于视频播放器加载mp4视频需要时间,HTML5是否支持在加载视频时播放“加载中”标志?
由于我的asp.net应用程序是一个移动页面,它需要用户点击视频来播放视频(android、iphone不支持自动播放)。所以,我不能将“正在加载”标志制作为海报,否则用户会对此感到困惑。我想在用户单击 iPad 上的播放按钮时显示加载徽标。
谢谢
乔
我花了很长时间才真正弄清楚如何做到这一点,但我要在这里分享它,因为我终于找到了一种方法!仔细想想,这很荒谬,因为加载是所有视频都必须做的事情。您可能认为他们在创建 html5 视频标准时会考虑到这一点。
我认为应该有效(但不会)的原始理论是这样的
很简单吧?问题是,当设置源元素或设置 video.src 属性时,我无法显示背景图像。天才/幸运的最后一击是发现(通过实验)如果海报被设置为某种东西,背景图像将不会消失。我使用的是假海报图像,但我想它也可以与透明的 1x1 图像一起使用(但为什么担心有另一个图像)。因此,这可能是一种黑客攻击,但它有效,而且我不必向我的代码添加额外的标记,这意味着它可以在我使用 html5 视频的所有项目中工作。
HTML
<video controls="" poster="data:image/gif,AAAA">
<source src="yourvid.mp4"
</video>
CSS(用JS加载应用于视频的类)
video.loading {
background: black url(/images/loader.gif) center center no-repeat;
}
JS
$('#video_id').on('loadstart', function (event) {
$(this).addClass('loading');
});
$('#video_id').on('canplay', function (event) {
$(this).removeClass('loading');
$(this).attr('poster', '');
});
这对我来说非常有效,但仅在 mac 上的 chrome 和 safari 中进行了测试。如果有人发现错误或改进,请告诉我!
还有一个在加载视频时添加预加载器图像的简单解决方案: HTML:
<video class="bg_vid" autoplay loop poster="images/FFFFFF-0.png">
海报是1px的透明图片。
CSS:
video {
background-image: url(images/preload_30x30.gif);
background-repeat: no-repeat;
background-size: 30px 30px;
background-position: center;
}
使用标签 ID 海报
<video controls="controls" poster="/IMG_LOCATION/IMAGENAME">
您可以使用 JavaScript 创建一个带有动画“加载”gif 的图像叠加层来完成此操作,该图像仅在视频正在加载且未准备好播放时显示。
您必须编写 JavaScript 来与媒体 API 链接,以检测视频何时准备好播放等(这样您就可以再次隐藏图像),但这应该是可能的。
我的解决方案是在 window.fbAsyncInit = function() 中添加以下内容:
var finished_rendering = function() {
var el = document.querySelector('div#loading_msg');
el.style.display="none";
}
FB.Event.subscribe('xfbml.render', finished_rendering);
发现:https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/v2.12
对于那些需要或喜欢仅使用 js 而不使用 css 的人: 我们之所以被迫使用 css 背景而不是仅仅设置 GIF 作为视频海报,是因为 Safari 不会播放 GIF,只会显示 GIF 动画的第一帧。然而,我们希望能够通过不向用户显示静态框架来在每个平台上提供最佳的用户体验。
解决方法:
3 帧动画示例,
let base64StringForVideoPosterFrame1;
let base64StringForVideoPosterFrame2;
let base64StringForVideoPosterFrame3;
getFile1(); // Start the fetch chain
function getFile1() {
fetch("/images/video_poster_frames/video_poster_frame_1.png").then(response => response.blob()).then(blob => {
const reader = new FileReader();
reader.onload = () => { base64StringForVideoPosterFrame1 = reader.result.split(',')[1]; };
reader.readAsDataURL(blob);
}).catch(error => { console.error('Problem with fetch:', error); }).finally(() => { getFile2(); });
}
function getFile2() {
fetch("/images/video_poster_frames/video_poster_frame_2.png").then(response => response.blob()).then(blob => {
const reader = new FileReader();
reader.onload = () => { base64StringForVideoPosterFrame2 = reader.result.split(',')[1]; };
reader.readAsDataURL(blob);
}).catch(error => { console.error('Problem with fetch:', error); }).finally(() => { getFile3(); });
}
function getFile3() {
fetch("/images/video_poster_frames/video_poster_frame_3.png").then(response => response.blob()).then(blob => {
const reader = new FileReader();
reader.onload = () => { base64StringForVideoPosterFrame3 = reader.result.split(',')[1]; };
reader.readAsDataURL(blob);
}).catch(error => { console.error('Problem with fetch:', error); }).finally(() => { setPosters(); });
}
let posters = [];
function setPosters() {
posters = [
'data:image/png;base64,'+base64StringForVideoPosterFrame1,
'data:image/png;base64,'+base64StringForVideoPosterFrame2,
'data:image/png;base64,'+base64StringForVideoPosterFrame3
];
}
假设您的 HTML 中有 2 个视频,
// Note that you can extend this to cover every single video element by using getElementsByTagName("video")
const v1 = document.getElementById('video1');
const v2 = document.getElementById('video2');
// -
let currentPosterIndex = 0;
function changePoster() {
v1.poster = posters[currentPosterIndex];
v2.poster = posters[currentPosterIndex];
currentPosterIndex = (currentPosterIndex + 1) % posters.length; // Loop back to the beginning every time we reach the end
}
// Change poster every 333 milliseconds
setInterval(changePoster, 333);
在您的 HTML 中
<video src="myVideo.fileExtension" onplaying="hideControls(this)" onwaiting="showControls(this)" preload="auto" poster="">No video support?</video>
<script type="text/javascript">
//We hide the video control buttons and the playhead when the video is playing (and is enjoyed by the viewer)
function hideControls(event){ event.controls=false; }
//If the video has to pause and wait for data download from the server we let controls be seen whenever the user hovers or taps on the video. This also makes the built-in loading animation of the browser appear e.g. the rotating circular shape and we give it a little delay (like 1 sec) because we don't want the controls to blink and the delayed show-up actually looks nicer.
function showControls(event){ setTimeout(()=>{ event.controls=true; },1000); }
</script>
为了让它更好,你可以使用
ontimeupdate
代替 onplaying
,它会连续发射。
调整延迟时间以满足您的需求。
注意:如有必要,请检查您是否需要 playsinline 才能在 Safari 中正确处理视频
autoplay
。