canvas+howler.js 解决同页面视频、音频同时播放问题

一直感觉canvas很神奇很有趣,趁最近项目少,拿前端之前做的一个静态项目试了下水深,个中的经验和体会记录如下。
1
一、横竖屏转换
1、canvas样式
#canvas {
width: 100%;
height: 100%;
top: 0;
left: 0;
display: block;
}
1
2
3
4
5
6
7
把canvas缩放定位到屏幕内,以宽高中较小的一边为准。
1
2、横竖屏处理
function config() {
winHeight = window.innerHeight;
winWidth = window.innerWidth;
if (winHeight > winWidth) { // 竖屏
canvas.width = 640;
canvas.height = 1030;
ctx.rotate(Math.PI/2);
ctx.translate(0, -canvas.width);
// posY = -canvas.width;
isVertical = true;
} else { // 横屏
isVertical = false;
canvas.width = 1030;
canvas.height = 640;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
以下敲黑板划重点
canvas画布和可视窗口是两个东西,为了搞明白这个花费了我很大的气力,目前是这么理解的:

姑且理解为可视窗口是个玻璃面板,canvas画布是张A4纸,实际在A4纸上画东西,如上图,旋转90°之后画布在窗口之外,画的东西就看不见了,ctx.translate(0, -canvas.width);相当于在画布上画了东西之后y方向上偏移了-canvas.width位置显示出来。也可以在每个元素绘画的时候y坐标+posY来处理。

在检测到屏幕旋转的时候只要再调用一下初始化的config()方法就可以了,挺方便。

window.onresize = function(){
config();
};
1
2
3
3、取点
touchstart/touchmove/touchend取到的点是窗口的点,2中所画的坐标是画布的坐标系,窗口的坐标不管旋转与否都是不变的,所以横屏的时候拖动的是X轴,竖屏时拖动的是Y轴,取点横竖屏时也不一样。

doc.querySelector(‘.indexPage‘).addEventListener(‘touchstart‘, function(e) {
startX = isVertical ? e.touches[0].clientY : e.touches[0].clientX;
});
1
2
3
二、对js类的初认识
以前对js,基本停留在用它原生的一些方法做一些操作处理,封装的概念也只是提取一些公共的代码独立成方法方便调用而已,感觉和后台语言还是有很大的区别,没接触到js类。这里用到了js的类、对象这些概念:

/**
* 箭头
*/
var Arrow = function() {
this.img = {name: imageData[‘arrow‘], x: 425, y: 500};
};
Arrow.prototype.draw = function() {
if (isMove)
ctx.drawImage(this.img.name, this.img.x + posX, this.img.y + posY);
else
ctx.drawImage(this.img.name, this.img.x, this.img.y + posY);
};
1
2
3
4
5
6
7
8
9
10
11
12
不知道自己的理解准确与否,var Arrow = function(){}即声明了一个类,function()就相当于构造函数,img就是它的一个属性,prototype 属性实现向对象添加属性和方法,像示例代码中就是给这个类添加了一个draw方法,调用时,一样,先实例化对象:var arrow = new Arrow(); 然后就可以调用对象的方法:arrow.draw(); 当然,方法可以传参。这个项目中基本都是这种方式处理的,把各种元素分出来单独处理可以达到一定的封装作用,方便代码维护和适应需求的变动,不至于把自己弄晕。

三、Howler.js控制音频
很好用,很好用,很好用,重要的事情讲三遍!之前听前端同事经验,音频出现问题是很稀松平常的事情,ios和安卓系统各种情况不一样,特别是ios上不能自动播放音频,一定要认为触碰一下才可以(可能是防止偷用户流量?),处理方式从预先加载后暂停到微信的方法解决不等,遇到这种音频特别多,不同时间需要播放不同几个音频的比较变态的项目来说,用以前的方式(虽然我没有接触过)会比较奔溃。Howler.js使用方式很简单,首先实例化Howl对象:

var bgSound = new Howl({
src: [soundPath + ‘sound/bg.mp3‘],
autoplay: true,
loop: true
});
1
2
3
4
5
播放音频:

bgSound.play();
1
判断音频是否正在播放:

if (bgSound.playing()) {
//balabalabala
}
1
2
3
四、加载页
以前一度觉得加载页是个很神奇的东西,怎么知道加载到了百分之多少,怎么能契合得那么好(一度以为加载页动画只是个假的玩意儿 [捂脸]),现在才知道原来加载基本就是加载图片,而图片加载的过程中是可以监控图片的加载程度的,大概就是这么个意思:

var count = 0, total = resources.length;
function loadPage() {
function loaded() { // 加载完成一次
count++;
percent = count / total * 100; // 计算加载的百分比
if (percent >= 100) {
isLoaded = true;
// 好啦,加载好了,可以愉快玩耍了
}
}

for(var i=0; i < total; i++) {
(function(resource){
var img = new Image();
img.onload = function(){
loaded.call(this);
};
img.onerror = function() {
loaded.call(this);
};
img.src = resourcePath + resource[i][‘path‘];
imageData[resource[i][‘name‘]] = img;
})(resources); // 这里的resources就是所有在加载页显示时需要加载的资源
}
}
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
当然,加载页需要的资源是要事先加载好的,所以加载页资源在加载的时候页面是白屏的,另外,resources强调是加载页显示时需要加载的资源是因为有时候为了用户体验会分段加载资源,即加载页结束时并没有把所需的所有资源加载进去,剩下的资源会在合适的时机控制它加载。

五、requestAnimationFrame()
网上查了很久这个js函数,没怎么看明白,反正就是一个性能挺好的刷新动画的方法,主要就是让canvas画布不停不停不停地画,这里是这么用的:

function draw() {
// 实际的画图方法

requestAnimationFrame(draw);
}
1
2
3
4
5
六、其他
剩下就是具体的逻辑控制了,类似什么时候播音频,什么时候走序列帧动画之类之类的。
==============================================================================

Howler.js是一个不错的HTML5声音引擎。功能强大,性能不错,用起来也很方便。

1. 官网
https://howlerjs.com/ 其代码托管在GitHub上。

2. 兼容性
Howler默认使用Web Audio,但在IE上可以自动转为HTML 5 Audio。这点很是贴心。

3. 声音激活
移动端的Safari和Chrome都禁止网页自动播放声音,必须通过用户的操作,touch, click等触发。Howler可以设置成自动捕捉用户操作激活(解禁)声音播放。

4. 声音格式
Howler.js支持很多声音格式以兼容各种浏览器。MP3, MPEG, OPUS, OGG, OGA, WAV, AAC, CAF, M4A, MP4, WEBA, WEBM, DOLBY, FLAC.

5. 声音精灵
Howler 支持声音精灵。GitHub上的audiosprite, 一个基于ffmpeg的声音编译工具(https://github.com/tonistiigi/audiosprite)直接支持生成Howler格式的声音精灵,而且有诸多参数可选,可同时输出多种格式,Howler.js可以根据浏览器的支持来选择用哪个声音格式。注意Howler.js选择声音格式的顺序是声音精灵json描述文件的顺序,即你生成声音精灵时写的顺序。

6. 循环点处理
我们自己手动写的声音循环在循环一次和下一次的衔接往往有些延迟,造成不连贯,Howler.js对于循环点的处理性能不错,延迟比较小。

6. 其他特点
支持3D游戏
自动缓存
支持淡入淡出效果
轻量
纯JS
无第三方依赖
模块化
7. 官网上的简单样例
7.1 嵌入网页
<script src="/path/to/howler.js"></script>
<script>
var sound = new Howl({
src: [‘sound.webm‘, ‘sound.mp3‘]
});
</script>
1
2
3
4
5
6
7.2 播放mp3
var sound = new Howl({
src: [‘sound.mp3‘]
});

sound.play();
1
2
3
4
5
7.3 更多播放选项
var sound = new Howl({
src: [‘sound.webm‘, ‘sound.mp3‘, ‘sound.wav‘],
autoplay: true,
loop: true,
volume: 0.5,
onend: function() {
console.log(‘Finished!‘);
}
});
1
2
3
4
5
6
7
8
9
7.4 定义及播放声音精灵
var sound = new Howl({
src: [‘sounds.webm‘, ‘sounds.mp3‘],
sprite: {
blast: [0, 3000],
laser: [4000, 1000],
winner: [6000, 5000]
}
});

// Shoot the laser!
sound.play(‘laser‘);
1
2
3
4
5
6
7
8
9
10
11
7.5 事件监听
var sound = new Howl({
src: [‘sound.webm‘, ‘sound.mp3‘]
});

// Clear listener after first call.
sound.once(‘load‘, function(){
sound.play();
});

// Fires when the sound finishes playing.
sound.on(‘end‘, function(){
console.log(‘Finished!‘);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
7.6 控制多个声音
var sound = new Howl({
src: [‘sound.webm‘, ‘sound.mp3‘]
});

// Play returns a unique Sound ID that can be passed
// into any method on Howl to control that specific sound.
var id1 = sound.play();
var id2 = sound.play();

// Fade out the first sound and speed up the second.
sound.fade(1, 0, 1000, id1);
sound.rate(1.5, id2);
1
2
3
4
5
6
7
8
9
10
11
12
7.7 使用ES6
import {Howl, Howler} from ‘howler‘;

// Setup the new Howl.
const sound = new Howl({
src: [‘sound.webm‘, ‘sound.mp3‘]
});

// Play the sound.
sound.play();

// Change global volume.
Howler.volume(0.5);
1
2
3
4
5
6
7
8
9
10
11
12

————————————————
版权声明:本文为CSDN博主「时间1812」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/time1812/article/details/79184641

原文地址:https://www.cnblogs.com/2019gdiceboy/p/11978303.html

时间: 2024-10-13 22:01:01

canvas+howler.js 解决同页面视频、音频同时播放问题的相关文章

页面视频只可以播放一个

// 页面只有一个可以播放 var videos = document.getElementsByTagName('video'); for (var i = videos.length - 1; i >= 0; i--) { (function(){ var p = i; videos[p].addEventListener('play',function(){ pauseAll(p); }) })() } function pauseAll(index){ for (var j = vide

js解决EasyUI页面渲染速度慢问题(Mask遮罩)

1 /** 2 * 页面加载等待页面 3 * 4 * @author gxjiang 5 * @date 2010/7/24 6 * 7 */ 8 var height = window.screen.height-250; 9 var width = window.screen.width; 10 var leftW = 300; 11 if(width>1200){ 12 leftW = 500; 13 }else if(width>1000){ 14 leftW = 350; 15 }e

【转】一种解决h5页面背景音乐不能自动播放的方案

原文:http://www.cnblogs.com/wmhuang/p/5452259.html ---------------------------------------------------------------------------------------------- 场景:微信.浏览器.App 普通解决方案:采用audio标签的autoplay属性 现象: 大部分IOS系统和少部分Android微信不支持自动播放 $解决方案:监听WeixinJSBridgeReady事件.D

一种解决h5页面背景音乐不能自动播放的方案

场景:微信.浏览器.App 普通解决方案:采用audio标签的autoplay属性 现象: 大部分IOS系统和少部分Android微信不支持自动播放 $解决方案:监听WeixinJSBridgeReady事件.DOMContentLoaded事件 微信的JS API建立在微信壳浏览器的内置JS对象WeixinJSBridge上,WeixinJSBridge并不是WebView一打开就有了,客户端需要初始化这个对象,当这个对象准备好的时候,客户端会抛出事件"WeixinJSBridgeReady&

解决h5页面背景音乐不能自动播放的方案

场景:微信.浏览器.App 普通解决方案:采用audio标签的autoplay属性 现象: 大部分IOS系统和少部分Android微信不支持自动播放 $解决方案:监听WeixinJSBridgeReady事件.DOMContentLoaded事件 微信的JS API建立在微信壳浏览器的内置JS对象WeixinJSBridge上,WeixinJSBridge并不是WebView一打开就有了,客户端需要初始化这个对象,当这个对象准备好的时候,客户端会抛出事件"WeixinJSBridgeReady&

Android解决WebView的定位功能、视频全屏播放、下载功能、页面Url的处理、进度条处理

解决WebView的定位功能.视频全屏播放.下载功能.页面Url的处理.进度条处理 事先说明: 定位功能在安卓6.0需要用户手动确认权限后才能使用 若需在安卓6.0适配WebView的定位功能,则需要在WebView中手动增加用户权限访问 详细可百度安卓6.0权限管理系统,或者采用第三方封装好的权限管理类进行编写(如Bmob) 如果对内容不理解的话,可参考最后的整个类的代码 如果对BaseActivity这个抽象类不理解的话,可以查看下面一篇文章对BaseActivity的介绍 步骤一:webv

【个人小结】项目公共js的配置,解决不同页面多个配置修改的问题

之前写了两个公司项目里面用到的公共插件,说是插件其实也不算标准.问题描述如下:公司项目分三个平台测试,地址分别为 :http://a.server1.com,  http://a.server2.com,  http://a.server3.com .其中server1,server2,server3分别为三台服务器,而每台服务器有对应的插件地址: http://chajian.server1.com,  http://chajian.server2.com,  http://chajian.s

js代码从页面移植到文件中失效或js代码修改后不起作用的解决办法

最近在做关于网站的项目,总是发生这样的问题 写的javascript代码在页面上没有问题,但是将js代码移植到.js的文件中,在页面上进行调用,总是出现失效等错误 另外修改后的js代码,重新刷新网页仍然不起作用 经过大量搜索并经过验证,可以用下面方法来解决 将js代码封装到js文件中失效的原因可能是js文件中存在中文注释,导致在执行的时候中断,在js文件尽量不要写中文注释 修改后的js代码刷新网页后不起效果可能是因为你所用的浏览器使用缓存的问题,可在浏览器中设置取消使用缓存,并删除临时文件,重启

ios系统 竖屏拍照 canvas处理后 图片旋转(利用exif.js解决ios手机上传竖拍照片旋转90度问题)

转:https://www.cnblogs.com/lovelgx/articles/8656615.html ---恢复内容开始--- 问题:html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题:Android手机没这个问题. 解决方法:利用exif.js解决ios手机上传竖拍照片旋转90度问题 因此解决这个问题的思路是:获取到照片拍摄的方向角,对非横拍的ios照片进行角度旋转修正. 利用exif.js读取照片的拍摄信息,详见 htt