HTML5学习总结-04 音频&视频播放
一 音频播放
1 Audio(音频)
HTML5提供了播放音频文件的标准
2 control(控制器)
control属性攻添加播放,暂停和音量空间。
3 标签定义声音
<audio>
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button id="btn" onclick="playMusic()">播放</button>
<button id="mutedBtn" onclick="muteMusic()">静音</button>
<audio id="audio" src="source/Morning.mp3" controls="controls" >您的浏览器不支持标签</audio>
<script>
function playMusic(){
var audioObj = document.getElementById("audio");
var btn = document.getElementById("btn");
console.log("step1 audioObj.paused="+audioObj.paused);
if( audioObj.paused){
btn.innerText ="暂停";
audioObj.play()
}else{
btn.innerText ="播放";
audioObj.pause();
}
}
function muteMusic(){
var audioObj = document.getElementById("audio");
var mutedBtn = document.getElementById("mutedBtn");
console.log( audioObj.muted);
if( audioObj.muted ){
audioObj.muted= "";
mutedBtn.innerText= "取消静音"
}else{
audioObj.muted= "muted";
mutedBtn.innerText= "静音"
}
}
</script>
</body>
</html>
二 视频播放
1 Video(视频)
HTML5提供了播放视频文件的标准
2 control(控制器)
control属性攻添加播放,暂停和音量空间。
3 标签定义声音
<video>
4 属性
width: 宽
height: 高
5 例子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<video controls="controls">您的浏览器不支持标签
<source src="source/video1.mp4"></source>
<source src="source/video1.ogv"></source>
</video>
</body>
</html>
三 video捕获摄像头画面
1 通过video元素调用摄像头捕获画面
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
<style>
#myDiv {}
</style> </head> <body>
<div>
<video width="" height="" autoplay></video>
<canvas width="" height=""></canvas>
<br>
<button id="drawBtn" style="width: 100%;height: 50px;">拍照</button>
</div> <script>
var video = document.querySelector('video');
var canvas = document.querySelector('canvas'); // video捕获摄像头画面
navigator.webkitGetUserMedia({
video: true
}, success, error); function success(stream) {
video.src = window.webkitURL.createObjectURL(stream);
video.play();
} function error(err) {
alert('video error: ' + err)
} //canvas
var context = canvas.getContext('2d'); setTimeout(function() {
//把当前视频帧内容渲染到画布上
context.drawImage(video, , , , );
}, ); var button= document.getElementById('drawBtn');
button.onclick = function(){
context.drawImage(video, , , , );
} </script>
</body> </html>
运行页面后,浏览器出于安全性考虑,会询问是否允许当前页面访问你的摄像头设备,点击“允许”后便能直接在 <video> 上看到摄像头捕获到的画面了:

直接在页面中显示base64 编码的图片
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body> <img src='data:image/jpg;base64,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ceaLj3NsPV9jWhVtflaf3O58xaHr2v8AhwznSZZLfz9vmfuFfdtzj7ynHU1sf8LG8cf9BGT/AMA4v/iK+haK41hJxVlN/wBfM+gqZ/h6kuephotvq7N/+knzbpXhnxD4x1gyvDOfOfdPeTqQq++T1OOgH8q6X4ieGdR0TxBb65p0DvaRJDtkVd3lPGAo3D0wq89K9toqlg48rV9e5nLiKs68aiglFJrl8nbr8ux4YPjN4jA/489LP/bKT/4uuT8TeJr3xVqSX99FbxypEIQIFIXAJPcnn5jX0/RSlhak1aU/w/4JVDPMLQnz0sMk/wDF/wAA8P8AiP8A8if4K/68v/acVeh/DP8A5J5pX0l/9GvXW0VtChy1HO/SxwYnM/bYSOF5bWk3e/e+lreZ82eN/CV34W1ubET/ANnyuWtpwvy4PO3PZh0x7ZrpdH+M+o2VkkGo6dHfyIoUTCYxM3u3BBP5V7XNDFcRNFNGkkbDDI6ggj3BqlBoOjWpzb6TYRH1jtkX+Qr6R5tSrUlDFUuZrrex4nsmneLPH/EPjvV/GGn2kem+HLuGS2u0uo54Waf5lDYGAg9c/hWq/wAZb+xRI9R8MNHPj5sztEG9wrISB+Jr1sAAAAYAqKe3guojFcQxzRnqkihgfwNYfXsK0oSoe6v7zvr5j5Jb3Pnfxz45/wCEz+wf8S77H9k8z/lv5m/ft/2RjG39a6z4O+GbqO7m1+6haOAxGK23jG/JGWHsAMZ75PpXpsfhnQIpBJHoemo453LaRg/nitQAAAAYArXEZrB4b6th4csfW/mKNJ83NJnnnxl/5E22/wCv5P8A0B65Hw38Vv8AhH/D9ppX9i/aPs6keb9q2bssT02HHX1r3GivnJ0ZOfPGVvke9h8yoQwqw1ejzpO/xNfkjyP/AIXf/wBS9/5O/wD2uuL8S+JJPGfiezvI7BoHCJAsKv5hbDE56D+90xX0hRUTw9SatKenob4fNsJhp+0o4a0v8bf5o8i+N/39D+k//tOm+IviTplwt3ol/wCGxeJBI0IL3GMlSV3DC5U8djmvX6KqVCTlKUZWv5GNHNKMaNOlVpc3Jez5mt3foj5wsPDvi6XQ724sLa/h048vArsvmj2T+PHfitfwv480rwpa+UnhgC+A2zXHn/O579VJX6DiveKKiOEcGnGWvpc6qufxrxlCvRvFvpJx++25BZ3H2uxt7nbs86JZNuc4yM4zU9FFdh867N6BRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/2Q=='/>
</body>
</html>
1)data:image/png;base64是什么?
参考 http://blog.csdn.net/c_mihoo/article/details/12774719
Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输。由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要转换一下。针对图片进行Base64编码后,减少一次网络请求。但也不缓存图片了。
2)在线图片转Base64
http://tool.css-js.com/base64.html
3)java实现图片与base64字符串之间的转换
package test; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; public class Base64Test
{ //图片转化成base64字符串
public static String GetImageStr()
{//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
String imgFile = "e://quant.png";//待处理的图片
InputStream in = null;
byte[] data = null;
//读取图片字节数组
try
{
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
//对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);//返回Base64编码过的字节数组字符串
} //base64字符串转化成图片
public static boolean GenerateImage(String imgStr)
{ //对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) //图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
try
{
//Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for(int i=;i<b.length;++i)
{
if(b[i]<)
{//调整异常数据
b[i]+=;
}
}
//生成jpeg图片
String imgFilePath = "e://111.png";//新生成的图片
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return true;
}
catch (Exception e)
{
return false;
}
} public static void main(String[] args)
{
String strImg = GetImageStr();
System.out.println(strImg); } }
2 上传画面到服务器
var curFrame; //当前帧
function savePic(){
console.log("curFrame=\n"+curFrame);
$.ajax({
url : '/TestH5/SnapPicAction',
type : "POST",
data : {
'date': '告警' + Date.now() ,
'pic': '<img src="' + curFrame + '" />'
},
success: function(){
console.log('submit done')
},
error: function(err){
// cache.reqTime = 0;
console.log('error: ' + err)
}
});
}
把捕获的数据帧发送到后台。完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
#myDiv { }
</style>
</head> <body>
<div>
<video width="" height="" autoplay></video>
<canvas width="" height=""></canvas>
<br>
<button id="drawBtn" style="width: 50%;height: 50px;">拍照</button>
<button id="savePicBtn" style="width: 50%;height: 50px;">保存</button>
</div> <script src="js/jquery-3.1.0.js"></script>
<script>
var video = document.querySelector('video');
var canvas = document.querySelector('canvas'); var curFrame; //当前帧 // video捕获摄像头画面
navigator.webkitGetUserMedia({
video : true
}, success, error); function success(stream) {
video.src = window.webkitURL.createObjectURL(stream);
video.play();
} function error(err) {
alert('video error: ' + err)
} //canvas
var context = canvas.getContext('2d'); setTimeout(function() {
//把当前视频帧内容渲染到画布上
context.drawImage(video, , , , );
}, ); var button = document.getElementById('drawBtn');
button.onclick = function() {
context.drawImage(video, , , , );
} $(document).ready(function() { }); //捕获并保存帧内容
function captureAndSaveFrame(){
context.drawImage(video, , , , );
curFrame = canvas.toDataURL(); //转为base64并保存
} function savePic(){
console.log("curFrame=\n"+curFrame); $.ajax({
url : '/TestH5/SnapPicAction',
type : "POST",
data : {
'date': '告警' + Date.now() ,
'pic': '<img src="' + curFrame + '" />'
},
success: function(){
console.log('submit done') },
error: function(err){
// cache.reqTime = 0;
console.log('error: ' + err)
}
}); } var savePicBtn = document.getElementById('savePicBtn');
savePicBtn.onclick = function() {
captureAndSaveFrame();
savePic();
} </script>
</body> </html>
3 保存数据帧的后台业务逻辑
SnapPicAction.java
package com.mobile.action; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.mobile.util.Base64; /**
* Servlet implementation class SnapPicAction
*/
public class SnapPicAction extends HttpServlet {
private static final long serialVersionUID = 1L; public SnapPicAction() {
super();
} protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("--- doGet SnapPicAction"); response.getWriter().append("Served at: ").append(request.getContextPath());
} protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf8"); System.out.println("--- doPost SnapPicActionn --------------------");
String date = request.getParameter("date");
String pic = request.getParameter("pic");
System.out.println("***step0 pic=" + pic);
int beginIdx = pic.indexOf("\"") + ;
int lastIdx = pic.lastIndexOf("\""); String base64Pic = pic.substring(beginIdx, lastIdx).replace("data:image/png;base64,", ""); decodeBase64ToImage(base64Pic, "E://temp3//", "aaa.png"); } public static void decodeBase64ToImage(String base64, String path, String imgName) {
try {
FileOutputStream write = new FileOutputStream(new File(path + imgName));
byte[] decoderBytes = Base64.decode(base64);
write.write(decoderBytes);
write.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
Base64.java
package com.mobile.util;
public class Base64 {
/**
* Base64编码表。
*/
private static final char[] BASE64CODE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '', '', '', '',
'', '', '', '', '', '', '+', '/', };
/**
* Base64解码表。
*/
private static final byte[] BASE64DECODE = { -, -, -, -, -, -, -, -, -, -, -, -, -, -, -, -, -, -,
-, -, -, -, -, -, -, -, -, -, -, -, -, -, // 注意两个63,为兼容SMP,
-, -, -, -, -, -, -, -, -, -, -, , -, , -, , // “/”和“-”都翻译成63。
, , , , , , , , , , -, -, -, , -, -, -, , , , , , , , , , , , , ,
, , // 注意两个0:
, , , , , , , , , , , -, -, -, -, -, // “A”和“=”都翻译成0。
-, , , , , , , , , , , , , , , , , , , , , , , , , , ,
-, -, -, -, -, };
private static final int HEX_255 = 0x0000ff;
private static final int HEX_16515072 = 0xfc0000;
private static final int HEX_258048 = 0x3f000;
private static final int HEX_4032 = 0xfc0;
private static final int HEX_63 = 0x3f;
private static final int HEX_16711680 = 0xff0000;
private static final int HEX_65280 = 0x00ff00;
private static final int NUMBER_TWO = ;
private static final int NUMBER_THREE = ;
private static final int NUMBER_FOUR = ;
private static final int NUMBER_SIX = ;
private static final int NUMBER_EIGHT = ;
private static final int NUMBER_TWELVE = ;
private static final int NUMBER_SIXTEEN = ;
private static final int NUMBER_EIGHTEEN = ;
/**
* 构造方法私有化,防止实例化。
*/
private Base64() {
}
/**
* Base64编码。将字节数组中字节3个一组编码成4个可见字符。
*
* @param b
* 需要被编码的字节数据。
* @return 编码后的Base64字符串。
*/
public static String encode(byte[] b) {
int code = ;
// 按实际编码后长度开辟内存,加快速度
StringBuffer sb = new StringBuffer(((b.length - ) / NUMBER_THREE) << NUMBER_TWO + NUMBER_FOUR);
// 进行编码
for (int i = ; i < b.length; i++) {
code |= (b[i] << (NUMBER_SIXTEEN - i % NUMBER_THREE * NUMBER_EIGHT))
& (HEX_255 << (NUMBER_SIXTEEN - i % NUMBER_THREE * NUMBER_EIGHT));
if (i % NUMBER_THREE == NUMBER_TWO || i == b.length - ) {
sb.append(BASE64CODE[(code & HEX_16515072) >>> NUMBER_EIGHTEEN]);
sb.append(BASE64CODE[(code & HEX_258048) >>> NUMBER_TWELVE]);
sb.append(BASE64CODE[(code & HEX_4032) >>> NUMBER_SIX]);
sb.append(BASE64CODE[code & HEX_63]);
code = ;
}
}
// 对于长度非3的整数倍的字节数组,编码前先补0,编码后结尾处编码用=代替,
// =的个数和短缺的长度一致,以此来标识出数据实际长度
if (b.length % NUMBER_THREE > ) {
sb.setCharAt(sb.length() - , '=');
}
if (b.length % NUMBER_THREE == ) {
sb.setCharAt(sb.length() - NUMBER_TWO, '=');
}
return sb.toString();
}
/**
* Base64解码。
*
* @param code
* 用Base64编码的ASCII字符串
* @return 解码后的字节数据
*/
public static byte[] decode(String code) {
// 检查参数合法性
if (code == null) {
return null;
}
int len = code.length();
if (len % NUMBER_FOUR != ) {
throw new IllegalArgumentException("Base64 string length must be 4*n");
}
if (code.length() == ) {
return new byte[];
}
// 统计填充的等号个数
int pad = ;
if (code.charAt(len - ) == '=') {
pad++;
}
if (code.charAt(len - NUMBER_TWO) == '=') {
pad++;
}
// 根据填充等号的个数来计算实际数据长度
int retLen = len / NUMBER_FOUR * NUMBER_THREE - pad;
// 分配字节数组空间
byte[] ret = new byte[retLen];
// 查表解码
char ch1, ch2, ch3, ch4;
int i;
for (i = ; i < len; i += NUMBER_FOUR) {
int j = i / NUMBER_FOUR * NUMBER_THREE;
ch1 = code.charAt(i);
ch2 = code.charAt(i + );
ch3 = code.charAt(i + NUMBER_TWO);
ch4 = code.charAt(i + NUMBER_THREE);
int tmp = (BASE64DECODE[ch1] << NUMBER_EIGHTEEN) | (BASE64DECODE[ch2] << NUMBER_TWELVE)
| (BASE64DECODE[ch3] << NUMBER_SIX) | (BASE64DECODE[ch4]);
ret[j] = (byte) ((tmp & HEX_16711680) >> NUMBER_SIXTEEN);
if (i < len - NUMBER_FOUR) {
ret[j + ] = (byte) ((tmp & HEX_65280) >> NUMBER_EIGHT);
ret[j + NUMBER_TWO] = (byte) ((tmp & HEX_255));
} else {
if (j + < retLen) {
ret[j + ] = (byte) ((tmp & HEX_65280) >> NUMBER_EIGHT);
}
if (j + NUMBER_TWO < retLen) {
ret[j + NUMBER_TWO] = (byte) ((tmp & HEX_255));
}
}
}
return ret;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>TestH5</display-name> <servlet>
<servlet-name>SnapPicAction</servlet-name>
<servlet-class>com.mobile.action.SnapPicAction</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>SnapPicAction</servlet-name>
<url-pattern>/SnapPicAction</url-pattern>
</servlet-mapping> </web-app>
jquery CDN
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js">
</script>
参考资料:
data:image/png;base64是什么
http://blog.csdn.net/c_mihoo/article/details/12774719
HTML5学习总结-04 音频&视频播放的更多相关文章
- [html5] 学习笔记-html5音频视频
HTML5 最大的新特色之一就是支持音频和视频.在 HTML5 之前,我们必须使用插件如 Silverlight 或 Flash 来实现这些功能.在 HTML5 中,可以直接使用新标签< au ...
- HTML5学习笔记 音频
HTML5提供了播放音频的标准. Web上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件比如flash来播放的.然而,并非所有的浏览器都拥有同样的插件. hmt ...
- HTML5 学习总结(一)——HTML5概要与新增标签
一.HTML5概要 1.1.为什么需要HTML5 HTML4陈旧不能满足日益发展的互联网需要,特别是移动互联网.为了增强浏览器功能Flash被广泛使用,但安全与稳定堪忧,不适合在移动端使用(耗电.触摸 ...
- HTML5 学习笔记(一)——HTML5概要与新增标签
目录 一.HTML5概要 1.1.为什么需要HTML5 1.2.什么是HTML5 1.3.HTML5现状及浏览器支持 1.4.HTML5特性 1.5.HTML5优点与缺点 1.5.1.优点 1.5.2 ...
- html5学习笔记一
HTML5学习笔记 <video>标记:定义视频,Ogg.MPEG4.WebM三种格式 <video src=”movie.ogg” controls=”controls”> ...
- HTML5 学习笔记--------》HTML5概要与新增标签!
一.HTML5概要 1.1.为什么需要HTML5 HTML4陈旧不能满足日益发展的互联网需要,特别是移动互联网.为了增强浏览器功能Flash被广泛使用,但安全与稳定堪忧,不适合在移动端使用(耗电. ...
- 2015第9周三html5学习0
之前规划了2015关注的技术方向是html5和node.js,虽然前面也搜集过html5相关的评论介绍性能容,但对如何学习和有哪些可利用要经常的看的资源有明显的界定,刚上网搜索了半个多小时,对结 ...
- HTML5学习总结——HTML5入门与新增标签
一.HTML5概要 1.1.为什么需要HTML5 概念: HTML5 是继 HTML4.01, XHTML 1.0 和 DOM 2 HTML 后的又一个重要版本, 旨在消除富 Internet 程序( ...
- 测试开发之前端——No9.HTML5中的视频/音频
HTML5 视频和音频的 DOM 参考手册 HTML5 DOM 为 <audio> 和 <video> 元素提供了方法.属性和事件. 这些方法.属性和事件允许您使用 JavaS ...
随机推荐
- c8051f320学习,单片机不外乎时钟、IO、串口、USB等外设用法
时钟 IO(输入.输出,如何配置) IO 数字和模拟资源可以通过25个I/O 引脚(C805 1F3 2 0 ),每个端口引脚都可以被定义为 通用I/O(GPIO)或 0 模拟输入 所有端口I ...
- Sentinel-Redis高可用方案(一):主从复制
引言 大概是因为Redis是个人开发的产品,所以Redis的高可用方案是被分成了几块来实现:主从复制.主从切换以及虚拟IP或客户端方案. 从Redis 2.8开始加入对Sentinel机制从而实现了服 ...
- 十天冲刺---Day1
站立式会议 由于第一天冲刺,所以有些没有昨天完成项和遇到的问题. 站立式会议内容总结: git上Issues内容: 燃尽图(做错了,将每天的燃尽图误以为是每天添加任务然后到一天结束后生成燃尽图(?)) ...
- Java网络编程——TCP实例
1.客户端 1.1:创建服务端点 1.2:获取已有数据 1.3:通过socket输出流将数据发送给服务端 1.4:读取服务端反馈信息 1.5:关闭socket import java.io.Buffe ...
- Qt自定义窗体,边框,圆角窗体
MainWindow::MainWindow(QWidget*parent): QMainWindow(parent), ui(new Ui::MainWindow) { setAttribute(Q ...
- nginx启动、重启、关闭
一.启动 cd usr/local/nginx/sbin ./nginx 二.重启 更改配置重启nginx kill -HUP 主进程号或进程号文件路径 或者使用 cd /usr/local/ngin ...
- 【POJ 2774】Long Long Message 最长公共子串
还是模板啊,手残&&打成||查错查了1h+TAT #include<cstdio> #include<cstring> #include<algorith ...
- selenium+eclispse里代码备注
1.火狐.谷歌和IE浏览器引擎都要重新下载selenium官网引擎,并设置路径才可以支持selenium3 而狐火用自己的引擎不用设置路径既可以支持selenium2也支持selenium3,谷歌和I ...
- 机器学习Python包
随着机器学习的逐日升温,各种相关开源包也是层出不群,面对如此多种类的工具包,该如何选择,有的甚至还知之甚少或者不知呢,本文简单汇总了一下当下使用比较多的Python版本机器学习工具包,供大家参看,还很 ...
- AI,DM,ML,PR的区别与联系
数据挖掘和机器学习的区别和联系,周志华有一篇很好的论述<机器学习与数据挖掘>可以帮助大家理解.数据挖掘受到很多学科领域的影响,其中数据库.机器学习.统计学无疑影响最大.简言之,对数据挖掘而 ...