8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Expo Application Services(EAS)とAgoraを使って動画版Clubhouseを作った

Last updated at Posted at 2021-08-18

#目次
1.作ったもの
[2.Expo Application Services](#2-Expo Application Services)
3.デモアプリを作ろう
4.補足
5.まとめ

#1. 作ったもの

動画配信SNS、Ocacatalkを作りました。

img.jpg

Clubhouseの動画版です。テキストチャットもできます。Clubhouse使ったことないので伝え聞く情報から完全に想像だけで作りました。よかったら遊んでみてください。iPhone/Android両対応です。

#2. Expo Application Services

Expo CLI

これまで私のアプリは全てExpo Managed Workflowで開発してきました。Expoとは簡単にいうとReact Nativeのアプリ開発を超便利にしてくれる開発ツールです。XcodeやAndroid Studioをまったく触らなくても開発からリリースまで出来てしまいます。私はSwift/Kotlinを書けませんしXcode/Android Studioをほぼ触ったことがありません。Expo Managed Workflowを使った開発の経験しかありません。

デバッグはもちろんiOS/Androidシミュレーターでもできますが、Expo Goアプリを利用して実機で簡単にできます。私は手持ちのMacBookAirよりも快適に使える自作パソコンで開発するのが好きなので、Windows上のVSCodeでコードを書く→iPhoneで実機デバッグするという形で開発していました。

OTAアップデートやホットリロードも完全に動作するため特に理由がなければExpoを使って開発するのがオススメです。

一方で、Expoには欠点もあります。それはReact Native CLIとは異なりネイティブコードを触ることができないということです。具体的にはBlutoothやWebRTC、InAppPurchaseなどネイティブコードを使う一部のライブラリには非対応です。ただ、GPSやカメラ、Mapなど大半の機能はExpoが純正ライブラリを提供しているためこれまでリリースしてきたアプリはExpoで開発できました。

EAS CLI

Expo Application ServicesはExpoの提供する次世代のビルドサービスです。Expoの便利な機能を使いながら上述のこれまで非対応だったネイティブコードを触るライブラリを利用することができます。

2021年後半の本リリースに向けて現在はプレビュー機能となっていますが、$29/moPriority Planを登録することで利用できるようになります。

Ocacatalk

というわけで、実際にPriority Planに登録してEAS buidを使ってリリースしたのが冒頭で紹介した新作アプリOcacatalkです。

Ocacatalkのビデオチャット機能はAgoraを利用しています。

Agoraは、自社開発のスマートフォン・PCアプリやWebサイトに、カスタマイズしたビデオ・音声通話やライブ配信をかんたんに実装できるSDKです。Clubhouseのバックエンドに使われていることでもおなじみのSaaSです。

React Native用のライブラリ(react-native-agora)はこれまでも提供されていましたが、AgoraのビデオチャットはWebRTCであり、Expoでは利用できませんでした。

OcacatalkはEAS buildを使い、これまでできなかったAgoraSDKを利用して開発しました。

#3. デモアプリを作ろう

EAS buildの開発方法

EAS buildはまだプレビュー段階のためあまり情報がありません。Expo Managed Workflowでの開発に慣れていれば問題ないと思います。

しかし、いくつか違いがあるので実際にAgoraを使ってビデオチャットを行うデモアプリを作る方法を書きます。

デモアプリのリポジトリです。

出来上がるもの

左がiPhone12、右がiPhone6sでとったスクリーンショットです。2つのデバイスでビデオチャットをしている様子です。

img2.jpg

AgoraIDの準備

本題からはずれるので詳細は省きますが、とりあえずAgoraにサインアップしてプロジェクトを作成します。10,000 FREE mins per monthの無料枠があり、クレジットカード情報の登録も必須じゃないので安心です。

プロジェクトを作成してAppIDを取得します。デモアプリなのでApp certificateはDisableにしておきます。

img3.png

開発環境

ネイティブコードを利用する場合Expo Goアプリでデバッグできないので、iOSかAndroidのシミュレーターを使います。自作パソコンにAndroid Studioを入れたくないのでMacBookAirを使います。

  • Mac Book Air 2020 (Intel, macOS 11.5.2)
  • expo-cli v4.9.1
  • eas-sli v0.23.0

react-native-cliは入っていません。

img4.png

Expoプロジェクトの準備

expo initで新規で作ってもいいのですが、せっかくなのでアプリっぽくするために前に作った自分用のボイラープレートを使います。

img5.jpg

  • ボトムタブ、スタックナビゲーション
  • Firebase authを使ったメールアドレス/PWでのサインアップ/ログイン
  • Firestoreを使ったユーザープロフィールの編集
  • Firebase Cloud Storageを使ったアバター画像のアップロード
  • expo notifications tokenの取得とFirestoreへの保存
  • デバイス設定に合わせたダークモードの動的切り替え

を実装した便利なボイラープレートです。

これをクローンしてきて依存関係をインストールします。

yarn install

とりあえず、Managed Workflowのまま動作確認します。

expo start

img6.jpg

無事に動きました。画像を載せる用にシミュレーターを使ってますがこの時点では実デバイスのExpo Goアプリでも動作します。

app.jsonの編集

デモアプリに名前をつけます。

"expo": {
  "name": "agora-eas-demo",
  "slug": "agora-eas-demo",
"ios": {
  "supportsTablet": true,
  "bundleIdentifier": "net.votepurchase.agoraeasdemo",
  "buildNumber": "1.0.0",
  "infoPlist": {
    "NSPhotoLibraryUsageDescription": "Use the photo library to change your avatar.",
    "NSCameraUsageDescription": "Use for video call.",
    "NSMicrophoneUsageDescription": "Use for video call."
  },
  "userInterfaceStyle": "automatic"
},

bundleIdentifierを設定します。ビデオチャットにカメラとマイクを使うのでNSCameraUsageDescriptionNSMicrophoneUsageDescriptionも追加します。

"android": {
  "package": "net.votepurchase.agoraeasdemo",

Androidのパッケージ名も設定します。

EAS buildの準備

EASにログインします。Expoのユーザー名とパスワードです。

eas login

EASの初期化を行います。

eas build:configure

途中で色々聞かれますが全てyesを選択しました。

新しくeas.jsonが作成されます。

{
  "build": {
    "release": {},
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    }
  }
}

デフォルトのままにしておきます。

動作確認

EASを使って動かしてみます。まだAgoraはインストールしていません。

iOSのシミュレーターを開いたまま以下のコマンドを打ちます。

expo run:ios

ルートディレクトリにiosフォルダが作成され、必要なファイルが作成されます。数分かかります。

しばらく待っているとビルドされたアプリが起動します。

img7.jpg

この時点では先ほどExpo Goで動かしたものと変わりありませんが、ホーム画面にはExpo Goアプリではなく今ビルドしたアプリがインストールされています。

img8.jpg

今回のデモアプリではログイン後にビデオチャットの画面を置きたいのでアプリにログインしておきます。

img9.jpg

Agora SDKのインストール

Agoraのライブラリをインストールします。

yarn add react-native-agora
cd ios
pod install

UIはAgoraが用意してくれているものをそのまま利用します(ReactNative-UIKit)

ルートディレクトリに戻ってからインストールします。

cd ..
yarn add agora-rn-uikit

以上でインストールは完了です。

ページ遷移を作成

ホーム画面→チャット開始前→チャット開始後、という風に遷移したいので、チャット画面用のコンポーネントを作ります。

img11.jpg

src/scenes/stream/Stream.js

import React, { useEffect, useState } from 'react'
import { Text, View, ScrollView, StatusBar, useColorScheme, Button } from 'react-native'
import styles from './styles'
import { firebase } from '../../firebase/config'
import AgoraUIKit from 'agora-rn-uikit'

export default function Stream(props) {
  const userData = props.extraData
  const scheme = useColorScheme()
  const [videoCall, setVideoCall] = useState(false);
  const rtcProps = {
    appId: '<Agora App ID>',
    channel: 'easdemo',
  };
  const callbacks = {
    EndCall: () => setVideoCall(false),
  };

  return (
    <View style={styles.container}>
      <StatusBar barStyle="light-content" />
      <View style={{ flex: 1, width: '100%' }}>
        {
          videoCall ?
            <AgoraUIKit rtcProps={rtcProps} callbacks={callbacks} />
            :
            <Button title={'Start Call'} onPress={()=>setVideoCall(true)} />
        }
      </View>
    </View>
  )
}

<Agora App ID>には最初のほうで作成したAgoraのAppIDが入ります。

作ったコンポーネントをルーティングに追加します。

src/routes/navigation/stacks/Stacks.js

import Stream from '../../../scenes/stream'
<Stack.Navigator headerMode="screen" screenOptions={navigationProps}>
  <Stack.Screen name="Home">
    {props => <Home {...props} extraData={user} />}
  </Stack.Screen>
  <Stack.Screen name="Stream">
    {props => <Stream {...props} extraData={user} />}
  </Stack.Screen>
</Stack.Navigator>

Home画面からチャット画面(Stream)に遷移できるようにします。

src/scenes/home/Home.js

import { useNavigation } from '@react-navigation/native'
const navigation = useNavigation()
<Button title={'Go Stream'} onPress={() => {
  navigation.navigate('Stream')
}} />

コードの変更はここまでです。

動作確認

実際に動かしてみます。

expo run:ios

画面遷移などはできますが、ビデオチャットが開始できません。シミュレーターではカメラとマイクが使えないのでこうなります。

img12.jpg

動作確認用に実デバイスにインストール

ビデオチャットの動作確認をしたいのでXcodeを使って実デバイス用にビルドします。

ルートディレクトリの中のiosフォルダをXcodeで開きます。Open a project or fileから先ほど作成されたiosフォルダを選択します。

img13.jpg

実機にインストールするためには署名をしないといけません。Signing & Capabilitiesタブを開いてTeamを選択します。Appleのデベロッパーアカウントが必要です。

img14.jpg

iPhoneをUSBケーブルでMacと接続します。インストール先を今接続したiPhoneにします。

img15.jpg

左上のビルド開始ボタンをクリックするとビルドとインストールが開始されます。

img16.jpg

しばらく待ってるとインストールが完了します。物理iPhoneのスクリーンショットです。

img17.jpg

実デバイスで動作確認

ビデオチャットの確認をしたいのでiPhone2台にインストールしました。それぞれのiPhoneでインストールしたデモアプリを起動すると無事にビデオチャットが開始されました。

img2.jpg

リリースビルド

リリースするわけではないですが確認のため実際にリリースビルドしてみました。

eas build --platform ios

無事にビルドできました。あとは通常のExpoアプリと同じようにTransporterアプリを使ってAppStoreに提出します。

img18.png

#4. 補足

バージョン番号

バージョン番号のインクリメントは手動です。

Managed Workflowではストアに新バイナリを提出するときにapp.jsonexpo.ios.buildNumberexpo.android.versionCodeをインクリメントしますが、EAS buildでは手動でそれぞれ更新しないといけません。

iOSならios/agoraeasdemo/Info.plistCFBundleVersionを手動でインクリメントします。

Androidはandroid/app/build.gradleandroid.defaultConfig.versionCodeです。

Androidでのビルド

ここまでXcodeを使ったiOS用のビルドについてだけ書いてきました。Androidについては書いていません。

img19.jpg

なぜならAndroid Studioのエミュレーターでどうしても動かせなかったからです。ただし、

eas build --platform android

でのリモートビルドは普通にできてしまったのでAndroidでの動作確認をしないままGoogle Playに提出してそのままリリースしました。

OTAアップデート

Testflight中でもリリース後でもexpo publishでのOTAアップデートはできました。ただし、通常のExpoアプリと同様にapp.jsonの変更やネイティブコードを触るライブラリを追加した場合はOTAアップデートできません。ストア経由でのアップデートが必要です。

AgoraとAppStoreレビュー

AgoraIOを利用したアプリではAppStoreのレビューに難があります。

レビュアーはVPNを通してレビューしているようですが、AgoraはVPN経由だとビデオチャットが開始できません。そのため「ビデオチャットが開始できない」という理由で何度もリジェクトされてしまいました。

最終的にはレビュアーへのメモに

I run the app on my real device using Testflight, the permission request is displayed without any problem and I can allow it to use the camera / microphone.

**Please allow the app to access the camera and microphone. If you do not allow it, you will not be able to video chat.**
**Use a real device. Cameras and microphones are not available in the simulator.**

I have captured it working on my device.
https://youtu.be/Dh5h1-Kk1eU

If you are using a VPN, turn it off.

>The AppStore review team is testing via VPN, so that's probably the problem, but I don't know much about networks, so I don't know what the solution is.
https://github.com/AgoraIO-Community/react-native-agora/issues/357

という風に

  • VPNを使わないで欲しいこと
  • 実デバイスを使って欲しいこと
  • 自分のデバイスでは動作すること
  • YouTubeにアップロードしたデモビデオのリンク

を書いたところレビューを通過しました。

#5. まとめ

EAS buildを利用することでExpo Managed Flowでこれまで作れなかったアプリが作れるようになりました。

Expo GoアプリでのデバッグができないためMacが必須ではありますが、Managed Workflowでの快適な開発体験をほとんど損なうことなくネイティブコードを触るライブラリを使えます。

Expoにはお世話になっているのでしばらく課金は続けようと思います。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?