赞
踩
MediaDevices.getUserMedia()会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。
它返回一个 Promise
对象,成功后会resolve
回调一个 MediaStream
对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise
会reject
回调一个 PermissionDeniedError
或者 NotFoundError
。
navigator.mediaDevices.getUserMedia详细的使用方法以及API可以去看官方文档
MediaRecorder()
构造函数会创建一个对指定的 MediaStream
进行录制的 MediaRecorder
对象。
这里的MediaStream就是上面resolve返回的那个MediaStream。
语法:
var mediaRecorder = new MediaRecorder(stream[, options]);
MediaStream
将要录制的流. 它可以是来自于使用 navigator.mediaDevices.getUserMedia()
创建的流或者来自于,以及DOM元素.
option(可选):
一个对象,包含一下属性:
mimeType
: 为新构建的 MediaRecorder
指定录制容器的MIME类型. 在应用中通过调用 MediaRecorder.isTypeSupported()
来检查浏览器是否支持此种mimeType
.audioBitsPerSecond
: 指定音频的比特率.videoBitsPerSecond
: 指定视频的比特率.bitsPerSecond
: 指定音频和视频的比特率. 此属性可以用来指定上面两个属性. 如果上面两个属性只有其中之一和此属性被指定, 则此属性可以用于设定另外一个属性.window.MediaRecorder详细使用方法可以去看官方文档
使用react框架实现,调用的是原生方法,其他框架的写法都差不多。
页面结构:
<div>
{/* 这个video标签录制时看到实时画面使用 */}
<video src="" ref='video' className={styles.video}></video>
<button onClick={this.clickStart.bind(this)}>开始</button>
<button onClick={this.clickEnd.bind(this)}>停止</button>
{
this.state.chunkURL ? <a href={this.state.chunkURL} download='test.webm'>点击下载</a> : ''
}
{/* 这个video标签是录制完后把录制之后的数据处理为二进制流后进行展示使用 */}
<video src={this.state.chunkURL} className={styles.video} ref='newvideo'></video>
</div>
1、在页面加载的时候需要把使用媒体输入和创建录制视屏的弄好。
下面代码是需要在页面加载的时候完成。
init() {
navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(
(stream) => {
this.recorder = new window.MediaRecorder(stream)
this.setState({
stream: stream
})
},
(error) => {
alert("出错,请确保已允许浏览器获取音视频权限");
}
);
}
2、点击开始需要干的事情
(1)把第一个video标签的srcObject属性和navigator.mediaDevices.getUserMedia成功返回的stream关联上
(2)video的muted属性是是否静音,值是布尔值,true为静音
(3)让视屏播放起来
(4)让recorder开始录制
(5)给recorder绑定上ondataavailable和onstop的回调 ondataavailable:当有又用的数据的时候触发,onstop:停止录制当然时候触发
// 给record绑定事件的回调 bindEvents() { this.recorder.ondataavailable = (e) => { this.setState({ chunk: e.data }) } this.recorder.onstop = () => { let blob = new Blob([this.state.chunk], { type: 'video/webm' }) let videoStream = URL.createObjectURL(blob); this.setState({ chunkURL: videoStream }) setTimeout(()=>{ console.log(this.state.chunkURL); },5000) this.refs.newvideo.play() } } // 点击开始 clickStart() { this.onPreview() this.onStart() this.bindEvents() } onPreview() { this.refs.video.srcObject = this.state.stream this.refs.video.muted = true this.refs.video.play(); } onStart() { this.recorder.start(); }
3、点击结束
点击结束按钮调用record的stop事件停止录制,同时将第一个video标签暂停,不暂停也不影响,只有一直有摄像头拍到的实时画面但是不会录制。
clickEnd() {
this.recorder.stop()
this.refs.video.pause()
}
import React from 'react' import styles from './index.less' class VideoDemo extends React.Component { constructor(prop) { super(prop) this.state = { recorder: null, stream: null, chunk: null, chunkURL: null } this.recorder = null } render() { return ( <div> {/* 这个video标签录制时看到实时画面使用 */} <video src="" ref='video' className={styles.video}></video> <button onClick={this.clickStart.bind(this)}>开始</button> <button onClick={this.clickEnd.bind(this)}>停止</button> { this.state.chunkURL ? <a href={this.state.chunkURL} download='test.webm'>点击下载</a> : '' } {/* 这个video标签是录制完后把录制之后的数据处理为二进制流后进行展示使用 */} <video src={this.state.chunkURL} className={styles.video} ref='newvideo'></video> </div> ) } init() { navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then( (stream) => { this.recorder = new window.MediaRecorder(stream) this.setState({ stream: stream }) }, (error) => { alert("出错,请确保已允许浏览器获取音视频权限"); } ); } // 给record绑定事件的回调 bindEvents() { this.recorder.ondataavailable = (e) => { this.setState({ chunk: e.data }) } this.recorder.onstop = () => { let blob = new Blob([this.state.chunk], { type: 'video/webm' }) let videoStream = URL.createObjectURL(blob); this.setState({ chunkURL: videoStream }) setTimeout(()=>{ console.log(this.state.chunkURL); },5000) this.refs.newvideo.play() } } // 点击开始 clickStart() { this.onPreview() this.onStart() this.bindEvents() } onPreview() { this.refs.video.srcObject = this.state.stream this.refs.video.muted = true this.refs.video.play(); } onStart() { this.recorder.start(); } clickEnd() { this.recorder.stop() this.refs.video.pause() } componentDidMount() { this.init() } } export default VideoDemo
less样式代码
.video{
width: 100vw;
height: 50vh;
}
1、如果只想录制声音或是其他什么的只需要改init方法里面getUserMedia方法里的参数。
()
}
componentDidMount() {
this.init()
}
}
export default VideoDemo
less样式代码
.video{
width: 100vw;
height: 50vh;
}
## 总结
1、如果只想录制声音或是其他什么的只需要改init方法里面getUserMedia方法里的参数。
2、本来想实现a标签下载的,但是不知道为什么下载下来的视屏是黑色的没有画面。该问题还未解决,解决了再来更新。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。