JS实现预加载视频音频/视频获取截图(返回canvas截图)

yizhihongxing

下面是“JS实现预加载视频音频/视频获取截图(返回canvas截图)”的完整攻略。

一、准备工作

首先要在HTML文件中引入jQuery和video.js库:

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/7.15.4/video.min.js"></script>

二、预加载视频音频

使用 video.js 加载音频视频,并设置 preload 属性为 auto,实现自动加载。

<video id="myvideo" class="video-js vjs-default-skin" preload="auto" width="640" height="264">
  <source src="your_video_path.mp4" type="video/mp4" />
  <source src="your_video_path.webm" type="video/webm" />
  <source src="your_video_path.ogg" type="video/ogg" />
</video>

三、截取视频画面生成图片

视频截图需要依赖 canvas,截图需要在视频播放前或者播放时执行。

1.添加一个空的canvas元素:

<canvas id="mycanvas"></canvas>

2.使用 video.js 开始播放:

const myPlayer = videojs('myvideo');
myPlayer.play();

3.在 video.js 中,提供了 createTimeRange() 方法,该方法用于自动创建表示整个视频的范围,并返回 TimeRanges 对象,该对象包含一系列范围和其长度。

针对 TimeRanges 移除有效的视频帧:

myPlayer.on('timeupdate', function() {
    const timeRanges = myPlayer.buffered();
    let bufferedTime = 0;

    // 遍历 TimeRanges 的长度
    for(let i = 0; i < timeRanges.length; i++) {
        bufferedTime += timeRanges.end(i) - timeRanges.start(i);
    }

    // 如果bufferedTime大于播放器的当前时间,表示已经加载完毕至少一个关键帧
    if(bufferedTime >= myPlayer.currentTime()) {

        //获取当前画面
        const $canvas = $('#mycanvas');
        const canvas = $canvas[0];

        const ctx = canvas.getContext('2d');

        canvas.width = myPlayer.videoWidth()
        canvas.height = myPlayer.videoHeight()
        ctx.drawImage(myPlayer.el(), 0, 0, canvas.width, canvas.height);

        // 获取 canvas 截图数据
        const dataURL = canvas.toDataURL();
        console.log(dataURL);
    }
})

在每一帧播放时间改变的时候,使用 canvas 抓取出当前帧的图片,并利用 toDataURL() 方法获取图片数据。

示例

示例一

一个基于 video.js + jQuery 的简单应用,预加载音频视频,开始播放后实时截取视频画面并生成图片。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Video screenshot</title>
  <link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet" />
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://vjs.zencdn.net/7.15.4/video.min.js"></script>
</head>

<body>
  <button id="btn">Capture</button>
  <br>
  <video id="myvideo" class="video-js vjs-default-skin" preload="auto" width="640" height="264">
    <source src="https://vjs.zencdn.net/v/oceans.mp4" type="video/mp4" />
  </video>
  <canvas id="mycanvas"></canvas>

  <script>
    $(function() {
      const myPlayer = videojs('myvideo');
      myPlayer.play();

      myPlayer.on('timeupdate', function() {
        const timeRanges = myPlayer.buffered();
        let bufferedTime = 0;

        for(let i = 0; i < timeRanges.length; i++) {
          bufferedTime += timeRanges.end(i) - timeRanges.start(i);
        }

        if(bufferedTime >= myPlayer.currentTime()) {
          const $canvas = $('#mycanvas');
          const canvas = $canvas[0];

          const ctx = canvas.getContext('2d');

          canvas.width = myPlayer.videoWidth()
          canvas.height = myPlayer.videoHeight()
          ctx.drawImage(myPlayer.el(), 0, 0, canvas.width, canvas.height);

          const dataURL = canvas.toDataURL();
          console.log(dataURL);
        }
      })


      $('#btn').on('click', function () {
        const dataURL = canvas.toDataURL();
        const url = window.URL.createObjectURL(dataURL);

        const a = document.createElement('a');
        document.body.append(a);
        a.href = url;
        a.download = 'screenshot.png';
        a.click();

        setTimeout(() => {
          window.URL.revokeObjectURL(url);
          a.remove();
        }, 100)
      })
    });
  </script>
</body>

</html>

示例二

一个基于 video.js + Vue.js 的全功能应用,预加载音频视频,开始播放后实时截取视频画面并生成图片。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Video screenshot</title>
  <link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet" />
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://vjs.zencdn.net/7.15.4/video.min.js"></script>
</head>

<body>
  <div id="app">
    <div class="controls">
      <button @click="play" :disabled="playing">播放</button>
      <button @click="pause" :disabled="!playing">暂停</button>
      <button @click="capture" :disabled="!playing">截屏</button>
    </div>
    <div class="player-container">
      <video id="myvideo" class="video-js vjs-default-skin" preload="auto" v-bind:width="width" v-bind:height="height">
        <source v-bind:src="src" type="video/mp4" />
      </video>
      <canvas id="mycanvas" class="player-canvas"></canvas>
    </div>
  </div>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        src: 'https://vjs.zencdn.net/v/oceans.mp4',
        width: 640,
        height: 264,
        playing: false,
      },
      computed: {
        videoPlayer: function() {
          return videojs('myvideo')
        }
      },
      methods: {
        play() {
          this.videoPlayer.play()
          this.playing = true;
        },
        pause () {
          this.videoPlayer.pause()
          this.playing = false;
        },
        capture() {
          const $canvas = $('#mycanvas');
          const canvas = $canvas[0];
          const ctx = canvas.getContext('2d');
          const video = this.videoPlayer.el();

          canvas.width = video.videoWidth;
          canvas.height = video.videoHeight;

          ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

          const dataURL = canvas.toDataURL();
          console.log(dataURL);
        },
      },
      mounted() {
        this.videoPlayer.play();
        this.playing = true;

        this.videoPlayer.on('timeupdate', function() {
          const timeRanges = this.buffered();
          let bufferedTime = 0;

          for(let i = 0; i < timeRanges.length; i++) {
            bufferedTime += timeRanges.end(i) - timeRanges.start(i);
          }

          if(bufferedTime >= this.currentTime()) {
            const $canvas = $('#mycanvas');
            const canvas = $canvas[0];
            const ctx = canvas.getContext('2d');
            const video = this.el();

            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;

            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
          }
        });
      }
    })
  </script>
</body>

</html>

四、总结

以上就是本次攻略的完整内容,通过上述步骤可以轻松地预加载音频视频并实现获取视频截图的功能,同时,两个示例也提供了帮助我们更加快速高效完成音视频处理工作的方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS实现预加载视频音频/视频获取截图(返回canvas截图) - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • 判断div滑动到底部的scroll实例代码

    要判断一个div是否滑动到底部,需要监听它的滚动事件,该事件触发时,可以通过判断scrollHeight和scrollTop之和是否等于clientHeight来判断是否滑动到底部。下面是完整的markdown格式文本示例代码: HTML代码 <div id="myDiv" style="height: 200px; ov…

    css 2023年6月10日
    00
  • 导航跟随滚动条置顶移动示例代码

    要实现导航跟随滚动条置顶移动,需要使用JavaScript来监听滚动事件,根据滚动条位置和导航栏高度来动态改变导航栏的样式和位置。 下面为您提供一份完整的攻略,让您轻松实现这一功能。 准备工作 首先需要在HTML文件中引入jQuery库和自己编写的JavaScript文件。 <script src="https://cdn.bootcdn.n…

    css 2023年6月10日
    00
  • 如何用css3实现switch组件开关的方法

    如何用CSS3实现Switch组件开关的方法 Switch组件开关是一种常见的UI组件,它可以用于控制开关状态的切换。在CSS3中,可以使用伪元素和过渡效果来实现Switch组件开关的效果。本攻略将详细讲解如何用CSS3实现Switch组件开关的方法,并提供两个示例说明。 1. CSS3实现Switch组件开关的方法 1.1. 使用伪元素 可以使用伪元素来实…

    css 2023年5月18日
    00
  • 遗迹灰烬重生武器有哪些 武器、套装与特性收集攻略

    遗迹灰烬重生武器攻略 一、遗迹灰烬重生武器介绍 遗迹灰烬重生是《原神》中的一个重要活动,其中最重要的奖励之一就是遗迹灰烬重生武器。在这个活动中,你可以通过完成任务、挑战宝箱和购买商品等方式获得遗迹灰烬重生装备和材料。 二、遗迹灰烬重生武器种类 在遗迹灰烬重生活动中,一共有7种不同的武器可以获得,分别是: 狼的末路 天空之刃 邪神之死 龙脊长弓 狂沙裂斩 冰风…

    css 2023年6月10日
    00
  • 详解使用mocha对webpack打包的项目进行”冒烟测试”的大致流程

    Mocha是一个用于Node.js和浏览器的JavaScript测试框架。它提供了简单明了的描述测试的语法,并且支持异步测试和回调测试。在实际的项目中,我们常常需要对Webpack打包的项目进行“冒烟测试”,以确保所有模块能够正确加载、所有依赖关系链接正确等。下面是详解使用Mocha对Webpack打包的项目进行”冒烟测试”的大致流程: 步骤一:安装Moch…

    css 2023年6月10日
    00
  • 详解jQuery移动页面开发中的ui-grid网格布局使用

    详解jQuery移动页面开发中的ui-grid网格布局使用 什么是ui-grid网格布局? ui-grid是jQuery Mobile框架中提供的一种网格布局方式,用于将页面内容按照网格布局方式进行排列,通常用于移动设备的页面开发中。 如何使用ui-grid网格布局? 在HTML代码中定义ui-grid网格布局。 <div class="ui…

    css 2023年6月11日
    00
  • CSS通过RGBa将一个元素设置为透明效果

    首先,我们来了解一下RGBa的基本概念。 RGBa是一种CSS的颜色表示方式,可以给一个元素设置透明度。其中,RGB代表红、绿、蓝三种颜色,a代表alpha透明度。a的取值范围是0~1,0表示完全透明,1表示完全不透明。因此,RGBa的语法为:rgba(red, green, blue, alpha),其中red、green、blue三个参数分别表示红、绿、…

    css 2023年6月9日
    00
  • CSS3 伪类选择器 nth-child()说明

    CSS3 的伪类选择器之一是nth-child(),其作用是筛选出一组兄弟元素中,特定位置的那一个。 语法说明 对某个元素所进行的选取规则为: :nth-child([<an+b>]) 解释如下: n表示从等差数列的第一个数开始,共有多少个数,从0开始计算。 an+b表示等差数列的公式,其中a和b为自然数,且满足条件0 ≤ b < a。 用…

    css 2023年6月9日
    00
合作推广
合作推广
分享本页
返回顶部