探索Web前端获取音视频流录制视频

最近整理我的一些独立项目,考虑用音视频的形式记录感想,起初在用Mac系统自带的录屏软件,后来计划能不能用web前端技术开发一款在线录制音视频的工具,小有成果,先用文字形式记录下来。

我在做任何一件事情之前,一定是先被一件具体的事给刺激到,萌生出一个模糊的不知所云的概念,深入思考发现这个概念对我或对环境具有某种或大或小的意义,从而激发我产生将概念变为实事儿的行动的力量。也许此时我还不明白最后能做成什么,那就先做可行性研究,边研究边修正概念,概念从模糊到清晰。在这个循环过程中,一个概念也许会分成许多个旁支概念。再研究再修正,最终明白了什么,也更坚定。

概念从模糊到清晰 - 陈帅华涂鸦

技术可行性

在阅读了大量权威组织发布的文档,以及吸收前人做过的尝试之后。经过分析,目前Web前端技术栈是可以实现在线录制音视频的。我将可录制的媒体源分为三大类:第一类是最常用的——摄像头和麦克风两个媒体源;第二类是屏幕显示媒体源,也就是录屏能力,屏幕录制包括对整个屏幕的录制和对单个应用程序窗口的录制;第三类是HTML5元素媒体源,可以将video和canvas等HTML5元素当作媒体源进行录制。

了解了目前Web前端技术的边界,结合我的初心——用音视频的形式记录和分享我的想法——需要录屏、录像和录音。也就是说我的需求里涉及到上面三大类媒体源中的前两大类——摄像头麦克风和屏幕显示。这样我就能把在电脑上的操作录制下来,偶尔搭配使用摄像头和麦克风录像和录音📹。

目标再一次明确之后,尝试制作demo,以Chrome浏览器作调试工具,暂不考虑其他浏览器兼容性问题和解决方案。只为体验最新前端技术。需要注意,只有以https协议访问的网页才具备访问媒体设备源的权限,我的博客网站既可以使用http协议访问也可以使用https协议。

提供Web API详细参考:

  1. Media Capture and Streams API (Media Stream)
  2. MediaDevices.getUserMedia()
  3. MediaStream Recording API

屁话少说,放码过来

下面是我代码中获取音视频流的工具函数。

function getUserMediaStream(constraints, cb) {
  navigator.mediaDevices.getUserMedia(constraints)
    .then(stream => { cb(null, stream); })
    .catch(err => { cb(err, null); });
}

下面是我代码中定义的获取屏幕显示媒体流的工具函数。

function getDisplayMediaStream(cb) {
  navigator.mediaDevices.getDisplayMedia()
    .then(stream => { cb(null, stream); })
    .catch(err => { cb(err, null); })
}

下面是我代码中定义的bufferdataUrl工具函数。

function bufferToDataUrl(buffer, cb) {
  let blob = new Blob(buffer, { type: "video/webm" });
  let reader = new FileReader();
  reader.onload = function() { cb(reader.result) };
  reader.readAsDataURL(blob);
}

下面是我代码中定义的dataUrl转文件的工具函数。

function dataUrlToFile(dataUrl) {
  let binary = atob(dataUrl.split(",")[1]);
  let data = [];
  for (var i = 0; i < binary.length; i++)
    data.push(binary.charCodeAt(i));

  return new File([new Uint8Array(data)], "recorded-video.webm", {
    type: "video/webm"
  });
}

写在最后

我发现写文章真是梳理想法的最好手段之一。当脑子里灵光的乍现,就像是一只猫突然出现将一筐毛线球🧶打翻在地。当我满心好奇地走进这可能转瞬即逝的灵光之中,就像那只猫跳到地上。当我想对这灵光内一探究竟,就像那只不老实的猫🐱把滚落一地的毛线球🧶弄的七扯八折乱七八糟。当我试着安静🤫下来(我知道当灵感来了我的情绪很难控制),努力用文字将想法写出来,老实说这过程确实太TM痛苦。这个过程就像我需要把被🐱猫弄了一地的凌乱的毛线捋顺一样。最困难的也是最关键的就是是找到线头在哪里。而把想法写成文字就是找线头和捋顺毛线的过程。

一只猫打翻一地毛线

我需要更多的耐心,一不小心线头就打了死结。就像想法突然消失,忘记刚才想到了哪里(除了心理因素,不知道这和生理因素有无关系)。只能从想法的源头重新走过,盼着重新唤醒消失的念头,解开死结。

我发现比写文字要简单的梳理想法的手段是涂鸦——也就是脑图。我想到什么就画什么,最后呈现的就是连续的想法。可爱的小孩儿还保留着原始人在山洞墙壁内涂涂画画的原始本能。

比写文字更难的就是录制视频了,因为视频包括声音描述、画面描述和文字描述,比前两者(文字和涂鸦还多一条音轨)。老实说,即使一个想法在我脑子里已经熟悉到陌生,要我立即开口用声音描述,我也会一时哑口无言。任何需要后天努力的本事都需要不断的练习才能获得。

文字、声音、画面,每一轨都可以单独拎出来作为表现想法的独立形式。而它们一起使用是加法还是减法呢?目前我的大部分文章都有了文字和画面两种传达形式,唯独缺少声音的位置,这也是我研究并开发一款我自己觉得好用的在线音视频处理工具的初心。

最后要说,我喜欢那只时常突然闯入我的——好奇的猫🐱,即使因为它的突然闯入,打翻了一地毛线🧶,也同时给我带来了什么。

授权账号 » 
原创声明 » 未经授权,请勿复制转载,谢谢配合
联系方式 » 
微信:huazi19930927
邮箱:lanserdi@163.com
发布日期 » 2019年8月26日 周一
2条留言 · Github账号登录以留言

陈帅华 · 2019年8月27日 · 第2楼

避而不谈的是真相,需细细琢磨。
悬而未决的是争议,需从长计议。

陈帅华 · 2019年8月27日 · 第1楼

1. 你是知道什么是对什么是错?!
2. 你知道能决定你的行动的只有你自己?!
3. 你知道大多数人对你的一切的态度是冷漠,充其量抱着看热闹的心态?!