一、监听开始事件
- eventtarget.addeventlistener() 方法将指定的监听器注册到
eventtarget
上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素element
,document
和window
或者任何其他支持事件的对象 (比如 xmlhttprequest)。 addeventlistener()
的工作原理是将实现eventlistener的函数或对象添加到调用它的eventtarget上的指定事件类型的事件侦听器列表中。
document.queryselector('button#start').addeventlistener('click', async () => { document.queryselector('button#start').disabled = true; const constraints = { audio: {}, video: { width: 1280, height: 720 } }; await init(constraints); });
二、获取音视频轨道
mediadevices.getusermedia()
会提示用户给予使用媒体输入的许可,媒体输入会产生一个mediastream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、a/d转换器等等),也可能是其它轨道类型。- 它返回一个 promise 对象,成功后会resolve回调一个
mediastream
对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise会reject回调一个 permissiondeniederror 或者notfounderror
。
async function init(constraints) { try { const stream = await navigator.mediadevices.getusermedia(constraints); handlesuccess(stream); } catch (e) { console.error('navigator.getusermedia error:', e); } }
htmlmediaelement
接口的 srcobject 属性设定或返回一个对象,这个对象提供了一个与htmlmediaelement关联的媒体源,这个对象通常是 mediastream ,但根据规范可以是 mediasource, blob 或者 file。
function handlesuccess(stream) { recordbutton.disabled = false; window.stream = stream; const gumvideo = document.queryselector('video#gum'); gumvideo.srcobject = stream; }
三、录制媒体流
mediarecorder()
构造函数会创建一个对指定的mediastream
进行录制的mediarecorder
对象mediarecorder.ondataavailable
事件处理程序api处理dataavailable
事件,在响应运行代码blob数据被提供使用。dataavailable
当mediarecorder
将媒体数据传递到您的应用程序以供使用时,将触发该事件。数据在包含数据的blob对象中提供。
这在四种情况下发生:
- 媒体流结束时,所有尚未传递到
ondataavailable
处理程序的媒体数据都将在单个blob中传递。 - 当调用
mediarecorder.stop() (en-us)
时,自记录开始或dataavailable事件最后一次发生以来已捕 获的所有媒体数据都将传递到blob中;此后,捕获结束。 - 调用
mediarecorder.requestdata() (en-us) dataavailable
时,将传递自记录开始或事件最后一次发生以来捕获的所有媒体数据;然后blob创建一个新文件,并将媒体捕获继续到该blob中。 - 如果将
timeslice
属性传递到开始媒体捕获的mediarecorder.start() (en-us)
方法中,dataavailable则每timeslice毫秒触发一次事件。这意味着每个blob都有特定的持续时间(最后一个blob除外,后者可能更短,因为它将是自上次事件以来剩下的所有东西)。
let mediarecorder; const recordbutton = document.queryselector('button#record'); recordbutton.addeventlistener('click', () => { if (recordbutton.textcontent === '开始记录') { startrecording(); } else { stoprecording(); recordbutton.textcontent = '开始记录'; playbutton.disabled = false; } }); function startrecording() { recordedblobs = []; try { mediarecorder = new mediarecorder(window.stream); } catch (e) { console.error('创建mediarecorder时异常:', e); } recordbutton.textcontent = '停止记录'; playbutton.disabled = true; mediarecorder.ondataavailable = handledataavailable; mediarecorder.start(); } function stoprecording() { mediarecorder.stop(); } function handledataavailable(event) { if (event.data && event.data.size > 0) { recordedblobs.push(event.data); } }
四、播放媒体流
url.createobjecturl()
静态方法会创建一个domstring
,其中包含一个表示参数中给出的对象的url。这个 url 的生命周期和创建它的窗口中的 document 绑定。这个新的url 对象表示指定的 file 对象或 blob 对象。
let recordedblobs; const recordedvideo = document.queryselector('video#recorded'); const playbutton = document.queryselector('button#play'); playbutton.addeventlistener('click', () => { const superbuffer = new blob(recordedblobs, { type: 'video/webm' }); recordedvideo.src = null; recordedvideo.srcobject = null; recordedvideo.src = window.url.createobjecturl(superbuffer); recordedvideo.controls = true; recordedvideo.play(); });
html:
<link rel="stylesheet" href="./index.css"> <video id="gum" autoplay></video> <video id="recorded"></video> <div> <button id="start">开始</button> <button id="record" disabled>开始记录</button> <button id="play" disabled>play</button> </div> <script src="./index.js"></script>
css:
button { margin: 0 3px 10px 0; padding-left: 2px; padding-right: 2px; width: 99px; } button:last-of-type { margin: 0; } video { vertical-align: top; --width: 25vw; width: var(--width); height: calc(var(--width) * 0.5625); } video:last-of-type { margin: 0 0 20px 0; } video#gumvideo { margin: 0 20px 20px 0; }
javascript:
let mediarecorder; let recordedblobs; const recordedvideo = document.queryselector('video#recorded'); const recordbutton = document.queryselector('button#record'); recordbutton.addeventlistener('click', () => { if (recordbutton.textcontent === '开始记录') { startrecording(); } else { stoprecording(); recordbutton.textcontent = '开始记录'; playbutton.disabled = false; } }); const playbutton = document.queryselector('button#play'); playbutton.addeventlistener('click', () => { const superbuffer = new blob(recordedblobs, { type: 'video/webm' }); recordedvideo.src = null; recordedvideo.srcobject = null; recordedvideo.src = window.url.createobjecturl(superbuffer); recordedvideo.controls = true; recordedvideo.play(); }); function handledataavailable(event) { if (event.data && event.data.size > 0) { recordedblobs.push(event.data); } } function startrecording() { recordedblobs = []; try { mediarecorder = new mediarecorder(window.stream); } catch (e) { console.error('创建mediarecorder时异常:', e); } recordbutton.textcontent = '停止记录'; playbutton.disabled = true; mediarecorder.ondataavailable = handledataavailable; mediarecorder.start(); } function stoprecording() { mediarecorder.stop(); } function handlesuccess(stream) { recordbutton.disabled = false; window.stream = stream; const gumvideo = document.queryselector('video#gum'); gumvideo.srcobject = stream; } async function init(constraints) { try { const stream = await navigator.mediadevices.getusermedia(constraints); handlesuccess(stream); } catch (e) { console.error('navigator.getusermedia error:', e); } } document.queryselector('button#start').addeventlistener('click', async () => { document.queryselector('button#start').disabled = true; const constraints = { audio: {}, video: { width: 1280, height: 720 } }; await init(constraints); });
到此这篇关于webrtc记录音视频流(web技术分享)的文章就介绍到这了,更多相关webrtc记录音视频流内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章,希望大家以后多多支持www.887551.com!
黄山市民网:https://www.huangshanshimin.com/