フラッターで雲にビデオを保存する



動機
ビデオコール、VoIP、コーデック、これらすべてのことは、それはとても複雑です!🤯 私は自分自身をコード化することはできません-私は、この分野は、初心者のための非常に挑戦することができます.
私が思ったよりずっと簡単であるとわかります!この記事では、クラウドサーバーにカメラからビデオを保存することができますUver単純なフラッターアプリを作成する方法を示します.

💡 This article describes how to use VoxImplant platform. You need to bear in mind that this is a paid service, so please check their pricelist before jumping in.



内容
  • How to prepare platform

  • Client
  • Preparations
  • Camera permissions and debugging
  • Client code
  • Conclusion
  • Links

  • プラットフォーム作成

    Before we get our fingers dirty, we need to prepare the platform. VoxImplant provides a user-friendly interface and rich API for their services, so let's cook the backend part of our app.

  • Create a new account on voximplant.com ダッシュボードにログインします.

  • 開いた左のメニュー

    あなたが望むように名前をつけてくださいrecorder ). 作成したアプリケーションをクリックしてその設定に移動します.

  • アプリケーションダッシュボードでユーザーに移動
    名前とパスワードを選択します.

    💡 I used "Separate account balance" checkbox, so this user would have separate balance from main account. You can call me paranoid, but it's never too much security!



  • 最後にコードを追加できます.シナリオに移動します.私は鉱山を訪れたvideo-recorder . このコードをエディタにコピーします
    //subscribe to the events
    VoxEngine.addEventListener(AppEvents.CallAlerting, (e) => {
      e.call.addEventListener(CallEvents.Connected, handleCallConnected);
      e.call.addEventListener(CallEvents.RecordStarted, handleRecordStarted);
      e.call.addEventListener(CallEvents.Failed, VoxEngine.terminate);
      e.call.addEventListener(CallEvents.Disconnected, VoxEngine.terminate);
      e.call.answer();
    });
    
    function handleCallConnected(e) {
      // Record call including video
      e.call.record({video:true});
    }
    
    function handleRecordStarted(e) {
      // Send video URL to client
      e.call.sendMessage(JSON.stringify({url: e.url}));
    }
    
    それは自己説明です、しかし、要するにConnected イベントは、クラウドに着信ビデオを記録します.録音が開始されるとRecordStarted イベントは、クライアントへのリンクとメッセージを送信します.単純さのために、我々はビデオプレーヤーをクライアントに加えません、したがって、このコードはちょうどそれをする方法を示すためにここにあります.
  • そして最後のこと!我々は、我々の呼び出しを取り扱うルータを加えなければなりません.ルーティングに移動します.私の場合、パターンはすべての着信を受け入れます、しかし、生産環境で、あなたはそれを意味がある何かに変えなければなりません.ボックスから我々のシナリオを選んでください.
  • そして、それはプラットホームでそれです.とても簡単!今、我々はクライアントの一部に切り替えることができます.

    クライアント
    準備

    💡 If you don't want to code client yourself - just clone it:
    git clone [email protected]:bunopus/video_recorder.git
    Don't forget to add your USERNAME and PASSWORD. Create .env file in root folder with following content and run an app.

      USER=USERNAME@YOUR_APP_URL
      PASSWORD=ACTUAL_PASSWORD
    
    Let's start preparing our client. I assume that you already have Flutter SDK up and running. If not - check their docs

  • プロジェクトの作成
    flutter create video_recorder
    

  • 追加flutter_voximplant パッケージ
    flutter pub add flutter_voximplant
    
  • 我々は、少なくとも私たちの超簡単なアプリのために、他のパッケージは必要ありません.あなたはそれがアップして実行していることを確認することができますflutter run .

    カメラのアクセスとデバッグ

    Before we continue I would like to say a couple of words about debugging apps that use camera. Even though it should be straightforward – it's not 🤦‍♀️. At least for Android.

    For VoxImplant plugin to work – add this into your project ( docs )

    IOS
    次のエントリを追加しますInfo.plist ファイルは<project root>/ios/Runner/Info.plist :
    <key>NSMicrophoneUsageDescription</key>
    <string>Microphone is required to make audio calls</string>
    <key>NSCameraUsageDescription</key>
    <string>Camera is required to make video calls</string>
    
    このエントリは、マイクとカメラにアクセスするアプリをすることができます.

    アンドロイド
    Java 8のサポートを追加する必要があります.
    オープン<project root>android/app/build.gradle ファイルを「Android」セクションに追加します.
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    
    しかし、それは十分でないthis article )!
    アンドロイド用android/app/src/(main|debug|profile)/AndroidManifest.xml 追加
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.handson">
      ...  
      <uses-permission android:name="android.permission.CAMERA" />
      <uses-permission android:name="android.permission.RECORD_AUDIO" />
    </manifest>
    
    次に、エミュレータを開き、アプリケーションへのアクセスを与える.

    💡 Best cross-platform solution for Flutter to handle permissions is permission_handler package. It removes neccesity to dance around your phone.


    あなたの実際のWebカメラを使用する場合は、Androidエミュレータが付属して広場をジャンプしない場合はhere
    でも🤦‍♀️ 私のケースでは、1つの問題があります:私はいくつかのカムを持って、私のコンピュータに接続し、エミュレータの設定で私は最初の1つを持っていた!

    うまくいけばそれはあなたのエミュレータを実行する場合に解決することができますthis command ( Macで)
    cd ~/Library/Android/sdk/emulator
    emulator @YOUR_DEVICE_NAME -camera-back webcam1
    

    💡 For some reason you can't use -camera-back webcam1 -camera-front webcam1 at the same time 🤷‍♀️


    カメラが動作しているかどうかを確認するには-あなたのエミュレータでカメラのアプリを開き、この$ h 1 t👁👄👁

    クライアントコード Finally we have done everything to start coding our client. Let's take a look at lib/main.dart . At the init phase we're creating a client for the platform calling Voximplant().getClient() .
    Then we login _client.login() using the username and password created previously. To simplify code I store them in a .env file (and use
    flutter_dotenv パッケージ).あなたのログインアプリケーションの場合は、ログイン画面を実装し、Authトークンを使用することができますexample )

    💡 Use [email protected] format to log in.


    class _MyHomePageState extends State<MyHomePage> {
      final VIClient _client = Voximplant().getClient();
      VICall? _call;
      AppState _state = AppState.initialising;
    
      @override
      initState() {
        super.initState();
        _login();
      }
    
      void _login() async {
        try {
          await _client.connect();
          await _client.login(dotenv.get('USER'), dotenv.get('PASSWORD'));
          setState(() {});
          _state = AppState.ready;
        } on Exception catch (e) {
          log(e.toString());
          setState(() {
            _state = AppState.error;
          });
        }
      }
    
    我々は“レコード”を押すと、我々のアプリは、プラットフォームへの呼び出しを開始_client.call() . あなたはVICallSettings codecやその他のパラメータを指定する構造.最初の引数として渡される空の文字列に注意してくださいcall : これはあなたの呼び出しのルート名です.あなたが覚えているならば.* 我々の中でpattern フィールドので、任意の名前を受け入れられます.生産のために、ここで意味のあるルートを加えて、それからプラットホームでそれをチェックすることができます.
      void _record() async {
        var _settings = VICallSettings();
        _settings.videoFlags = VIVideoFlags(sendVideo: true);
        _call = await _client.call("", settings: _settings);
        _call?.onCallConnected = _onCallConnected;
        _call?.onCallDisconnected = _onCallDisconneced;
        _call?.onMessageReceived = _onMessage;
      }
    
    _call?.onCallConnected 他のコールバックイベントを購読し、それに応じて我々のアプリのUIを変更するために使用されます.
    _onMessage 機能は、プラットフォームが私たちに送るビデオURLを記録します.その後、ユーザーの助けを借りてそれを見ることができますvideo_player パッケージ.
    void _onMessage(VICall call, String message) {
        log(message);
      }
    

    💡 There is a bug in flutter_voximplant package that makes messages unusable on Android. Fix is already merged into master, but not published to pub. Hopefully it will be fixed soon.


    我々が呼び出しを終える必要があるとき、我々はちょうど呼び出し方法です_call?.hangup()そして、我々がする必要がある最後のことは、我々がそれを必要としないとき、接続を終えることです.私は、内部でそれをしていますdispose メソッド.
    @override
    void dispose() {
      super.dispose();
      _logout();
    }
    
    Future<void> _logout() async {
      final state = await _client.getClientState();
      if (state != VIClientState.Disconnected) _client.disconnect();
    }
    

    💡 dispose method in Flutter widgets has couple of issues, for example not called when app quit or doesn't work as async. In a production environment you will need some workarounds to make sure that connection is closed properly.



    結論 Aaaand that's it 🎉! Our client is ready, and when we press the Record button (and then Stop), we can go to App -> Call history and see the happy face of a happy developer! 😃


    リンク
  • Voximplant flutter package
  • Typescript implementation of video recorder
  • Video recording tutorial
  • イラストはストーリーで作成- www.freepik.com