码上掘金不仅可以写 PPT,还可以录视频

sxkk20081年前知识分享103

我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!

前言

短视频作为新时代的产物,到现在才发展了几年的时间,创作者们看到了短视频的红利,有不少人已经通过视频录制和知识付费的方式实现了流量的变现,当然这只是一少部分人,还有成千上万的热涌向这个风口,他们在干什么?他们正在学习视频录制、视频剪辑的路上。

短视频的入门门槛虽然很低,但想要获得流量还是有一定门槛的,我今年的 flag 之一就是学习视频制作剪辑,前段时间剪了一个视频总共 1 分 20 秒,就花了我一整天的时间,那么我在想,作为前端工程师能不能开发一款产品,让短视频创作更低,后来我看到了一款贴合程序员的产品 Slidev,可以让我们使用 markdown 写 PPT,并且可以录制视频。

前端实现视频录制

好了,正文开始,本文基于我之前写的一篇文章《Markdown 写 PPT 是如何实现的?》,我们要在此之上实现视频录制的功能。

使用 WebRTC 的 API 可以实现了一个录音、录像、录屏工具

我们先使用 React 写一个录制的组件

import React, { useState, useRef } from 'react'
import ReactDom from 'react-dom'

const App = () => {
  const [videoUrl, setVideoUrl] = useState<string>('')

  // 结束
  const stopRecord = async () => {}

  // 开始
  const startRecord = async () => {}

  const pauseRecord = async () => {}

  const resumeRecord = async () => {}

  return (
    <div>
      <h1>React 录屏h1>
      <video className="video" src={videoUrl} controls />
      <h2>
        <button onClick={startRecord}>开始button>
        <button onClick={pauseRecord}>暂停button>
        <button onClick={resumeRecord}>恢复button>
        <button onClick={stopRecord}>停止button>
      h2>
    div>
  )
}

ReactDom.render(<App />, document.getElementById('app'))

上面有一个 video 标签,以及 开始、停止、暂停、恢复、几个按钮用于控制屏幕的录制。

const mediaStream = useRef<MediaStream>()
const audioStream = useRef<MediaStream>()
const recorder = useRef<MediaRecorder>()
const mediaBlobs = useRef<Blob[]>([])

我们使用 useRef 来存放数据,mediaStream 存放视频流, audioStream 存放音频流,recorder 存放视频录制对象,mediaBlobs 将流转化为 Blob 对象。

下面代码是开始录制和结束录制的逻辑:

// 结束
const stopRecord = async () => {
  recorder.current?.stop()
  // 不仅让 MediaRecorder 停止,还要让所有轨道停止
  mediaStream.current?.getTracks().forEach((track) => track.stop())
}

// 开始
const startRecord = async () => {
  // 录屏接口
  mediaStream.current = await navigator.mediaDevices.getDisplayMedia({ video: true })
  // 主动停止录制
  mediaStream.current?.getTracks()[0].addEventListener('ended', () => {
    stopRecord()
  })
  // 录音接口
  audioStream.current = await navigator.mediaDevices.getUserMedia({ audio: true })
  // 往视频流中加入音频流
  audioStream.current
    ?.getAudioTracks()
    .forEach((audioTrack) => mediaStream.current?.addTrack(audioTrack))
  // 录制视频流
  recorder.current = new MediaRecorder(mediaStream.current)

  // 将 stream 转成 blob 来存放
  recorder.current.ondataavailable = (blobEvent) => {
    mediaBlobs.current.push(blobEvent.data)
  }
  // 停止时生成预览的 blob url
  recorder.current.onstop = () => {
    const blob = new Blob(mediaBlobs.current, { type: 'video/mp4' })
    //来生成预览链接
    const mediaUrl = URL.createObjectURL(blob)
    setVideoUrl(mediaUrl)
  }

  recorder.current?.start()
}

上述代码先通过 navigator.mediaDevices.getDisplayMedia 获取用户选中的录屏流,接着通过 navigator.mediaDevices.getUserMedia({ audio: true })获取音频流,然后通过 mediaStream.current?.addTrack(audioTrack) 将所有音频流加入到视频流中。再通过 MediaRecorder 录制视频流,通过 ondataavailable 来存放当前流中的 Blob 数据。 最后一步,调用 URL.createObjectURL 来生成预览链接。

下面是暂停和恢复的实现代码,是 MediaRecorder 提供的方法

const pauseRecord = async () => {
  recorder.current?.pause()
}

const resumeRecord = async () => {
  recorder.current?.resume()
}

这样就实现了一个在线录屏的 Demo,一起在“码上掘金”中看看效果吧。

代码片段

实现幻灯片演讲录制

接下来我们将视频录制的功能集成到之前的幻灯片中,只需要将上面的 App 组件改成 RecordView 组件,并且通过 position: fixed; 属性将操作按钮定位到幻灯片之上。

录制完成后,通过创建一个 a 标签,就可以实现自动下载。

下面是自动下载的代码:

export function downloadBlob(blob, filename) {
  let element = document.createElement('a')
  element.setAttribute('href', blob)
  element.setAttribute('download', filename)
  element.style.display = 'none'
  document.body.appendChild(element)
  element.click()
  document.body.removeChild(element)
}

同样我们在“码上掘金”中看看效果吧。 代码片段 鼠标移动到左下角会显示操作按钮,我们还可以点击编辑按钮对幻灯片进行实时编辑,这么简单就实现了想要的效果,简直不可思议。

竖屏录制

目前短视频都是竖屏的,我们那么能否录制竖屏版的视频呢?答案是可以的,但是在“码上掘金”中不能,因为“码上掘金”是一个代码编辑器,在移动端无法访问,因此我还将这个应用部署到了 vercel 上,大家可以通过这个地址访问 :

http://ppt.runjs.cool/

打开 Chrome devtools 选择手机调试模式,选中一个合适的型号,便可以开始录制了,录制的时候选中当前网页就可以了。

竖屏录制

这样保存下来的视频便是竖屏的。

最后,我将这个工程的源码上传到了 GitHub:https://github.com/maqi1520/vitejs-md-ppt

目前还比较粗糙,经过精雕细琢后可能会成为一个好产品,先占个坑吧!

小结

本文用 WebRTC 的 API 简单地实现了一个录屏工具,并且可以结合 markdown 写 PPT 实现录制幻灯片的功能,我们一起来梳理下录屏的实现逻辑

  • 使用 getUserMedia 可获取麦克风以及摄像头的流;
  • 使用 getDisplayMedia 可获取屏幕的视频、音频流;
  • 使用 MediaRecorder 可监听 stream, 从而获取 Blob 数据;
  • 最后使用 URL.createObjectURLBlob 转为下载链接;

以上就是本文全部内容,如果对你有帮助,可以随手点个赞,这对我真的很重要,希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。

相关文章

AI绘画生成器:探究人工智能发展中的艺术生产力

AI绘画生成器:探究人工智能发展中的艺术生产力

  随着人工智能技术的不断发展,各行业开始将其与实际应用相结合,比如在艺术创作领域中,越来越多的人开始尝试使用AI绘画生成器进行创作。这一工具可以让普通用户轻松创作出具有艺术...

AI机器人的发展带来的风险及应对措施

AI机器人的发展带来的风险及应对措施

  近年来,随着人工智能技术的发展,越来越多的机器人被运用于生产、服务、医疗等领域,给人们的工作和生活带来了很多便利。然而,机器人带来的风险也逐渐引起了人们的关注。本文将探讨...

百度知识图谱:打开人类知识的新大门

百度知识图谱:打开人类知识的新大门

  百度知识图谱是由百度公司开发的一种基于人工智能技术的知识表示和推理系统。它通过构建大规模的知识图谱,将海量的结构化和非结构化数据进行整合,并将这些知识与实体之间的关系进行...

image.png

使用 React-DnD 打造简易低代码平台

前言2016 年起,低代码概念开始在国内兴起,当年该行业总共有 10 起融资事件,之后低代码行业融资笔数整体呈上升趋势,并在 2020 年增长至 14 起,其中亿元以上融资有 13 起。从融资轮次分布...

人工智能技术缺陷:挑战与改进措施

人工智能技术缺陷:挑战与改进措施

  人工智能作为一种前沿技术,近年来取得了显著的发展和应用。然而,人工智能技术在应用过程中也存在着一些明显的缺陷。  首先,人工智能技术的一个主要缺陷是其对数据的依赖性。人工...

GPT-3.5 Turbo:下一代人工智能的未来

GPT-3.5 Turbo:下一代人工智能的未来

  人工智能(AI)的发展是许多科学家和工程师一直在关注和研究的话题。毫无疑问,AI已经在很多领域取得了巨大的进展,例如自然语言处理、语音识别、图像识别等领域。然而,随着技术...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。