SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

近未来の技術トレンドを先取り! 「Tech-Sketch」出張所

WebRTC(PeerJS)で遠隔作業支援システムを作る(実装編2)

近未来の技術トレンドを先取り! 「Tech-Sketch」出張所 第16回(後編)

  • X ポスト
  • このエントリーをはてなブックマークに追加

 本連載ではTIS株式会社が提供している技術ブログ「Tech-Sketch」から「コレは!」というテーマをピックアップし、加筆修正して皆様にお届けしております。今回はPeerJSを用いた「ブラウザ上で動作する遠隔作業支援システム」の後半部分(スマートグラスと監視端末のブラウザ間をP2P接続し、映像や音声、データを双方向に交換する部分)を取り上げます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

実装編1では

 前回の実装編1では、作業準備の処理フローとしてPeerJSの初期化とMediaStreamの取得まで進めました。ここまでで、スマートグラスと監視端末はそれぞれユニークIDが採番されてシグナリングサーバと接続しており、自身のカメラやマイクへのアクセスも可能となっています。

2. 通常作業の処理フロー

 では次に通常作業時の処理フローとして、シグナリング処理からスマートグラスのカメラ映像をリアルタイムに監視端末へ表示する部分まで進めます。

2-1. 接続要求

 PeerJSを用いて他のPeerとP2P接続する場合、接続先PeerのユニークIDを指定しなければなりません。今回はシンプルに、スマートグラスの接続待ち画面(device画面②/下図左)に表示したユニークID(下図であればf9uyrhv2lzwljtt9)を、監視端末(monitor画面②/下図右)の入力フォームに転記する形で実装しました。

接続要求の送信画面
接続要求の送信画面

 監視端末の「CALL」ボタンをクリックすると、MonictorClassのmakeCallメソッドが呼び出され、シグナリング処理が開始されます。

monitor.coffee
$('#make-call').click ->
  calltoId = $('#callto-id').val()
  video = $('#device-video')
  mc.makeCall(calltoId, video, connecting, waiting) # 接続処理実施

2-2. MediaConnectionの確立

 MonitorClassのmakeCallメソッドでは、MediaConnectionの接続要求とDataConnectionの接続要求を一挙に実施します。

 まずはMediaConnectionの接続処理から追ってみましょう。

MediaConnection

 WebRTCのRTCPeerConnectionによって交換されるMediaStreamをラップしたオブジェクト。

MediaConnectionの確立
MediaConnectionの確立

※1 監視端末:MediaConnectionの接続要求を送信

 最初に@peer.call()を呼び出すことで、監視端末側からスマートグラスに向けてMediaConnectionの接続要求を出します(Offer送信)。この際、接続済みの監視端末のMediaStreamを引数に渡します。

 監視端末側ではこの段階でMediaConnectionオブジェクトが取得できますが、P2P接続が確立していないため、まだ利用できません。

remote-monitor.coffee
class MonitorClass extends BaseClass
  ...
  makeCall: (callto, video, connecting, waiting) ->
    ...
    # MediaConnectionの接続要求処理
    mediaConnection = @peer.call callto, @ls # calltoに向かってMediaConnectionの接続を要求(Offer送信)
    @connect mediaConnection, video, waiting # BaseClassから継承したメソッドconnect呼び出し
     
    # DataConnectionの接続要求処理
    ...
    # DataConnectionのイベント処理
    ...

 BaseClassに実装されたconnectメソッドには、MediaConnectionの接続が確立した際のイベントハンドラと接続が閉じられた場合のイベントハンドラが記述されています(後述)。

※2 スマートグラス:MediaConnectionの接続要求の受信イベント発生

 スマートグラスがシグナリングサーバに中継された接続要求を受信すると、@peer.on('call', callback)イベントが発生し、設定したcallback関数が呼び出されます。

 下記のように、接続要求受信時には、接続済みのスマートグラスのMediaStreamを引数に接続受託を返信(Answer送信)することになります。

remote-monitor.coffee
class DeviceClass extends BaseClass
  ...
  onCall: (video, connecting, waiting) ->
    console.log "onCall"
    # @peer.on('call', callback)イベント発生
    @peer.on 'call', (mediaConnection) =>
      # 監視端末からの接続要求を受信した際の処理
      console.log "peer.on 'call'"
      mediaConnection.answer @ls # 接続元(監視端末)へ接続受諾を返信(Answer送信)
      @connect mediaConnection, video, connecting, waiting # BaseClassから継承したメソッドconnect呼び出し

※3 監視端末・スマートグラス:MediaConnectionのイベント処理

 MediaConnectionに設定できるイベントハンドラにはいくつかありますが、重要なのは次の2つです。

  • MediaConnection.on('stream', callback)イベント : MediaConnectionの接続が確立し、接続相手先のMediaStreamが利用可能となった際に呼び出される。
  • MediaConnection.on('close', callback)イベント : 自分もしくは接続相手先が、MediaConnectionを切断した際に呼び出される(MediaConnectionの切断を検知するまでは数秒のタイムラグがある)。
remote-monitor.coffee
class BaseClass
  ...
  connect: (mediaConnection, video, connecting, waiting) ->
    ...
    # MediaConnectionのイベント処理
    mediaConnection.on 'stream', (stream) =>
      # 接続相手先のMediaStreamが利用可能となった際の処理
      console.log "mediaConnection.on 'stream'"
      video.prop 'src', URL.createObjectURL(stream) # 接続相手のMediaStreamをvideoタグのsrcに接続
      connecting() # 通常作業画面を表示
    mediaConnection.on 'close', =>
      # 自分もしくは接続相手先がMediaConnectionを切断した際の処理
      console.log "mediaConnection.on 'close'"
      @ls.getAudioTracks()[0].enabled = false # 自分自身のマイクをOFFにする
      @ems.close() if @ems? # 切断されたMediaConnectionはcloseしておく
      waiting() # 接続待ち画面を表示

 MediaConnection.on('stream', callback)イベントの発生時には、取得した接続相手のMediaStreamをvideoタグのsrcに接続し、通常作業画面を表示します。

 また、MediaConnection.on('close', callback)イベントの発生時には、自分自身のマイクをOFFにした後に切断されたMediaConnectionをcloseし、接続待ち画面へ戻ります。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
2-3. DataConnectionの確立

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
近未来の技術トレンドを先取り! 「Tech-Sketch」出張所連載記事一覧

もっと読む

この記事の著者

松井 暢之(TIS株式会社)(マツイ ノブユキ)

TIS株式会社 コーポレート本部 戦略技術センターに所属。アーキテクチャ設計やデータモデル策定、フレームワーク構築などバックエンド側のアーキテクトとしてプロジェクトに従事していたが、現部門への異動を契機に戦略技術の検証や新規サービスの事業企画に軸足を移す。近頃はなぜか、インフラ・運用のパターン化と自動化を目...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8018 2014/09/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング