禁止转载,音频与视频信息的捕捉一直是Web开发

作者: 前端  发布:2019-10-08

虚假来电:HTML5振动API的恶意使用

2014/01/16 · HTML5 · 3 评论 · HTML5

本文由 伯乐在线 - 梧桐 翻译。未经许可,禁止转载!
英文出处:Terence Eden。欢迎加入翻译组。

一个新的API出来了。HTML5 (很快)将支持用户设备振动。这明显是很有趣的事情,比如它可以用户触发提醒,提升游戏体验,以及其他各种好玩的事情,例如通过振动发送摩斯代码。

到目前为止,Chrome(以及其他Android浏览器)要使用位置信息、摄像头、地址簿等资源必须申请权限。这是一种安全措施防止你的个人信息在未授权的情况下泄露。

而现在使用HTML5振动API并不会在屏幕上触发警告。因为一般认为用这个功能几乎没有危害,毕竟在现实中它能干的坏事无非是持续消耗电量。事实就是这样简单吗?我不敢肯定。

引言

点评:音频与视频信息的捕捉一直是Web开发中的一个难点,下面为大家介绍一种新的API,该API通过使用navigatior.getUserMedia()方法来让Web应用程序拥有访问用户摄像头与麦克风设备的能力

邪念

我们都看过那种无耻的广告做得跟Windows弹出窗一模一样,它们通常发出一个正当的系统请求:更新Java或类似的。

假如一个恶意网页弹出一个虚假的系统提示并同时振动,你有多大的信心能区分一个合法的弹出框和一个png图片?毕竟手机振动了,你就会认为它是真实的系统提示。

9159.com 1

(图1)

这时候你是收到了一个“空投”炸弹,还是说网页在跟你开个小玩笑?

页面广告自动播放声音本来就很烦人了。自动振动跟它比起来毫不逊色。回想一下你在满屏幕搜索那个推销保险的广告。

目前振动的强度还不能控制,只能控制持续时间。当然通过构造恶意代码去突破没打补丁的浏览器也不是不可能的,甚至可以让电机持续高负荷运转直到损坏。

从毕业到年已经整整7年,期间一直从事.net开发做c/s从 c# 转到 wpf 而后又开始做b/s 用silverlight,从最开始的arcgis engine 到后来的silverlight api ,去年开始一直在涉及开源的GIS方面应用开发openlayers geoserver dotspatial等。c/s方面还可以用.net的一些开源库来搞,bs原本想凑合用sl混混,但是不会js实在是让我工作起来很难受。这次正好有个项目用涉及到的系统都是提供js接口,本屌丝连html页面标签都认不全,无比蛋疼之下只好下定决心。

本文概述
长期以来,音频与视频信息的捕捉一直是Web开发中的一个难点。许多年来,我们一直依赖浏览器插件来实现这个需求。
在HTML 5中,出现了许多可以访问硬件设备的API,例如访问GPS设备的Geolocation API、访问accelerometer设备的Orientation API、访问GPU设备的WebGL API、访问音频播放设备的Web Audio API等等。这些API是非常强大的,因为开发者可以直接通过编写JavaSccript脚本代码来访问底层硬件设备。
本文介绍一种新的API,该API通过使用navigatior.getUserMedia()方法来让Web应用程序拥有访问用户摄像头与麦克风设备的能力。

虚假来电

如果与HTML5 Audio一起使用,完全可以创建一个很真实的虚假”来电“,既有振动也有铃声。一旦”接听“,页面就可以播放一段音频:”喂,尽快回打给我,我的号码是“一个吸费号码”。接下来还可以使用URI自动打开拨号界面。

9159.com 2

(图2)

你能告诉我上面说的是真实的来电吗?如果你够仔细或许会发现。但如果页面正在播放你的默认铃声,然后设备还在振动,这时你就很可能迷糊。如果和WebRTC呼叫绑定,那实际上你看到的就是一个精心构造的骗局。

javaScript 介绍

捕捉媒体数据的技术发展历史
在过去几年里,开始出现了在Web应用程序中访问客户端本地设备的需求,因此,W3C组织决定组织一个DAP(Device APIS POLICY)工作小组,来为该需求的实现制定一个统一的标准。
接下来让我们来看看在2011年发生了哪些事情:

视频演示

本文作者还录了一段视频,放在Youtube上了。

通用跨平台的脚本语言。

在HTML页面文件中实现媒体数据的捕捉
DAP工作小组的第一个要制定的标准就是如何在Web应用程序的HTML页面中实现媒体数据的捕捉。他们决定重载类型为file的input元素(<input type="file">),并且为accept属性添加一个新的属性值。
如果开发者想实现用户通过摄像头进行拍照的功能,可以书写如下所示的代码。

源代码

下面是一个很基本的例子,你可以在手机上试验一下。(或点击这里看示例)

JavaScript

<body> <script type="text/javascript"> navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate; navigator.vibrate([1000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500]); </script> <img width="100%" src="phone.png" onclick="window.location.href='tel:09098790815';" /> <audio autoplay="autoplay"> <source src="ring.mp3" /> </audio> </body>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;body&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  navigator.vibrate = navigator.vibrate ||
       navigator.webkitVibrate ||
       navigator.mozVibrate ||
       navigator.msVibrate;
 
  navigator.vibrate([1000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500, 1000, 500]);
&lt;/script&gt;
&lt;img width=&quot;100%&quot; src=&quot;phone.png&quot; onclick=&quot;window.location.href=&#039;tel:09098790815&#039;;&quot; /&gt;
&lt;audio autoplay=&quot;autoplay&quot;&gt;  
  &lt;source src=&quot;ring.mp3&quot; /&gt;  
&lt;/audio&gt;
&lt;/body&gt;

目前只有Android平台的Firefox支持,但毫无疑问其他浏览器将会跟进。

js主要由以下三部分组成

代码如下:

提示:

Firefox是Andriod平台上唯一支持振动的。其他的比如三星浏览器,Chrome或者Opera都不支持。Iphone也不支持。Windows Phone或黑莓根本没人在乎的,所以我就不测试了。

当页面使用振动API的时候,Firefox目前并不会申请权限。

你认为浏览器在振动前是否应该有警告?还是说这种风险太低?我想这要看那些骗子公司是否会利用这一点了,或者要看用户是否反对了。

更新: 感谢Reddit和HackerNews上面的评论,BB10似乎也支持振动API,Windows Phone不支持。

赞 收藏 3 评论

ECMAScript 核心

<input type="file" accept="image/*;capture=camera">

关于作者:梧桐

9159.com 3

(新浪微博:@jakiewoo_vp9) 个人主页 · 我的文章 · 13

9159.com 4

DOM 文档对象模型

录制视频数据与音频数据的代码与之类似:

BOM 浏览器对象模型

代码如下:

 

<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">

ECMAScript:

在这些代码中,只需使用file控件(类型为file的input元素)即可完成拍照或录制媒体数据的功能。但是在因为这些代码中尚缺乏一些实现与之相关的需求(例如在canvas元素中渲染捕捉到的视频数据,或者对捕捉到的视频数据应用WEBGL滤镜)的能力,所以没有得到开发者的广泛应用。
支持浏览器:
Android 3.0浏览器
Chrome for Android (0.16)
Firefox Mobile 10.0
device元素
如果使用file控件,则捕捉媒体数据后对其进行处理的能力是非常有限的,所以出现了一种新的可支持任何设备的标准。该标准使用device元素。
Opera浏览器是第一个通过device元素实现视频数据捕捉的浏览器。几乎在同一天,WhatWG组织决定使用navigator.getUserMedia()方法来捕捉媒体数据。一个星期后,Opera推出一个新的支持navigator.getUserMedia()方法的浏览器。后来,Microsoft工具推出支持该方法的IE 9浏览器。
device元素的使用方法如下所示。

1997年 制定的 ECMA-262标准 中定义了ECMAScript

代码如下:

最新一版的标准时2009年的ECMA-262第5版 简称ECMAScript 5

<device type="media" onchange="update(this.data)"></device>
<video autoplay></video>
<script>
function update(stream) {
document.querySelector('video').src = stream.url;
}
</script>

从第一版到第五版 如果用C#的角度来解释就可以理解为C#1.0-5.0这种概念。

支持浏览器
不幸的是,目前为止尚没有一个正式版的浏览器中支持device元素。
WEBRTC
最近,由于WebRTC(Web Real Time Communication:Web实时通信)API的出现,媒体数据捕捉技术又有了一个很大的发展。Google、Opera、Mozilla等公司均正在努力将其实现在自己的浏览器中。
WebRTC API是一个与getUserMedia方法紧密相关的API,它提供一种访问客户端本地的摄像头或麦克风设备的能力。
支持浏览器:
目前为止,在Chrome 18版浏览器中,在chrome://flags页面中进行设置后可使用WebRTC,在Chrome 21版本的浏览器中,该API被默认使用,不再需要设置。在Opera 12以上与Firefox 17版本的浏览器中默认支持WebRTC API。
使用getUserMedia方法
通过使用getUserMedia方法,我们可以不依靠插件而直接访问客户端本地的摄像头设备与麦克风设备。
检测浏览器支持
可以通过如下所示的方法来检测浏览器是否支持getUserMedia方法。

ECMAScript与web浏览器没有关系,Web浏览器只是ECMAScript实现可能的宿主环境之一,其他宿主比如Adobe Flash。

代码如下:

ECMAScript 主要规定了如下内容:语法、类型、语句、关键字、保留字、操作符、对象。

function hasGetUserMedia() {
//请注意:在Opera浏览器中不使用前缀
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
if (hasGetUserMedia()) {
alert('您的浏览器支持getUserMedia方法');
}
else {
alert('您的浏览器不支持getUserMedia方法');
}

javaScript实现了ECMAScript,Adobe ActionScript也同样实现了ECMAScript。

获取访问设备的权限 为了访问客户端摄像头设备与麦克风设备,我们首先需要获取权限。getUserMedia方法的第一个参数是一个用于指定媒体类型的对象。例如,当你想访问摄像头设备时,第一个参数应该为{video:true},为了同时访问摄像头设备与麦克风设备,需要使用{video:true,audio:true}参数,代码如下所示:

到了2008年,五大主流web浏览器(IE,Firefox,Safari,Chrome,Opera)全部做到了与ECMA-262兼容。对于ecmascript5的兼容如下:

代码如下:

Opera 11.60+、
Internet Explorer 9+、Firefox 4+、Safari 5.1+、Chrome 13

<video autoplay id="video"></video>
<script>
var onFailSoHard = function() {
alert('设备拒绝访问');
};
//不使用供应商前缀
navigator.getUserMedia({video: true, audio: true}, function(localMediaStream) {
var video = document.getElementById('video');
video.src = window.URL.createObjectURL(localMediaStream);
//请注意:当使用getUserMedia方法时,在Chrome浏览器中不触发onloadedmetadata事件
video.onloadedmetadata = function(e) {
//后续代码略
};
}, onFailSoHard);
</script>

 

在这段代码中,结合了video元素的使用。请注意我们没有使用video元素的src属性值,而是为video元素指定了一个引用媒体文件的URL地址,同时将代表了从摄像头中所获取到的视频数据的LocalMediaStream对象转换为一个Blob URL。
在这段代码中,同时为video元素使用autoplay属性,如果不使用该属性,则video元素将停留在所获取的第一帧画面处。
请注意:在Chrome浏览器中,如果只使用{audio:true},则引发BUG,在Opera浏览器中,同样不能使用audio元素。
9159.com,如果你想让多个浏览器同时支持getUserMedia方法,请使用如下所示的代码:

文档对象模型(DOM)

代码如下:

文档对象模型是针对XML的,但经过扩展用于HTML的应用程序API。DOM把整个页面映射为一个多层节点结构。HTML或者XML页面中的每个组成部分都是这种类型的节点,这些节点又包含着不同类型的数据。

window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
var video = document.getElementById('video');
if (navigator.getUserMedia) {
navigator.getUserMedia({audio: true, video: true}, function(stream) {
video.src = window.URL.createObjectURL(stream);
}, onFailSoHard);
}
else {
alert('您的浏览器不支持getUserMedia方法');
}

DOM并不是针对js的,很多语言都实现了DOM.

安全性
在有些浏览器中,当调用getUserMedia方法时,显示一个提示窗口,询问用户是否允许或拒绝访问他们的摄像头或麦克风。
拍照
在Canvas API中,可以使用ctx.drawImage(video,0,0)方法将video元素中的某一帧画面输出到canvas元素中。当然,既然我们已经将捕捉到的用户摄像头中的图像信息输出到video元素中,当然也可以将图像信息通过video元素输出到canvas元素中,即实现实时拍照功能,代码如下所示。

DOM Level1 于1998年10月成为W3C的推荐标准。

代码如下:

DOM1由两个模块组成:

<video autoplay></video>
<img src="" id="img" ></img>
<canvas style="display:none;" id="canvas" ></canvas>
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var localMediaStream = null;
function snapshot() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0);
document.getElementById('img').src = canvas.toDataURL('image/png');
}
}
video.addEventListener('click', snapshot, false);
//不使用供应商前缀
navigator.getUserMedia({video: true}, function(stream) {
video.src = window.URL.createObjectURL(stream);
localMediaStream = stream;
}, onFailSoHard);

DOM core

应用CSS滤镜
目前为止,可以在Chrome 18以上版本的浏览器中使用CSS滤镜。
通过CSS滤镜的使用,我们可以对video元素中捕捉的视频添加各种图像滤镜效果。

DOM HTML

代码如下:

其中DOM核心规定了如何映射基于XML的文档结构。DOM HTML模块则在DOM核心的基础上加以扩展,添加了针对HTML的对象和方法。

<style>
#video3 {
width: 307px;
height: 250px;
background: rgba(255,255,255,0.5);
border: 1px solid #ccc;
}
.grayscale {
-webkit-filter: grayscale(1);
}
.sepia {
-webkit-filter: sepia(1);
}
.blur {
-webkit-filter: blur(3px);
}
...
</style>
<video id="video" autoplay></video>
<script>
var idx = 0;
var filters = ['grayscale', 'sepia', 'blur', 'brightness', 'contrast', 'hue-rotate',
'hue-rotate2', 'hue-rotate3', 'saturate', 'invert', ''];
function changeFilter(e) {
var el = e.target;
el.className = '';
var effect = filters[idx++ % filters.length]; // loop through filters.
if (effect) {
el.classList.add(effect);
}
}
document.getElementById('video').addEventListener('click', changeFilter, false);
</script>

DOM2在DOM1的基础上增加了鼠标和用户界面事件、范围、遍历等。DOM3又进一步扩展了DOM。

浏览器对象模型(BOM)

BOM可以控制浏览器显示的页面以为的部分。但是BOM没有相关的标准这也导致了各种问题。HTML5致力于把很多BOM功能写入正式规范。人们习惯把所有针对浏览器的js扩展算作BOM的一部分,如:弹出新的浏览器窗口,移动、缩放关闭浏览器窗口,cookies支持,提供浏览器信息的navigator对象,提供浏览器加载页面信息的location对象,提供用户显示器分辨率的screen对象xmlhttprequest和activexobject这也的自定义对象。

由于没有BOM的标准,因此每个浏览器都有自己的实现。

 

JavaScript的版本

当前最新版本应该是2010年7月的1.82 对应的IE版本是9

 

在HTML中使用JavaScript

<script>元素

向HTML页面中插入js的主要方法就是使用<script>元素,相关属性:

async:可选。立即下载脚本,但不反感页面中的其他操作。只对外部脚本文件有效。

charset:可选。标识通过src属性制定的代码的字符集。

src:可选。表示包含要执行代码的外部文件。

type:可选默认值为text/javascript。为了兼容性一般使用text/javascript。

示例:

<script type=“text/javascript”>

function sayhi(){alert(“hi”);}

</script>

包含在<script>元素内部的js代码将被从上至下依次解释。然后将该定义保存在自己的环境当中。在解释器对<script>元素内部的所有代码解释完毕前,页面中的其余内容都不会被浏览器加载或显示。

在使用<script>嵌入js代码时要注意不能出现”</script>”字符串如下:

<script type=”text/javascript”>

function sayhi()

{

alert(“</script>”);这样就会报错

alert(“</scriot>”);这样才正确

}</script>

如果要通过<script>元素来包含外部js文件则需要指定src属性。src属性接收一个url。如果指定了src属性则<srcript>标签中不在解析包含的代码。只要不存在defer和async属性,浏览器都会按照<script>元素在页面中出现的先后属性对他们一次进行解析。

标签的位置

按照惯例,所有的<script>元素都应该放在页面的<head>元素中。但是这种做法导致要全部的js代码都下载解析完后,才会开始呈现页面内容(浏览器遇到<body>标签时才开始呈现内容)。这样对于很多js代码的页面来说,用户体验很不好,为了避免这个问题现代web英语程序一版会把全部jsavascript引用放在<body>元素中页面的内容后面。如:

<!DOCTYPE html>

<html>

<head>

<title>123<title>

</head>

<body>

<!--这里放内容—》

<script type=”text/javascript”src=”example1.js”></script>

</body>

</html>

</html>

在html4.01开始为<script>定义了defer属性

<srcipt type=”text/javascript” defer=”defer”src=”example1.js”></script>

这样就可以把js代码放到head中了

本文由9159.com发布于前端,转载请注明出处:禁止转载,音频与视频信息的捕捉一直是Web开发

关键词: