Canvas+Video打造酷炫播放体验

本文介绍了如何使用HTML5的video元素和Canvas进行视频播放和处理。通过具体代码实例展示了如何利用Canvas对视频进行实时捕获及处理,包括视频画面的缩放、倒置等效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

image

一.简介

直到现在,仍然不存在一项旨在网页上显示视频的标准。

今天,大多数视频是通过插件(比如 Flash)来显示的。然而,并非所有浏览器都拥有同样的插件。

HTML5 规定了一种通过 video 元素来包含视频的标准方法。如:

1
2
< video  src="movie.ogg" controls="controls">
</ video >

 

 

二.Canvas+Video

HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。

drawImage函数有三种函数原型:

drawImage(image, dx, dy) 
drawImage(image, dx, dy, dw, dh) 
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

第一个参数image可以用HTMLImageElement,HTMLCanvasElement或者HTMLVideoElement作为参数

dx和dy是image在canvas中定位的坐标值;dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值;

sx和sy是image所要绘制的起始位置,sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值。

所以这使酷炫播放体验有了实现的可能。

 

 

三.理解canvas.translate和canvas.scale

很多人对于canvas.translate(x,y)的理解有的错误,之前一直以原点(0,0)为基准点,作用就是移动原点,默认的原点(0,0)是在屏幕左上角的,你可以通过translate(x,y)把点(x,y)作为原点,就一直以为这个(x,y)就是新的坐标原点。但看一下API就会知道,这种理解是不对的,

不过API确实容易误导大家:

1
2
3
4
5
6
7
view plain
public  void  translate ( float  dx, float  dy) 
  Since: API Level 1 
Preconcat the current matrix with the specified translation 
Parameters 
dx  The distance to translate in X 
dy  The distance to translate in Y


其实是原来的原点分别在x轴和y轴偏移多远的距离,然后以偏移后的位置作为坐标原点。也就是说原来在(100,100),然后translate(1,1)新的坐标原点在(101,101)而不是(1,1)

canvas.scale:

canvas.scale提供了放大缩小倒置等功能。比如Y倒置:canvas.scale(1,-1)

 

 

四.核心代码

1
2
3
4
5
6
7
canvas.setAttribute( 'height' , Math. floor (video.height));
       canvas.setAttribute( 'width' , Math. floor (video.width));
 
       ctx.translate(0, canvas.height );
       ctx.scale(1, -1);
       ctx.globalAlpha = 0.3;
       ctx.drawImage(video, 0, 0, video.width, video.height, 0, -canvas.height/2, canvas.width, canvas.height);

 

 

五.在线演示

 
  00:00 /

 

 

 

 

 

 

 

 

六.代码下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
< html  >
< head >
< meta  charset="utf-8" />
< title ></ title >
 
</ head >
< body >
    < div >
    < video   width="640" height="264">
     < source  src="http://video-js.zencoder.com/oceans-clip.mp4" >
     < source  src="http://video-js.zencoder.com/oceans-clip.webm" >
   </ video > < br />
   < canvas  style="position:absolute; top:143px;"></ canvas >
</ div >
< div   style="position:absolute; top:400px;">
   < p >
     < input  type="button" id="play" value="play">
     < span  id="position">00:00</ span > / < span  id="duration"></ span >
   </ p >
   </ div >
< script  >
 
     var addEvent = (function () {
         if (document.addEventListener) {
             return function (el, type, fn) {
                 if (el && el.nodeName || el === window) {
                     el.addEventListener(type, fn, false);
                 } else if (el && el.length) {
                     for (var i = 0; i < el.length ; i++) {
                         addEvent(el[i], type, fn);
                     }
                 }
             };
         } else {
             return function (el, type, fn) {
                 if (el && el.nodeName || el === window) {
                     el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
                 } else if (el && el.length) {
                     for (var i = 0; i < el.length; i++) {
                         addEvent(el[i], type, fn);
                     }
                 }
             };
         }
     })();
    
</script>
< script >
     var video = document.querySelector('video');
     var togglePlay = document.querySelector('#play');
     var position = document.querySelector('#position');
     var canvas = document.querySelector('canvas');
     var ctx = canvas.getContext('2d');
 
     addEvent(togglePlay, 'click', function () {
         video.playbackRate = 0.5;
         if (video.paused) {
             if (video.ended) video.currentTime = 0;
             video.play();
             this.value = "pause";
         } else {
             video.pause();
             this.value = "play";
         }
     });
 
     setInterval(function () {
         position.innerHTML = asTime(video.currentTime);
         ctx.drawImage(video, 0, 0, video.width, video.height, 0, -canvas.height / 2, canvas.width, canvas.height);
     }, 1000 / 15);
 
     addEvent(video, 'ended', function () {
         togglePlay.value = "play";
     });
 
     addEvent(video, 'canplay', function () {
         video.muted = true;
         document.querySelector('#duration').innerHTML = asTime(this.duration);
         startCanvas();
     });
 
 
     function startCanvas() {
         canvas.setAttribute('height', Math.floor(video.height));
         canvas.setAttribute('width', Math.floor(video.width));
 
         ctx.translate(0, canvas.height );
         ctx.scale(1, -1);
         ctx.globalAlpha = 0.3;
         ctx.drawImage(video, 0, 0, video.width, video.height, 0, -canvas.height/2, canvas.width, canvas.height);
 
       
     }
 
     function asTime(t) {
         t = Math.round(t);
         var s = t % 60;
         var m = Math.round(t / 60);
 
         return two(m) + ':' + two(s);
     }
 
     function two(s) {
         s += "";
         if (s.length < 2 ) s = "0" + s;
         return s;
     }
</script>
</ body >
 
</ html >

转载于:https://www.cnblogs.com/yulei126/p/6756242.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值