主要参考了 https://zhuanlan.zhihu.com/p/25162723 ,作者没有提供详细的demo,所以自己简单写了个。以及添加了实时录制视频功能,修复了苹果手机无法实时显示视频的bug。
在线demo:https://ccmkjzx002.zgyyxykj.com/123.html
备注 :在线demo不会上传任何录制的视频,仅作展示
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>在线录制视频demo</title>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
video {
width: 100%;
}
body {
padding: 20px;
background: #f5f5f5;
}
</style>
</head>
<body>
<h1>在线录制视频demo</h1>
<hr>
<div id="record-div">
<h3>实时画面</h3>
<video id="play" playsinline autoplay x5-video-player-type="h5" style='object-fit:fill'></video>
<hr>
<div class="btn btn-success" onclick="start_record()">开始录制</div>
<div class="btn btn-warning" onclick="stop_record()">停止录制</div>
</div>
<video id="record" controls="" playsinline autoplay x5-video-player-type="h5" style='display: none;object-fit:fill'></video>
</body>
</html>
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
<script>
var MediaUtils = {
/**
* 获取用户媒体设备(处理兼容的问题)
* @param videoEnable {boolean} - 是否启用摄像头
* @param audioEnable {boolean} - 是否启用麦克风
* @param callback {Function} - 处理回调
*/
getUserMedia: function(videoEnable, audioEnable, callback) {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
navigator.msGetUserMedia || window.getUserMedia;
var constraints = { video: videoEnable, audio: audioEnable };
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
if (window.stream) {
window.stream.getTracks().forEach(track => {
track.stop();
});
}
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
callback(false, stream);
})['catch'](function(err) {
callback(err);
});
} else if (navigator.getUserMedia) {
navigator.getUserMedia(constraints, function(stream) {
callback(false, stream);
}, function(err) {
callback(err);
});
} else {
callback(new Error('Not support userMedia'));
}
},
/**
* 关闭媒体流
* @param stream {MediaStream} - 需要关闭的流
*/
closeStream: function(stream) {
if (typeof stream.stop === 'function') {
stream.stop();
} else {
let trackList = [stream.getAudioTracks(), stream.getVideoTracks()];
for (let i = 0; i < trackList.length; i++) {
let tracks = trackList[i];
if (tracks && tracks.length > 0) {
for (let j = 0; j < tracks.length; j++) {
let track = tracks[j];
if (typeof track.stop === 'function') {
track.stop();
}
}
}
}
}
}
};
// 用于存放 MediaRecorder 对象和音频Track,关闭录制和关闭媒体设备需要用到
var recorder, mediaStream;
// 用于存放录制后的音频文件对象和录制结束回调
var recorderFile, stopRecordCallback;
// 用于存放是否开启了视频录制
var videoEnabled = false;
// 录制短语音
function startRecord(enableVideo, isStart) {
videoEnabled = enableVideo;
MediaUtils.getUserMedia(enableVideo, true, function(err, stream) {
if (err) {
throw err;
} else {
var video = $('#play')[0];
video.setAttribute('autoplay', '');
video.setAttribute('muted', '');
video.setAttribute('playsinline', '');
video.srcObject = stream;
video.onloadedmetadata = function(e) {
video.play();
};
if (isStart) {
// 通过 MediaRecorder 记录获取到的媒体流
recorder = new MediaRecorder(stream);
mediaStream = stream;
var chunks = [],
startTime = 0;
recorder.ondataavailable = function(e) {
chunks.push(e.data);
};
recorder.onstop = function(e) {
recorderFile = new Blob(chunks, { 'type': recorder.mimeType });
chunks = [];
if (null != stopRecordCallback) {
stopRecordCallback();
}
};
recorder.start();
}
}
});
}
// 停止录制
function stopRecord(callback) {
stopRecordCallback = callback;
// 终止录制器
recorder.stop();
// 关闭媒体流
MediaUtils.closeStream(mediaStream);
}
// 播放录制的音频
function playRecord() {
var url = URL.createObjectURL(recorderFile);
$('#play').hide();
$('#record').show().attr({
autoplay: true,
src: url,
});
// var dom = document.createElement(videoEnabled ? 'video' : 'audio');
// dom.autoplay = true;
// dom.src = url;
// if (videoEnabled) {
// dom.width = 640;
// dom.height = 480;
// dom.style.zIndex = '9999999';
// dom.style.position = 'fixed';
// dom.style.left = '0';
// dom.style.right = '0';
// dom.style.top = '0';
// dom.style.bottom = '0';
// dom.style.margin = 'auto';
// document.body.appendChild(dom);
// }
}
function start_record() {
// 启动录制视频 (若需要录制音频参数指定为 false 即可)
startRecord(true, true);
}
function stop_record() {
$('#record-div').hide();
// 结束
stopRecord(function() {
// 播放
playRecord();
});
}
startRecord(true);
</script>
网友评论