HTML5学习总结-04 音频&视频播放

时间:2021-12-25 10:42:52

一 音频播放

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> 上看到摄像头捕获到的画面了:

HTML5学习总结-04 音频&视频播放

  直接在页面中显示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