从Recorder H5 GitHub开源库优化后,对边录边转码成小语音片段文件实时上传服务器这种操作支持非常良好,因此以前不太好支持的H5语音通话已经有了更好的突破空间。因此花了两晚时间打造了一个H5语音通话聊天的demo。
欢迎在线把玩:https://xiangyuecn.github.io/Recorder/
局域网H5版对讲机
(1)数据传输
github demo中考虑到减少对服务器的依赖,因此采用了WebRTC P2P传输功能,无需任何服务器支持即可实现局域网内的两个设备之间互相连接,连接代码也算简单。有服务器支持可能就要逆天了,不过代码也会更复杂。
如果正式使用,可能不太会考虑使用WebRTC,用WebSocket通过服务器进行转发可能是最佳的选择。
WebRTC局域网P2P连接要点(实际代码其实差不多,只不过多做了点兼容):
/******Peer A(本机)******/ var peerA=new RTCPeerConnection(null,null) //开启会话,等待远程连接 peerA.createOffer().then(function(offer){ peerA.setLocalDescription(offer); peerAOffer=offer; }); var peerAICEList=[......] //通过peerA.onicecandidate监听获得所有的ICE连接信息候选项,如果有多个网络适配器,就会有多个候选 //创建连接通道对象,A端通过这个来进行数据发送 var peerAChannel=peerA.createDataChannel("RTC Test"); /******Peer B(远程)******/ var peerB=new RTCPeerConnection(null,null) //连接到Peer A peerB.setRemoteDescription(peerAOffer); //开启应答会话,等待Peer A确认连接 peerB.createAnswer().then(function(answer){ peerB.setLocalDescription(answer); peerBAnswer=answer; }); //把Peer A的连接点都添加进去 peerB.addIceCandidate(......peerAICEList) var peerBICEList=[......] //通过peerB.onicecandidate监听获得所有的ICE连接信息候选项,如果有多个网络适配器,就会有多个候选 var peerBChannel=... //通过peerB.ondatachannel得到连接通道对象,B端通过这个来进行数据发送 /*******最终完成连接********/ //连接到Peer B peerA.setRemoteDescription(peerBAnswer); //把Peer B的连接点都添加进去 peerA.addIceCandidate(......peerBICEList) /* peerA peerB分别等待peerA/BChannel.onopen回调即完成P2P连接 ,然后通过监听peerA/BChannel.onmessage获得对方发送的信息 ,通过peerA/BChannel.send(data) 发送数据。 */
(2)音频采集和编码
由于是在我的Recorder库中新加的demo,因此音频采集和编码都是现成的,Recorder库有好的兼容性和稳定性,因此节省了最大头的工作量。
编码最佳使用MP3格式,因为此格式已优化了实时编码性能,可做到边录边转码,16kbps 16khz的情况下可做到2kb每秒的文件大小,音质还可以,实时传输时为3kb每秒,15分钟大概3M的流量。
用wav格式也可以,不过此格式编码出来的数据量太大,16位 16khz接近50kb每秒的实时传输数据,15分钟要37M多流量。其他格式由于暂未对实时编码进行优化,使用中会导致明显卡顿。
降噪、静音检测等高级功能是没有的,毕竟是非专业人员 要求高点可以,但不要超出范围太多啦。
(3)音频实时接收和播放
接收到一个音频片段后,本应该是立即播放的,但由于编码、网络传输导致的延迟,可能上个片段还未播放完(甚至未开始播放),因此需要缓冲处理。
因为存在缓冲,就需要进行实时同步处理,如果缓冲内积压了过多的音频片段,会导致语音播放滞后太多,因此需要适当进行对数据进行丢弃,实测发现网络正常、设备性能靠谱的情况下基本没有丢弃的数据。
然后就是播放了,本应是播完一个就播下一个,测试发现这是不靠谱的。因为结束一个片段后再开始播放下一个发出声音,这个过程会中断比较长时间,明显感觉得出来中间存在短暂停顿。因此必须在片段未播完时准备好下一个片段的播放,并且提前开始播放,达到抹掉中间的停顿。
我写了两个播放方式:
最开始用一个Audio停顿感太明显,因此用两个Audio轮换抹掉中间的停顿,但发现不同格式Auido播放差异巨大,播放wav非常流畅,但播放mp3还是存在停顿(后面用解码的发现是得到的PCM时长变长了,导致事件触发会出现误差,为什么会变长?怪异)。
因此后面写了一个解码然后再播放,mp3这次终于能正常连续播放了,wav格式和双Audio的播放差异不大。实时解码里面也用到了双Audio中的技巧,其实也是用到了两个BufferSource进行类似的轮换操作,以抹掉两个片段间的停顿。
不过最终播放效果还是不够好,音质变差了点,并且多了点噪音。如果有现成的播放代码拿过来用就就好了。
完。
TML5 对于初学者甚至是非程序员来说都有着十足的吸引力。实际上,只要你访问网站,就会和 HTML 打交道。如果能够熟悉一些关键的编程技巧,当你对网站做一些细节调整或优化基本的 Web 元素时就能节省大量的时间(甚至是金钱)。因此,本文精选了 10 个对于 Web 开发者来说非常实用的 HTML 编程技巧,而且它们不需要花太多时间精力就可以轻松掌握。
1. 可与本地缓存媒体资源交互
HTML5 FileSystem API 一开始被认为是 AppCache 的替代方案,用来实现资产的动态缓存。但是你知道吗,其实你还可以用它来实现与用户本地设备上存储文件的交互。
例如,你可以在应用中添加以下功能:
注意:FileSystem API 仅被 Chrome 支持。
如果你想尝试离线存储功能,还可以参考以下资源和代码教程:
2. 进行自动表单验证
对于网站安全性和流畅的用户体验来说,表单验证非常重要。所以我们应该让用户更轻松地在你的网站上输入各种正确类型的值。
在 HTML5 中有几种新的输入类型可用,这些类型已经打包进了预定义的验证功能:
但当你需要用户提供某些标准输入未指定的数据时(例如一个包含特殊字符的用户名),往往就会出问题了。这就是“pattern”属性派上用场的时候。
Pattern 可让你定义自定义规则,然后使用正则表达式(RegEx)验证表单输入。RegEx 指定了<input>元素值将要检查的表达式。
下面是一个添加新规则的示例。例如,你要指定密码不应超过 15 个字符,并且只能包含小写字母:
<form action="/action_page.php">
Password: <input?type="password"?name="pw"?pattern="[a-z].{1,15,}">
<input?type="submit">
</form>
为了更好地说明规则,你还可以添加一条自定义消息,告诉用户为什么他们输入的密码不符合要求。只需再加上一行来自定义弹出消息即可:
<form action="/action_page.php">
Password: <input?type="password"?name="pw"?pattern="[a-z].{1,15,}"?title="One to fifteen characters, lowercase only".>>
<input?type="submit">
</form>
3. 为 HTML5 代码元素创建缩写
Emmet[4] 是一个很好用的文本编辑器插件,可以简化你的 HTML/CSS 编码流程。这个工具使用的语法类似于 CSS 的选择器,可让你为标准 HTML 代码元素创建各种缩写。
下面是一个例子。如果你输入:
div#header>h1.logo>a{website}
则会收到:
<div?id="header">
<h1?class="logo"><a?href="">website</a></h1>
</div>
你可以使用 cheat sheet[5] 中的多种已有组合,也可以为任意 HTML 标签创建自定义组合,然后按 Tab 或 Ctrl + E 将其添加到文本编辑器中。我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,去年我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。
4. 实现更优的视频传输
使用 video 标签,可以将支持视频播放的媒体播放器无缝嵌入到网页中。
你可以选择:
此外,你必须为视频指定“控件”(例如播放、暂停和音量调节),否则用户将没有任何控件可用。这里的示例代码如下:
<video width="768"?height="432"?autoplay>
<source?src="video.mp4"?type="video/mp4">
</video>
为了进一步改善观看体验,你还可以尝试使用以下属性:
你可以在这个 HTML 速查表 [7] 中找到更多使用方便的多媒体文件标签。
5. 改善图像的显示方式
<picture>标签有助于优化图像的显示方式。
它通常用于:
示例:
<picture>
<source?media="(min-width: 846px)"?srcset="img_1.jpg">
<source?media="(min-width: 300 px)"?srcset="img_2.jpg">
<img?src="img_3.jpg"?alt="logo">
</picture>
<picture>标签包含两个附加子元素:
要启用其他样式选项,请将以下属性添加到<source>元素:
<img>元素可用来确保在不支持<picture>元素的浏览器中正确显示图像。
6. 提升首屏页面的加载速度
如果你希望你的网站在搜索结果中获得靠前的排名,并提供出色的用户体验,那么就需要重点关注页面的加载速度。
但是,要在 Google Page Insights 中拿到高分并不是那么容易。虽然这一工具的确会标出你的网站上应该修复的内容,但是对于从头开始对网站进行编码的人们并没有提供明确的优化指导。
谷歌对于首屏设计的官方建议 [8] 有些含糊不清:
所以我们来将其分解为更可操作的几个步骤:
然后再次运行检查任务,看看是否还有需要修复的内容。
7. 网站加速
只要将 .zip 文件而不是 index.html 文件发送给浏览器,就可以节省大量带宽和下载时间。
图片来自 betterexplained[11]
要设置 .gzip 压缩,你需要在 web 主机 / 服务器上找到 htaccess 文件,并使用以下代码对其进行修改:
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include?file?.(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
如果这样做不起作用,请参考下面这些针对不同 web 服务器类型的教程:
8. 利用 Microdata 进行 SEO
你可以使用 microdata 将额外的上下文编入网页。然后,网络爬虫就可以从你的页面中渲染微数据,并为用户提供更好的浏览体验,以更高的精确性对你的网站建立索引并为其提供更准确的搜索结果排名。
简而言之,Microdata 由名称 / 值(name/value)对组成,每一个项目(item)定义一组命名的属性(property)。
9. 使用 HTML5 本地存储代替 Cookie
Local Storage(也称为 DOM 存储)使你可以在本地存储用户数据,这样就无需通过 HTTP 网络请求发送数据了。它可以节省带宽并提升数据存储能力。看起来不错吧?
但是有一个重要的警告:本地存储仅能保存在客户端,而 cookie 既可以保存在服务器端也可以在客户端。因此,如果你的网站使用了服务器端的 Cookie 来基于已知的用户首选项自定义内容,则迁移到本地存储可能就需要重大的架构更改工作了。
但在比较简单的情况下(例如你使用 Cookie 来存储一些基本设置),本地存储可能是一个很好的替代品,尤其是在网络连接质量较差的区域。另外请记住,本地存储对于高敏感数据(例如财务信息)可能不是理想的选择,并且建议你对本地存储的所有数据都进行额外的加密。
Jenkov 详细介绍了如何设置和配置 HTML5 本地存储 [13]。
10. 编写有编号项目的降序列表
文章最后介绍一个非常简单的技巧:你可以使用<reversed>属性添加降序列表替代升序列表。
下面是一个示例代码片段:
<ol?reversed>
<li>Ready</li>
<li>Set</li>
<li>Go!</li>
</ol>
听起来可能没有多大意义,但是当你想在页面中添加一些时髦的样式时,它可能就会派上用场了。
小结
现在你应该掌握了这 10 个新的 HTML5 技巧和窍门,它们应该可以帮助你构建更快、更人性化和更有吸引力的网站。不过千万要记得,在开始实验之前先对你的网站进行备份!
原文链接:https://mp.weixin.qq.com/s/qtQZUvsnIn0nsFbG51lQQw
作者:前端工匠
篇文章给大家带来的内容是关于canvas实现压缩图片的代码示例,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。// 对图片进行压缩
function compress(imgPath) {
var image=new Image();
//新建一个img标签(还没嵌入DOM节点)
image.src=imgPath;
image.onload=function() {
var canvas=document.createElement('canvas');
var context=canvas.getContext('2d');
var imageWidth=image.width / 3;
//压缩后图片的大小
var imageHeight=image.height / 3;
var data='';
canvas.width=imageWidth;
canvas.height=imageHeight;
context.drawImage(image, 0, 0, imageWidth, imageHeight);
data=canvas.toDataURL('image/jpeg')
//压缩完成
$(".srcDiscernImg").attr("src", data);
console.log("渲染。。。。");
}
}
本篇文章到这里就已经全部结束了,更多精彩内容大家可以关注的HTML5视频教程栏目!!!
以上就是canvas实现压缩图片的代码示例的详细内容,更多请关注其它相关文章!
更多技巧请《转发 + 关注》哦!
*请认真填写需求信息,我们会在24小时内与您取得联系。