1.Navigator
接口表示用户代理的状态和标识。它允许脚本查询它和注册自己进行一些活动。
Navigator
2.mediaDevices
是 Navigator 只读属性,返回一个 MediaDevices 对象,该对象可提供对相机和麦克风等媒体输入设备的连接访问,也包括屏幕共享。
Navigator.mediaDevices
3.MediaDevices.getUserMedia()
会提示用户给予使用媒体输入的许可,媒体输入会产生一个媒体流(MediaStream
),里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道、一个音频轨道,也可能是其它轨道类型。
MediaDevices.getUserMedia()
语法:
// 指定请求的媒体类型(音频、视频)
var constraints = { audio: true, video: true };
// 它返回一个 Promise 对象,成功后会resolve回调一个 MediaStream 对象
var promise = navigator.mediaDevices.getUserMedia(constraints);
4.Promise
是一个对象,它代表了一个异步操作的最终完成或者失败。本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。
使用 Promise
语法:
// 绑定回调函数
promise.then(成功时调用的函数)
.catch(失败时调用的函数)
5.MediaRecorder
是 MediaStream Recording API 提供的用来进行媒体轻松录制的接口,他需要通过调用 MediaRecorder() 构造方法进行实例化。
MediaRecorder
事件处理:
// 该事件可用于获取录制的媒体资源
MediaRecorder.ondataavailable
// 用来处理 start 事件,该事件在媒体开始录制时触发
MediaRecorder.onstart
// 用来处理 stop 事件,该事件会在媒体录制结束时
MediaRecorder.onstop
回到目录…
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户中心title>
head>
<body>
<input type="text" id="title">
<button id="stop">停止录制button>
<audio controls>audio>
<script src="./js/record.js">script>
body>
html>
// 发送 Ajax 请求
function upload(title, content) {
var xhr = new XMLHttpRequest()
// 由于我们要把声音放在请求体中发送,所以必须使用 post 方法
// 这里是 ajax 发起的请求,所以,后续要怎么处理完全是 js 决定的
// 所以,这里就不使用 *.do 这种 URL 了
xhr.open('post', `/studio/track/record.json?title=${title}`)
xhr.onload = function() {
console.log(this.status)
console.log(this.responseText)
}
xhr.send(content)
}
// 为了让 js 代码可以在所有资源都加载完成后才去执行,就入口代码放在 window 的 load 事件处理中
window.onload = function() {
// 执行这个方法的时候,说明所有资源都被加载好了
if(!navigator.mediaDevices.getUserMedia) {
alert("该浏览器不支持媒体访问,请更换浏览器!")
return
}
var constraints = { audio: true }
var promise = navigator.mediaDevices.getUserMedia(constraints)
// stream 的类型就是 MediaStream (媒体流)
// 里面有从麦克风采集到的声音
function onSuccess(stream) {
alert('用户授权成功')
var mediaRecorder = new MediaRecorder(stream)
// 当开始录制后,这个方法会被调用
mediaRecorder.onstart = function () {
console.log('开始录制')
}
// 放置过程中录制下来的声音数据
var data = []
// 当数据可用时,会被调用
mediaRecorder.ondataavailable = function(evt) {
console.log('数据可用')
console.log(evt)
// evt.data 是一个 Blob 类型的,表示录制下来的声音片段的对象
data.push(evt.data)
}
// 当停止录制后(一切完成),这个方法会被调用
mediaRecorder.onstop = function() {
console.log('停止录制')
console.log(data)
// 将一组数据,组成一个统一的数据
var title = document.querySelector('#title').value.trim()
var type = "audio/ogg; codecs=opus"
var blob = new Blob(data, {
// 类型认为是死规定
type: type
})
// 将数据生成一个方便播放的 URL
var url = URL.createObjectURL(blob)
console.log(url)
// 找到 audio 元素,修改 src 属性,让页面上的
// 音频播放器可以播放我们录制下来的声音
var oAudio = document.querySelector('audio')
oAudio.src = url
upload(title, blob)
}
document.querySelector('#stop').onclick = function() {
mediaRecorder.stop()
}
// 开始录制,每1s生成一次数据
mediaRecorder.start(1000)
}
function onError(error) {
alert('授权过程中出现了错误: ' + error)
}
promise.then(onSuccess).catch(onError)
}
回到目录…
ObjectMapper使用详细介绍
@WebServlet("/studio/track/record.json")
public class RecordJsonServlet extends HttpServlet {
private final ObjectMapper objectMapper = new ObjectMapper();
private final TrackRepo trackRepo = new TrackRepo();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String title = req.getParameter("title");
String type = req.getHeader("Content-Type");
Log.println("title: " + title);
Log.println("type: " + type);
UserVO currentUser = null;
HttpSession session = req.getSession(false);
if (session != null) {
currentUser = (UserVO) session.getAttribute("currentUser");
}
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/json");
PrintWriter writer = resp.getWriter();
if (currentUser == null) {
Log.println("用户未登录");
HashMap<String, Boolean> result = new HashMap<>();
result.put("result", false);
String json = objectMapper.writeValueAsString(result);
Log.println(json);
writer.println(json);
return;
}
trackRepo.insert(currentUser.uid, title, type, req.getInputStream());
Log.println("将数据保存到数据库表中");
HashMap<String, Boolean> result = new HashMap<>();
result.put("result", true);
String json = objectMapper.writeValueAsString(result);
Log.println(json);
writer.println(json);
// 完整的音频数据放在 InputStream(请求体)
// ServletInputStream is = req.getInputStream();
// try (OutputStream os = new FileOutputStream("D:\\upload" + title + ".ogg")) {
// byte[] buf = new byte[4096];
// while (true) {
// int n = is.read(buf);
// Log.println("读到了: " + n);
// if (n == -1) {
// break;
// }
// os.write(buf, 0, n);
// }
// os.flush();
// }
}
}
回到目录…
总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是WebAPI的学习,实现了一个上传音频的小应用,如何访问连接媒体输入设备,如何通过Ajax发出请求,后端做出响应处理音频数据。之后的学习内容将持续更新!!!