Dynamically capture the frame display of vedio elements, click on the frame image to jump to playback video

Dynamically capture the frame display of vedio elements, click on the frame image to jump to playback video

illustrate

Create a simple video timing viewer. When the video is playing, it will periodically grab image frames from the video and draw them canvason When the user clicks canvason any frame displayed on the , the played video will jump to the corresponding point in time.

Video Timing Viewer

<video controls width="550px" height="310" id="video">
  <source src="./告白气球.mp4">
</video>
<canvas id="canvas"></canvas>

Among them video, canvasit is used to play the video and draw the captured frame picture. At this point, the video can be displayed, click to play to play, the next thing to do is to get the event processing function when you click to play, regularly capture pictures and draw them on canvasthe canvas

Note: autoplayThe attribute needs to cooperate with mutedthe attribute , otherwise it cannot be played automatically (because it is afraid that the automatic play will scare you to death, so it must be muted before it can be played automatically, which is very nice)

Dynamically capture vedio element frame display

The event handlers involved are:

  • The event handler for click to play isonplaying
  • The event handler for click pause isonpause
  • The event handler function for the end of video playback isonended
  • canvasWhen using video as the drawing source ( context.drawImage(video, picX, picY, picWidth, picHeight)), what is drawn is only the currently playing frame
<video controls width="550px" height="310" id="video" onplaying="startVideo()" onpause="clearTimer()" onended="clearTimer()">
  <source src="./告白气球.mp4">
</video>
let timer = null // 定时器(播放完需要清除)
const timerInterval = 1 // 抓取间隔 s
let picCount = 0 // 当前帧索引
let videoTime = 0 // 资源时长
const picWidth = 110
const picHeight = 62
const xCount = 12
let grid = 0

let canvas = document.querySelector('#canvas')
canvas.width = picWidth * xCount
canvas.style.background = 'beige'
context = canvas.getContext('2d')

let video = document.querySelector('#video')
let videoWidth = video.width
let videoHeight = video.height
video.volume = 0.3 // 设置音量
video.oncanplay = function () {
    
    
  videoTime = video.duration
  let yCount = Math.ceil(videoTime / timerInterval)
  grid = xCount * yCount
  canvas.height = picHeight * yCount
}

// 开始播放后开始抓图
function startVideo(){
    
    
  videoShot()
  timer = setInterval(videoShot, timerInterval * 1000)
}

// 将抓取的帧绘制到canvas上
function videoShot(){
    
    
  // %求余数
  // picCount: 0,1,2,3,4,....
  // picPostion: 0,1,2,3,4,...12,0,1,2,3,4,...12,...
  // picX: 0*110, 1*110, 2*110, 0*110,...
  // picY: 0, 0, 0, 300, 300, 300, 600, ...
  let picPostion = picCount % grid
  let picX = (picPostion % xCount) * picWidth
  let picY = (Math.floor(picPostion / xCount)) * picHeight
  context.drawImage(video, picX, picY, picWidth, picHeight)
  picCount++
}

// 播放结束
function clearTimer(){
    
    
  clearInterval(timer)
}

Note: The duration of obtaining resources video.durationneeds wait for the resources to be loadedvideo.oncanplay = function () { // 获取时长 }

Click the frame image to jump to playback video

// 开始播放后开始抓图
function startVideo(){
    
    
  if(timer) {
    
    
    clearTimer() // 清除定时器
  }
  videoShot()
  timer = setInterval(videoShot, timerInterval * 1000)
}

// 单击canvas上某一帧时定位到视频
canvas.onclick = function(e){
    
    
  let offX = e.offsetX - canvas.offsetLeft
  let offY = e.offsetY - canvas.offsetTop + 310 // 310 是video的高度

  // 点击的帧索引值
  let clickedFrame = Math.floor(offY / picHeight) * xCount
  clickedFrame += Math.floor(offX / picWidth)

  // 定位到指定帧位置
  video.currentTime = clickedFrame * timerInterval
  picCount = clickedFrame
}

Note: video.currentTimeIt will startVideo, so it needs to be judged startVideoin to clear the timer

Effect

Please add a picture description
insert image description hereMy Lun is handsome! ! !

The video resources are self-collected.

Guess you like

Origin blog.csdn.net/weixin_43443341/article/details/127065847