投稿日
TISアメリカ - API World 2019ハッカソン参加レポートNo.1 - RingCentral チャレンジ
はじめに
アメリカのシリコンバレーに拠点を置くTIS Ventures, Inc.(以降TVI)の井上です。
自炊でカレーばかり作るので、あだ名がカレーになりました。 フロントエンドが好きなソフトウェアエンジニアです。
TVIでは、新規事業創出を目的とし、シリコンバレー界隈の技術トレンドのキャッチアップ、スタートアップ企業のテックハントなどを行っております。
この度、10月にサンノゼで行われたカンファレンス「API World」のハッカソンに参加しました。本記事は、その参加レポートです。
※TVIはDev.toでブログを公開しています。本記事の英語版もありますので、興味のある方は是非、以下をご覧ください!
API World Hackathon Report No.1 – How to record a web-camera video in React – DEV Community 👩💻👨💻
API Worldとは
公式ページURL: https://apiworld.co/
API Worldは、世界最大のAPIに関するカンファレンスです。セッション、企業ブースの他にも、ハッカソンが開催されます。ハッカソンは総勢100人以上が参加し、2日間にわたって開催される大規模なものです。
チームとハッカソンの結果
ハッカソンは、最初にチームメンバーを探さないといけないのですが、 私は運良く、フロントエンドエンジニアとバックエンドエンジニア、アイディアマンが揃っている、バランスの良いチームに入れてもらえました。
- チームメンバーとの集合写真
私たちが作ったプロジェクトは、興味深いコミュニケーション・アプリケーションとしてRing Centralチャレンジの最優秀賞に選ばれ、さらに全チームのトップ5に選出されました。
以下の動画はトップ5に選ばれて登壇した時の様子です。(ムービーは載せられないので8倍速にしてgif化してます) デモの担当だったのですが、スピーカーが話しすぎたために出番はカットとなりました・・・ かわりに、微動だにしない私のスタンディング技術にご注目ください!(右から3番目が私です)
何を作ったか
CMを見ているユーザーが、CMに興味があるかどうかを判定するソリューションです。 クライアント側、バックエンド側をチームで手分けして作りました。 以下デモページ(CM動画一覧)です。
クライアント側:
CM再生開始・視聴者の表情撮影- 視聴者がCMサムネイル画像をクリックすると、モーダルウィンドウが表示され、CMが再生されます。それと同時に、Webカメラによる録画が開始され、CMを見ているユーザーの表情がウェブカメラで撮影されます。撮影した動画はAmazon S3に送られます。
バックエンド側:
動画解析・蓄積- Amazon S3に送られた動画は、Amazon Rekognitionで動画中の視聴者の表情を解析します。解析結果は蓄積され、APIで公開されます。
使っている技術スタックは以下の通りです。
- React (https://reactjs.org/)
- WebRTC (https://webrtc.org/)
- Amazon S3 (https://aws.amazon.com/s3/)
- Amazon Rekognition (https://aws.amazon.com/rekognition/)
私は以下のフロントエンドの実施を担当しました。
- デモページ(CM動画一覧)
- Webカメラ録画機能
詳細については、DevPostの以下のページをご覧ください。
Reactでウェブカメラ動画を撮影する方法
RecordRTCを使えば簡単に実装できます。簡単な例を以下に示します。
import React from 'react';
import RecordRTC from 'recordrtc';
class CameraRecorder extends React.Component {
constructor(props) {
super(props);
this.state = { recordVideo: null };
this.requestUserMedia = this.requestUserMedia.bind(this);
this.startRecord = this.startRecord.bind(this);
this.stopRecord = this.stopRecord.bind(this);
this.getUserMedia = this.getUserMedia.bind(this);
}
requestUserMedia() {
this.getUserMedia(stream => {
this.setState({ src: window.URL.createObjectURL(stream) });
});
}
startRecord() {
this.getUserMedia(stream => {
this.state.recordVideo = RecordRTC(stream, { type: 'video' });
this.state.recordVideo.startRecording();
});
}
stopRecord() {
this.state.recordVideo.stopRecording(() => {
this.state.recordVideo.save();
});
}
getUserMedia(callback) {
navigator.getUserMedia({ audio: false, video: true }, callback, error => alert(JSON.stringify(error)));
}
render() {
return (
<div>
<button onClick={this.startRecord}>Start Record</button>
<button onClick={this.stopRecord}>Stop Record</button>
</div>
)
}
}
export default CameraRecorder;
おわりに
日米を通じて人生初のハッカソンでしたが、チームメンバーに恵まれたおかげでTOP5に選出されました。
はじめて会う人とチームを組んで開発を進める中で、アイディアを形にする喜びを実感できたのは貴重な体験です。
また英語がカタコトでもボディランゲージとソースコードを介したコミュニケーションでなんとか乗り切れることもわかりました。
今後もハッカソンには継続的に参加していく予定です。
いろんなエンジニアの方々と交流を楽しみながら、実績を残していければと考えています。
本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。