HTML深度探索 :video应用与实践


1、定义和用法

  • <video> 标签用于在文档中嵌入媒体播放器,例如电影片段或其他视频流。
  • <video> 标签包含一个或多个带有不同视频源的 <source> 标签。浏览器将选择它支持的第一个源。<video></video> 标签之间的文本只会在不支持 <video> 元素的浏览器中显示。

示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <video width="400" height="300" controls>
        <source
            src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
            type="video/mp4">
        您的浏览器不支持视频标签。
    </video>
</body>

</html>

在这里插入图片描述

  • 上面的例子展示了 <video> 元素的简单用法。和 <img> 元素的使用类似,在 src 属性里加入一个我们需要展示的视频地址,同时也可以用其他属性来指定视频的宽度和高度、是否自动或者循环播放、是否展示浏览器默认的视频控件等。
  • 在不支持 video 元素的浏览器中,<video></video> 标签中间的内容会显示,作为降级处理。

2、视频格式

  • HTML 支持三种视频格式:MP4、WebM 和 OGG。:

    • MP4 (MPEG-4 Part 14) - 这是使用最广泛的视频格式之一,通常使用H.264视频编码和AAC音频编码。由于其广泛的支持和良好的压缩效率,MP4在各种设备和平台上都表现良好。
    • WebM - 这是一种开放的、免版税的媒体容器格式,由Google主导开发。它支持VP8或VP9视频编码和Vorbis或Opus音频编码。WebM的目标是提供一种高质量、开放标准的视频格式,特别适合网络使用。
    • OGG - 虽然OGG本身是一个容器格式,但在此上下文中,它通常指的是使用Theora视频编码和Vorbis音频编码的OGG文件。OGG也是开放且免版税的,但它的支持不如MP4广泛。
  • 在使用<video>标签时,你可以指定多个source元素来提供不同格式的视频源,这样浏览器可以选择最适合其平台的格式。例如:

<video controls>
  <source src="myVideo.mp4" type="video/mp4">
  <source src="myVideo.webm" type="video/webm">
  <source src="myVideo.ogg" type="video/ogg">
  Your browser does not support the video tag.
</video>

3、常用属性

  • src – 要嵌到页面的视频的 URL。可选;你也可以使用 video 块内的 元素来指定需要嵌到页面的视频。

  • autoplay – 一个布尔属性;声明该属性后,视频会尽快自动开始播放,不会停下来等待数据全部加载完成。

自动播放音频(或有声视频)可能会破坏用户体验,所以应该尽可能避免。如果你一定要提供自动播放功能,你应该加入开关(让用户主动打开自动播放)。
在某些浏览器(例如 Chrome 70.0)中,如果没有设置 muted 属性,autoplay 将不会生效。

  • controls – 如果存在该属性,浏览器会在视频底部提供一个控制面板,允许用户控制视频的播放,包括音量、拖动进度、暂停或恢复播放。

  • controlslist – 当浏览器显示视频底部的播放控制面板(例如,指定了 controls 属性)时,controlslist 属性会帮助浏览器选择在控制面板上显示哪些 video 元素控件。允许的值有 nodownload、nofullscreen 和 noremoteplayback。如果要禁用画中画模式(和控件),请使用 disablepictureinpicture 属性。

无controls

<video
     src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        width="400" height="300">
</video>

在这里插入图片描述
含controls

<video
	src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        width="400" height="300" controls>
</video>

在这里插入图片描述
含controls且含controlslist

<video
    src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        width="400" height="300" controls controlsList="nodownload nofullscreen">
</video>

在这里插入图片描述

  • height – 视频显示区域的高度,单位是 CSS 像素(仅限绝对值;不支持百分比)。

  • width – 视频显示区域的宽度,单位是 CSS 像素(仅限绝对值;不支持百分比)。

  • loop – 一个布尔属性;指定后会在视频播放结束的时候,自动返回视频开始的地方,继续播放。

  • muted – 一个布尔属性,指明在视频中音频的默认设置。设置后,音频会初始化为静音;默认值是 false。

  • playsinline – 一个布尔属性,指明视频将内嵌(inline)播放,即在元素的播放区域内。

  • poster – 海报帧图片 URL,用于在视频处于下载中的状态时显示。如果未指定该属性,则在视频第一帧可用之前不会显示任何内容,然后将视频的第一帧会作为海报(poster)帧来显示。

  • preload – 该枚举属性旨在提示浏览器,作者认为在播放视频之前,加载哪些内容会达到最佳的用户体验。可能是下列值之一:

    • none: 表示不应该预加载视频。
    • metadata: 表示仅预先获取视频的元数据(例如长度)。
    • auto: 表示可以下载整个视频文件,即使用户不希望使用它。
    • 空字符串: 与 auto 值一致。

autoplay 属性的优先级比 preload 高。如果指定了 autoplay 属性,浏览器显然需要开始下载视频以便回放。

4、常用事件

canplay – 当浏览器认为视频数据加载得足够多时触发,此时视频可以开始播放而不发生停顿(尽管可能还没有达到视频的开头)。

canplaythrough – 当浏览器认为视频数据加载得足够多,以至于可以播放到结束而不会发生停顿时触发。

ended – 视频停止播放,因为媒体已经到达结束点。

error – 当视频加载或播放过程中发生错误时触发。

loadstart – 浏览器开始加载资源时触发。

pause – 播放已暂停。

play – 播放已开始。

progress – 当浏览器正在下载视频数据时触发。

waiting – 当视频暂停以等待更多数据时触发。

volumechange – 当视频音量改变时触发。

举例

  • 点击页面任意区域触发视频播放
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Click to Play Video</title>
</head>

<body>
    <video
        src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        id="myVideo" width="400" height="300" controls muted>
    </video>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const videoElement = document.getElementById('myVideo');

            // 添加 click 事件监听器
            document.addEventListener('click', function (event) {
                // 检查是否点击的是视频以外的区域
                if (event.target !== videoElement) {
                    // 尝试播放视频
                    videoElement.play()
                        .catch(error => {
                            console.error('播放失败,可能是因为浏览器限制自动播放', error);
                        });
                }
            });
        });
    </script>
</body>

</html>
  • 视频出现在视口自动播放
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Auto Play Video on Scroll</title>
    <style>
        body,
        html {
            height: 2000px;
            /* 为了模拟滚动效果 */
        }

        #myVideo {
            position: relative;
            top: 1000px;
            /* 将视频放置在页面较远的位置,以便滚动 */
        }
    </style>
</head>

<body>
    <video
        src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        id="myVideo" width="400" height="300" controls muted>
    </video>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const videoElement = document.getElementById('myVideo');
            const observer = new IntersectionObserver((entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        // 当元素与视口交叠时播放视频
                        videoElement.play().catch(error => {
                            console.error('播放失败', error);
                        });
                    } else {
                        // 当元素离开视口时暂停视频
                        videoElement.pause();
                    }
                });
            }, {
                threshold: 0.5 // 可以调整这个值来改变何时开始播放
            });

            // 开始观察video元素
            observer.observe(videoElement);
        });
    </script>
</body>

</html>
  • 视频监听
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Click to Play Video</title>
</head>

<body>
    <video
        src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        id="myVideo" width="400" height="300" controls muted>
    </video>

    <script>
        const video = document.getElementById('myVideo');

        // 监听 'play' 事件
        video.addEventListener('play', function () {
            console.log('视频开始播放');
        });

        // 监听 'pause' 事件
        video.addEventListener('pause', function () {
            console.log('视频暂停');
        });

        // 监听 'ended' 事件
        video.addEventListener('ended', function () {
            console.log('视频播放结束');
        });

        // 监听 'timeupdate' 事件
        video.addEventListener('timeupdate', function () {
            console.log('当前播放时间:', video.currentTime);
        });
    </script>
</body>

</html>

5、预加载和懒加载

5.1 预加载

  • 预加载是指在页面加载时就开始加载视频数据,即使视频尚未开始播放。预加载有助于确保视频在用户决定观看时能够快速播放,避免播放延迟。预加载的程度可以通过<video>标签的preload属性来控制
<video controls preload="auto">
  <source src="myVideo.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>

4.2 懒加载

  • 懒加载是指在视频进入视口(即成为可见元素)之前不加载视频数据。这有助于节省带宽和资源,尤其是在移动设备上。
  • 需要注意的是,懒加载在一些浏览器中可能需要额外的属性或技巧来确保正确工作,特别是对于视频。例如,你可能需要使用poster属性指定一个封面图片,这样在视频数据加载之前,用户可以看到这个静态图像。此外,使用Intersection Observer API来手动控制加载时机也是一种常见的懒加载策略。
  • 使用Intersection Observer API来控制多个视频的懒加载是一种高效的方式,可以确保视频只在进入视口时才开始加载,从而提高页面性能。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Multiple Videos Lazy Loading with Intersection Observer</title>
    <style>
        body,
        html {
            height: 2000px;
        }

        video {
            position: relative;
            top: 500px;
            /* 将视频放置在页面较远的位置,以便滚动 */
        }

        .lazy-video {
            margin-bottom: 40px;
        }
    </style>
</head>

<body>

    <!-- 多个视频元素 -->
    <video class="lazy-video"
        poster="https://res.insta360.com/static/945c643dc4679f38662000810f35a428/shoot-first-frame-later-PC.jpg"
        data-src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        src="" id="myVideo" width="400" height="300" controls muted>
    </video>
    <video class="lazy-video"
        poster="https://res.insta360.com/static/945c643dc4679f38662000810f35a428/shoot-first-frame-later-PC.jpg"
        data-src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        src="" id="myVideo" width="400" height="300" controls muted>
    </video>
    <video class="lazy-video"
        poster="https://res.insta360.com/static/945c643dc4679f38662000810f35a428/shoot-first-frame-later-PC.jpg"
        data-src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        src="" id="myVideo" width="400" height="300" controls muted>
    </video>
    <video class="lazy-video"
        poster="https://res.insta360.com/static/945c643dc4679f38662000810f35a428/shoot-first-frame-later-PC.jpg"
        data-src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        src="" id="myVideo" width="400" height="300" controls muted>
    </video>
    <video class="lazy-video"
        poster="https://res.insta360.com/static/945c643dc4679f38662000810f35a428/shoot-first-frame-later-PC.jpg"
        data-src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        src="" id="myVideo" width="400" height="300" controls muted>
    </video>
    <video class="lazy-video"
        poster="https://res.insta360.com/static/945c643dc4679f38662000810f35a428/shoot-first-frame-later-PC.jpg"
        data-src="https://media.insta360.com/static/999ed572050c0e518970399a3c6e2899/shoot%20first%20frame%20later%20PC.mp4"
        src="" id="myVideo" width="400" height="300" controls muted>
    </video>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const lazyVideos = document.querySelectorAll('.lazy-video');

            const observer = new IntersectionObserver((entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const video = entry.target;
                        video.src = video.dataset.src;
                        video.preload = 'auto';
                        video.load();
                        video.play().catch(error => {
                            console.error('播放失败', error);
                        });
                        observer.unobserve(video); // 视频加载后停止观察
                    }
                });
            }, {
                rootMargin: '0px',
                threshold: 0.5 // 可以调整这个值来改变何时开始加载
            });

            // 开始观察所有video元素
            lazyVideos.forEach(video => observer.observe(video));
        });
    </script>
</body>

</html>
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会思想的苇草i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值