Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
React Nativeを使ったリアルタイム配信サービスの開発 / React-Native-...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Junichi Sato
October 02, 2021
Programming
1.5k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React Nativeを使ったリアルタイム配信サービスの開発 / React-Native-Matsuri-2021-BAKOON-Development
https://reactnative-matsuri.com/ja
Junichi Sato
October 02, 2021
More Decks by Junichi Sato
See All by Junichi Sato
Rust製ベクトル検索エンジンQdrant / qdrant-rust-vector-search
sat0b
0
820
React NativeとFirebaseを使ったアプリ開発 / App Development using React Native and Firebase
sat0b
1
1.1k
React Nativeで新規事業開発に挑戦した話 / Challenging New Business Development with React Native
sat0b
0
970
Other Decks in Programming
See All in Programming
カツオ、ご期待ください
suneo3476
0
130
一人だけ、Kiroが静止する日
hideg
0
140
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
3.1k
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
110
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
420
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
290
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
570
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
5.6k
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
200
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
740
GitHubハンズオン講座 — 実務レベルのチーム開発のフローを身につけよう
junhat6
0
110
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
260
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Amusing Abliteration
ianozsvald
1
320
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Navigating Team Friction
lara
192
16k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
560
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
How to Ace a Technical Interview
jacobian
280
24k
Fireside Chat
paigeccino
43
4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Transcript
React Native を使った リアルタイム配信サービスの開発 Junichi Sato / @sat0b 1
自己紹介 名前: 佐藤純一 (Junichi Sato) 所属: SB イノベンチャー株式会社 ( ヤフー株式会社)
得意分野 検索システム、類似画像検索システム → 『Python とTensorFlow で学ぶ類似画像検索システム』 GitHub: @sat0b Twitter: @sat0b 2
本日の内容 オンラインフィットネスBAKOON の紹介 サービスの技術について React Native / Firebase / TensorFlow.js
/ Agora 0→1 の開発で学んだこと 1 年半やってきた中での知見 3
BAKOON について オンラインフィットネスアプリ 20 分間のエクササイズ インストラクターがアイドル モーションキャプチャ機能 公式ページ https://bakoon.app/ 公式Twitter
@bakoon_official 4
サービスの目的 目的 楽しく自宅でフィットネスができるように サービスの特徴 エンターテイメント みんなでやっている感じ アイドル 楽しく配信を盛り上げてくれる モチベーションを上げる 5
SB イノベンチャーとは? SB グループの新規事業制度 自転車シェアリングのHELLO CYCLING など 1 年程度の事業化検討を行う BAKOON
は事業化検討期間中のサービス サービス運営メンバーはヤフー株式会社所属 6
BAKOON 開発の取り組み 2019 年10 月 PJ スタート 2020 年3 月
審査通過 2020 年5 月 開発スタート 2020 年8 月 アプリ版開発開始 2021 年1 月 iOS アプリリリース 2021 年3 月 有料課金開始 2021 年5 月 HIIT トレーニング開始 7
BAKOON 運営メンバー メンバー ビジネス1 人 エンジニア3 人 兼務出向 週1.5~3 日程度
フルリモートで開発 8
エクササイズの流れ 9
ホーム画面 配信者、エクササイズ内容の種類や 運動量などが表示 配信直前にPush 通知 & 入室可能に LIVE 配信 /
録画配信 の2 種類 直近の2 週間のスケジュールが表示 10
エクササイズ風景 モーションキャプチャ リアクション送信(右下) スコア測定(左上) スタンプ(下) バーチャルステージ機能(左) リアクションと運動を可視化 11
動画 12
アクティビティ画面 過去のアクティビティ 参加回数 合計スコア 合計参加時間 参加履歴 13
技術について 14
BAKOON のシステム概要 15
React Native 採用の経緯 最初の2 ヶ月くらいはWeb アプリで作成 React で開発 & 仮説検証
モバイルアプリ化 Push 通知、アプリ内課金 React Native に決めた理由 React から移行するため 少ない人数でiOS/Android 対応するため 16
Firebase の活用 17
Firebase とは Firebase Google が提供しているモバイルプラットフォーム アプリなどのバックエンド機能を提供 → バックエンド処理を代行することで開発コストを削減 特徴 GCP
のプロダクトと相性が良い モバイルアプリ向け機能が充実 今回はFirestore とFunctions について解説 18
Firestore Firestore NoSQL ドキュメント指向データベース サーバーを介さずにアプリから直接アクセスを行う セキュリティルールの設定 リアルタイム処理・オフラインサポートなどが充実 BAKOON での活用例 ホーム画面のスケジュール
配信画面でのリアクションやスタンプの送信 19
Firestore 用語 ドキュメント データの単位 コレクション ドキュメントを格納 サブコレクション ドキュメントに紐づくコレクション コレクショングループ 同名のコレクションを指定したいとき利用
20
Firestore モデル 21
リアルタイムリスナー ドキュメントをリッスンして更新を検知 変更されたドキュメントを受け取ることができる 定期的にDB にアクセスして確認などせずに済む 22
ホーム画面での活用 Firestore からスケジュールを取得 コレクションをonSnapshot で リッスン 更新が自動的に反映される db.collection(`rooms`) .where(`end`, `>=`,
dateBegin) .where(`end`, `<`, dateEnd) .onSnapshot(async (snapshot) => { snapshot.docs.map( async (doc): Promise<Room> => { // ... return rooms; } ) }) 23
配信画面 楽しい キツイ の送受信に利用 コレクショングループを onSnapshot でリッスン db.collectionGroup(`reactions`) .where(`roomId`, `==`,
roomId) .onSnapshot((snapshot) => { // ... setReaction(reaction) }) 24
Cloud Functions Cloud Functions とは サーバーレスでバックエンドコードを実行 クライアント側に置きたくないロジックを置く Functions の種類 (
一部) Firestore トリガー PubSub トリガー 呼び出し可能関数 (onCall, onRequest) 25
CQRS によるFirestore 設計 読み込み用、書き込み用のコレクションを分離する 書き込み専用のコレクションにイベントを書き込む Firestore トリガー関数で読み込み用のドキュメントを作成 利点 セキュリティルールが簡単になる アプリ側ではデータを単に取得するだけ
リアルタイム性が重要なドキュメントは読み書き兼用とする 26
アクティビティ情報 Firestore トリガーで アクティビティ情報を更新 回数、ポイント、参加時間 アプリからは計算済み ドキュメントを取得 27
アクティビティ情報の更新 28
リアルタイム配信 29
配信システムの概要 30
Agora による配信 リアルタイム配信のプラットフォーム 大規模利用可能・低レイテンシー・低価格 利用している機能 リアルタイム配信 配信の録画機能 タイマー音の出力 react-native-agora 31
Agora 配信の流れ ユーザー Agora クライアントの初期化 チャンネルへの参加 リモートの動画を表示 配信者 Agora クライアントの初期化
チャンネルへの参加 自分自身のローカル動画を表示 32
トークンの発行 セキュアな配信のためにはサーバーでToken 発行を行う 33
サーバーでトークン発行 トークン発行用関数の定義 export const getAgoraToken = functions.region('asia-northeast1') .https.onCall((data: Request, context):
Response => { return generateToken(data.channelName, data.uid); }); 34
アプリからトークン取得 アプリからサーバー上の関数を呼び出す const getAgoraToken = firebase.app() .functions(`asia-northeast1`) .httpsCallable(`getAgoraToken`); トークンの取得 const
token = await getAgoraToken({ channelName: channelId, uid: uid }); 35
Agora クライアント クライアントの初期化 const rtcEngine = await RtcEngine.create(appId); await rtcEngine.enableVideo();
await rtcEngine.setChannelProfile(ChannelProfile.LiveBroadcasting); token を渡してチャンネルに参加 rtcEngine.joinChannel(token, channelId, null, agoraUid); 36
動画の再生 クライアント側実装 <RtcRemoteView.SurfaceView style={style.view} uid={hostId} channelId={channelId} renderMode={VideoRenderMode.Hidden} mirrorMode={VideoMirrorMode.Enabled} /> 配信者側実装
<RtcLocalView.SurfaceView style={style.fullView} channelId={channelId} renderMode={VideoRenderMode.Hidden} /> 37
録画配信 (HLS) Agora の機能で配信後の動画をS3 上に保存 Amazon S3, Alibaba Cloud, Qiniu
Cloud に対応 Firestore にURL を保存、react-native-video で再生 38
モーションキャプチャ 39
TensorFlow.js JavaScript からTensorFlow を扱うことができる WebGL を利用したGPU アクセラレーション React Native から利用可能
tfjs-react-native WebGL にexpo-gl を利用 40
PoseNet PoseNet とは ポーズの推定するために利用される 体の部位の位置とスコアを推定 BAKOON での利用 PoseNet で骨格の推定を行う リアクションの推定
運動量のスコア計算 41
モデル計算 リアクションの推定モデル PoseNet の推定値を入力 ポーズごとに画像とラベルの組みを取って学習 スコア計算 距離などを補正して運動量を算出 運動するほど大きなスコアになるように計算 42
リアクション推定とスコア計算 PoseNet の骨格データの推定 const { pose, posenetOutput } = await
model.estimatePose(images); リアクションの推定 const prediction = await reactionModel.predict(posenetOutput); 運動量のスコア計算 const score = calculateScore(posenetOutput) 43
0→1 の開発で学んだこと 44
進め方の反省 仮説で新機能を投入する 新機能を考える、開発するのは楽しいが・・・ 仕事が増える ユーザーからのフィードバックが足りない ユーザーの解像度が上がらない ニーズが分からない どこで困ってるか分からない 45
フィードバックを最大化する ユーザーのフィードバックを得る 使ってくれてる人がどういう人なのか解像度を高める 改善や新機能開発の方向性を決める フィードバックを得られやすい仕組みを入れる ユーザーインタビュー ユーザーサポート アプリのログ 46
フィードバックの効果 47
LINE の問い合わせ機能 目立つ問い合わせ ホーム画面からLINE で問い合わせ サポートによるフィードバック こちらから詳細に質問できる チャネルトーク(channel.io ) Flipper
を使うとクラッシュする とのことで利用断念 48
ユーザーの理解を深める 入会時のアンケート どこから来たのか? どれくらい運動欲求があるのか? 退会時のアンケート 何が問題だったのか? 配信後のアンケート 感想、よかった点、悪かった点 49
イベントの設定 Firebase Analytics イベントを設定 アプリを利用しててどこで離脱するか? Firebase Analytics Funnels 50
流入施策 アプリは作っておいておくだけでは広まらない オーガニック流入 SNS での発信 広告流入 Twitter 広告 (AppsFlyer のSDK
を利用) react-native-appsflyer Apple Search Ads 51
Twitter 連携機能 52
おわりに 53
React Native でよかったこと React 製のWeb アプリからの移行がスムーズ React Native 力が上がるとReact も扱えるようになった
PJ のコードをTypeScript で統一 高い柔軟性・型の表現力 TS は好きな言語の一つになった 豊富なサンプルコード JS, Node.js 54
まとめ BAKOON のサービスについて紹介 BAKOON の技術・システム Firebase (Firestore とFunctions) の活用 Agora
を利用したリアルタイム配信 TensorFlow.js を用いたモーションキャプチャ 開発を通して学んだこと ユーザーのフィードバックを得る方法 55