WEB前端第六十五课——H5新特性:Worker线程、Files、FileReader、getUserMedia
1.Web Worker线程
JavaScript语言是单线程模型,通过Web Worker为JS创造多线程环境;
由主线程创建Worker线程,将一些任务分配给Worker运行,两者异步执行;
Worker完成计算任务后,再将结果返回给主线程。
优点:可以分担计算密集型或高延迟的任务,确保主线程运行会更加流畅;
缺点:Worker一旦创建成功,为随时响应主线程通信,如不主动关闭结束,
会一直运行,造成资源耗费。
代码示例:
// 创建Worker脚本任务
var n=0;
self.postMessage(n);
var timer=setInterval(function () {
n+=3;
//返回数据结果
postMessage(n);
},1000);
//添加消息事件监听,使用“addEventListener”或“onmessage()”两种方式都可以。
self.addEventListener('message',function (e) {
if (e.data=='Stop'&&n>15){
clearInterval(timer);
postMessage('The Worker stopped!') //返回消息给主线程。
//子线程中使用“close()”方法关闭Worker线程。
self.close();
}
},false);
2.文件操作
文件上传标签:
⑴ files集合
H5中所有“file”类型的元素都具有files属性,files为包含一组file对象的集合。
每个file对象都具有上传文件的所有信息,包括:name、size、type、lastModifiedDate等。
通过侦听“change”事件并读取Files集合,可以获得每个文件对象的属性信息。
代码示例:
⑵ FileReader构造函数,
File API提供了FileReader接口用于读取文件数据。
① FileReader属性:
error,读取文件时发生的错误,
错误码code:1-未找到文件、2-安全性错误、3-读取中断、4-不可读取、5-编码错误
readyState,FileReader对象的当前状态,状态常量包括三个:
常量名 值 描述
EMPTY 0 还没有加载任何数据
LOADING 1 数据正在加载中
DONE 2 已完成全部读取任务
result,表示读取到的文件内容,该属性只有在读取操作完成后才有效,
读取数据的格式取决于读取操作使用的哪种方法。
② FileReader接口有4个操作方法(前两个为核心方法):
readAsText(file或Blob,encoding),以纯文本形式读取File或Blob对象的内容,
第二个参数(可选)用于指定编码类型,默认为“UTF-8”;
readAsDataURL(file或Blob),将文件读取为DataURL格式(Base64编码);
readAsBinaryBuffer(file或Blob),将文件读取为二进制编码形式;(已废弃)
abort(),终止该读取操作。
上述3中读取文件的方法,读取结果都保存在“result”属性中!!
③ FileReader相关事件:
onabort,读取操作终止时调用;
onloadstart,读取操作开始时调用;
onerror,读取发生错误时调用;
onload,读取操作成功完成时调用;
onloadend,读取操作完成时调用,不论操作发生错误、中断还是成功。
onprogress,读取过程中周期性调用。
一般情况下,读取文件时,首先触发onloadstart事件,此时readyState状态值为1,result为空。
读取文件过程中,约每隔50ms触发一次onprogress事件,通过事件对象可以获取文件进度信息,
lengthComputable(是否未完成/有可计算长度)、loaded(已加载)、total(进度总长度)。
读取文件成功完成时,触发load事件,此时readyState状态值为2,result为文件内容。
如果读取文件过程中发生了错误,则触发error事件,而不会触发load事件。
代码示例:
FileReader
3.getUserMedia
getUserMedia()方法是H5提供的用于访问用户设备媒体(视频、音频、位置等)的API接口,
在新版Web标准中,getUserMedia()方法是window.navigator.mediaDevices下的一个方法。
语法:navigator.mediaDevices.getUserMedia(constraints);
说明:
⑴ navigator是window的一个只读属性,该对象包含了访问者浏览器的相关信息;
navigator对象属性:
appCodeName,浏览器的代码名
appName,浏览器的名称
appVersion,浏览器的平台和版本信息
cookieEnabled,浏览器中是否启用 cookie 的布尔值
platform,运行浏览器的操作系统平台
userAgent,浏览器代理信息,由客户机发送服务器的user-agent头部的值
⑵ mediaDevices是Navigator的一个只读属性,返回一个MediaDevices对象,
该对象可提供对相机、麦克风、屏幕共享等媒体设备的连接访问,
并且该对象是一个单例对象,通常只需直接调用改对象的成员。
⑶ getUserMedia()方法提示用户给予使用一个视频或音频输入设备的许可,
该方法接受三个参数,语法:
navigator.mediaDevices.getUserMedia(constraints,onSuccess,onError);
① constraints,多媒体类型设置
该参数是一个对象,用于设置多媒体类型,即获取哪些设备;
语法:{
video:true/false, //video参数还可以直接设置分辨率
audio:true/false
}; //两个参数中至少有一个类型被启用!
video参数值为分辨率时,语法:
video:{ width:1280,height:960},
设置video分辨率时,除了“width和height”,还可以使用关键字“min,max,ideal”;
如果是移动设备时,video参数还可以强制使用前置或后置摄像头,语法:
video:{facingMode:'user'}, //强制使用前置摄像头
video:{facingMode:{exact:environment}}, //强制使用后置摄像头
② promise说明
getUserMedia()方法是一个异步执行的方法,所以不会立即返回最终的值,
而是返回一个“Promise”对象,Promise对象代表了异步操作的最终完成或者失败,
当发生情况之一时,该对象绑定的相应回调函数就会被调用,返回结果也是Promise。
通常使用Promise对象的“then() 和 catch()”方法链式排列相关处理程序。
语法示例:
var promise = navigator.mediaDevices.getUserMedia(constraints);
promise.then(function onSuccess(mediaStream){...})
.catch(function onError(errorObj){...});
或者简写为:
navigator.mediaDevices.getUserMedia(constraints).then(onSuccess,onError);
说明:
then()的参数可选,catch(errorCallback) 是 then(null,successCallback)的缩略形式;
catch()之后可以继续接then(),进行其他链式操作。
③ successCallback,成功回调函数
获取多媒体设备成功时调用该回调函数。Success回调函数的参数是一个数据流对象,
数据流对象mediaStream的两个内置方法“getAudioTracks() 和getVideoTracks()”,
分别返回一个数组,数组成员是数据流包含的音轨audio和视轨video对象。
语法示例:
function onSuccess(mediaStream) {
var video = document.getElementById("video");
video.src = window.URL.createObjectURL(mediaStream);
说明:
成功(resolve)Promise对象的回调函数会带一个“MediaStream”对象作为其参数;
URL.createObjectURL()方法可以将媒体流转换为一个二进制对象的URL(Blob URL),
该URL可以作为 video元素 src 的属性值。
④ errorCallback,失败回调函数
获取多媒体设备失败时调用该回调函数。Error回调函数接受一个error对象作为参数,
Error对象有三个属性值,
PERMISSION_DENIED:用户拒绝提供信息。
NOT_SUPPORTED_ERROR:浏览器不支持硬件设备。
MANDATORY_UNSATISFIED_ERROR:未发现指定的硬件设备。
语法示例:
function onError(error) {
console.log("错误名称: "+ error.name+"
错误信息:"+error.message);
⑷ 视频拍照
获取视频后通过 Canvas API提供的 “ctx.drawImage(video,0,0)”方法实现拍照功能,该方法
可以将视频的一帧转换为canvas元素,进行截图拍照。
语法示例:
var ctx=canvas.getContext('2d'); //创建2d画笔
ctx.drawImage(video,0,0); //在画布上绘制图像
⑸ 视频、截图示例代码: