It’s now or never

IT系の技術ブログです。気になったこと、勉強したことを備忘録的にまとめて行きます。

【WebRTC学習】① ブラウザから動画/音声を取得する

概要

WebRTCについて調べることがあり、面白そうだなぁと思ったので勉強することにしました。

段階的に少しずつ理解を深めていきたいと思います。

この記事の目標

  • ブラウザからPCのカメラとマイクを起動して、htmlの <video> タグに表示する

WebRTCとは(超ざっくり)

WebRTC(Web Real-Time Communication)は、Web上でリアルタイム通信をするためのプロジェクトのこと。

様々なプロトコルを組み合わせた集合で、簡単にリアルタイム通信ができるようにAPIが提供されている。

僕が安易な言葉で説明するより、MDN株式会社時雨堂さんの記事を見るのが正確です。(とくに時雨堂さんの記事は日本語ですしめちゃくちゃ詳しいです。神。)

PCから動画音声を取得する

WebRTCのAPIは大きく分けて次の3つに分類されます。

  • MediaStream: 音声や動画をストリームで取得するためのAPI
  • RTCPeerConnection: 他デバイスとの通信を行うためのAPI
  • RTCDataChannel: 音声や動画以外のデータを扱うためのAPI

今回はこのMediaStreamのAPIを使って、ブラウザ経由でPCのカメラとマイクを起動し、HTMLの <video> タグにストリームを接続して動画を再生します。

実行環境

用意するコード

HTML

  • index.js
<!doctype html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>WebRTC Study</title>
</head>

<body>
    <div>
        <!-- 1. カメラとマイクから取得した動画と音声を流すためのvideoタグ -->
        <video id="local-video" autoplay style="width: 160px; height: 120px; border: 1px solid black;"></video>
    </div>

    <!-- 2. videoタグの再生を始めるためのボタン(jsで制御) -->
    <button id="btn-show-video">show video</button>

    <!-- 3. JSファイルの読み込み -->
    <script type='text/javascript' src='./index.js'></script>
</body>

</html>

まずは、動画と音声を再生するためのVideoタグを用意します。

Javascritp

  • index.ts
/**
 * 3. UserMediaからストリームを取得する(Video&Audio)
 */
async function setupUserMedia(): Promise<MediaStream | undefined> {
  try {
    // NOTE: Streamから取得できる情報を設定で指定できます(今回は動画と音声)
    const mediaConfig = { video: true, audio: true }
    const stream = await navigator.mediaDevices.getUserMedia(mediaConfig)
    // NOTE: videoTracksから端末がどのデバイスと接続しているかの情報が取得できます
    const videoTracks = stream.getVideoTracks()
    console.log(`Using video device: ${videoTracks[0].label}`)
    return stream
  } catch (err) {
    console.log('[error: setupUserMedia] ', err)
  }
}

/**
 * 4. videoタグにStreamを流し表示する
 * @param stream MediaStream
 */
function showVideo(stream: MediaStream) {
  const video = document.getElementById('local-video') as HTMLVideoElement
  // NOTE: videoElementのsrcObjectにstreamを接続すると動画が再生できるようになる
  video.srcObject = stream
}

/**
 * 2. ストリームを取得して、Videoタグを再生する
 */
async function handleShowVideo() {
  // start video capture
  const stream = await setupUserMedia()
  if (stream) {
    showVideo(stream)
  }
}

/**
 * 1.ボタンが押された時のハンドラー
 */
const btnShowVideo = document.getElementById('btn-show-video')
if (btnShowVideo) {
  btnShowVideo.addEventListener(
    'click',
    async function(e) {
      handleShowVideo()
      e.preventDefault()
    },
    false
  )
}

TypeScriptの処理は、以上で const stream = await navigator.mediaDevices.getUserMedia(mediaConfig) がWebRTCのMediaStreamを取得する処理です。

取得した、MediaStreamは、videoタグのsrcObject にセットすることで接続できます。

動作確認

f:id:inon29:20200128180435p:plain - show videoボタンを押下することでカメラからの動画とマイクの音声が再生されます

実装コード

ここに置いてあります。

参考記事