资讯专栏INFORMATION COLUMN

web技术分享| webRTC 媒体流录制

史占广 / 1716人阅读

摘要:这是因为仅仅意味着将一个媒体元素的属性关联到一个对象上去。若用户拒绝了使用权限,或者需要的媒体源不可用,会回调一个或者。

音视频的录制音视频的分为服务端录制和客户端录制,下面主要讲的是利用webrtc进行客户端录制的方式。
因为WebRTC 录制音视频流之后,最终是通过 Blob 对象将数据保存成多媒体文件的,

  • Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

  • Blob 表示的不一定是JavaScript原生格式的数据。File接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

  • 要从其他非blob对象和数据构造一个 Blob,请使用 Blob() 构造函数。要创建一个 blob 数据的子集 blob,请使用 slice()方法。要获取用户文件系统上的文件对应的 Blob 对象。

  • 接受 Blob 对象的API也被列在 File 文档中。

了解完Blob的特性之后呢, 我们进入正题。

获取元素声明变量

let mediaRecorder;let recordedBlobs;const recordedVideo = document.querySelector("video#recorded");const recordButton = document.querySelector("button#record");const playButton = document.querySelector("button#play");const downloadButton = document.querySelector("button#download");

绑定点击事件

  • URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。

  • URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。你可以在 sourceopen 被处理之后的任何时候调用 revokeObjectURL()。这是因为 createObjectURL() 仅仅意味着将一个媒体元素的 src 属性关联到一个 MediaSource 对象上去。调用revokeObjectURL() 使这个潜在的对象回到原来的地方,允许平台在合适的时机进行垃圾收集。

recordButton.addEventListener("click", () => {    if (recordButton.textContent === "Start Recording") {        startRecording();    } else {        stopRecording();        recordButton.textContent = "Start Recording";        playButton.disabled = false;        downloadButton.disabled = false;    }});playButton.addEventListener("click", () => {    const superBuffer = new Blob(recordedBlobs);    recordedVideo.src = null;    recordedVideo.srcObject = null;    recordedVideo.src = window.URL.createObjectURL(superBuffer);    recordedVideo.controls = true;    recordedVideo.play();});downloadButton.addEventListener("click", () => {    const blob = new Blob(recordedBlobs, {        type: "video/webm"    });    const url = window.URL.createObjectURL(blob);    const a = document.createElement("a");    a.style.display = "none";    a.href = url;    a.download = "test.webm";    document.body.appendChild(a);    a.click();    setTimeout(() => {        document.body.removeChild(a);        window.URL.revokeObjectURL(url);    }, 100);});document.querySelector("button#start").addEventListener("click", async () => {    const constraints = {        audio: {},        video: {            width: 1280,            height: 720        }    };    console.log("Using media constraints:", constraints);    await init(constraints);});

点击开始初始化

  • MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。

  • 它返回一个 Promise 对象,成功后会resolve回调一个 MediaStream 对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promisereject回调一个 PermissionDeniedError 或者 NotFoundError

async function init(constraints) {    try {        const stream = await navigator.mediaDevices.getUserMedia(constraints);        handleSuccess(stream);    } catch (e) {        console.error("navigator.getUserMedia error:", e);    }}function handleSuccess(stream) {    recordButton.disabled = false;    console.log("getUserMedia() got stream:", stream);    window.stream = stream;    const gumVideo = document.querySelector("video#gum");    gumVideo.srcObject = stream;}

开始记录方法

function startRecording() {    recordedBlobs = [];    try {        mediaRecorder = new MediaRecorder(window.stream);    } catch (e) {        console.error("Exception while creating MediaRecorder:", e);        return;    }    recordButton.textContent = "Stop Recording";    playButton.disabled = true;    downloadButton.disabled = true;    mediaRecorder.onstop = (event) => {        console.log("Recorder stopped: ", event);        console.log("Recorded Blobs: ", recordedBlobs);    };    mediaRecorder.ondataavailable = handleDataAvailable;    mediaRecorder.start();}function handleDataAvailable(event) {    if (event.data && event.data.size > 0) {        recordedBlobs.push(event.data);    }}

HTML

DOCTYPE html><html><head>    <meta charset="utf-8">    <meta id="theme-color" name="theme-color" content="#ffffff">    <link rel="stylesheet" href="./index.css">head><body>    <div id="container">        <video id="gum" playsinline autoplay muted>video>        <video id="recorded" playsinline loop>video>        <div>            <button id="start">Start camerabutton>            <button id="record" disabled>Start Recordingbutton>            <button id="play" disabled>Playbutton>            <button id="download" disabled>Downloadbutton>        div>    div>    <script src="./main.js" async>script>body>html>

CSS

button {    background-color: #d84a38;    border: none;    border-radius: 2px;    color: white;    font-family: "Roboto", sans-serif;    font-size: 0.8em;    margin: 0 0 1em 0;    padding: 0.5em 0.7em 0.6em 0.7em;}button:active {    background-color: #cf402f;}button:hover {    background-color: #cf402f;}button[disabled] {    color: #ccc;}button[disabled]:hover {    background-color: #d84a38;}div#container {    margin: 0 auto 0 auto;    max-width: 60em;    padding: 1em 1.5em 1.3em 1.5em;}video {    background: #222;    margin: 0 0 20px 0;    --width: 100%;    width: var(--width);    height: calc(var(--width) * 0.75);}

webRTC功能是非常强大的,关于webrtc和直播还有很多技术需要我们去研究,上续呢是DEMO的示例代码,感兴趣的小伙伴可以亲自试一试。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119786.html

相关文章

  • 【腾讯Bugly干货分享】从0到1打造直播 App

    摘要:流媒体服务器端用来接受视频录制端提供的视频源,同时提供给视频播放端流服务。支持该协议即,是由苹果提出基于的流媒体传输协议。更多配置可以参考下面是的配置文件腾讯云直播后台主要是调用腾讯云。 本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d... 作者:李智文 概要 分享内容: 互联网内容载体变迁历程,文字——...

    Ku_Andrew 评论0 收藏0
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!

    摘要:为了使连接起作用,对等方必须获取元数据的本地媒体条件例如,分辨率和编解码器功能,并收集应用程序主机的可能网络地址,用于来回传递这些关键信息的信令机制并未内置到中。所有特定于多媒体的元数据都使用协议传递。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 18 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里...

    XBaron 评论0 收藏0
  • 我的音视频技术笔记路线图

    摘要:我的文章不同于其他作者,鲜少有手把手入门性质文章这方面我的师哥雷博士已有许多著作在前,多是以某一个技术点为主题,展开进行较为深入的介绍。 恍惚间发现自己的博客文章已...

    Riddler 评论0 收藏0
  • 企业级Android音视频开发学习路线+项目实战+源码解析(WebRTC Native 源码、X26

    摘要:因此,对音视频人才的需求也从小众变成了大众,这更多的是大家对未来市场的预期导致的结果。做个勤奋向上的人,加紧学习,抓住中心,宁精勿杂,宁专勿多。 前言 如今音视频的...

    tomato 评论0 收藏0
  • WebRTC 及点对点网络通信机制

    摘要:本质上允许网页程序创建点对点通信,我们将会在随后的章节中进行介绍。信令涉及网络检索和穿透,会话创建及管理,通信安全,媒体功能元数据和调制及错误处理。这样就会完全建立及激活节点间的网络套接字会话。 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 这是 JavaScript 工作原理第十八章。 概述 何为 WebRTC ?首先,字面上已经...

    Rango 评论0 收藏0

发表评论

0条评论

史占广

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<