2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
川上健太郎氏:今まで紹介したとおり、けっこう便利なんですが、当然足りない機能やできないこともあります。実際にプロダクトに導入するにあたって、足りなさそうな機能やできないことをリストアップしてみました。
まず画質設定です。これは単純に実装されていないので、ビットレートを設定できないです。iOSで言うと、AVPlayerItemのpreferredPeakBitRateにあたります。また字幕、副音声ですね。先ほど説明した字幕はローカルから読み込むんですが、ストリームから受け取って表示する機能はないので、これも実装する必要があります。
試しに初めてAndroidをやってみました。iOSはわりとサクッとできるんですが、AndroidはiOSに比べるとちょっとコード量を書かないといけません。自分でプラグインを開発するのはけっこう大変そうだという印象を受けました。副音声も同様で、自分で実装が必要です。
これは当然と言えば当然なんですが、UIも自分で実装する必要があります。プレーヤーを実装するうえでは、それほど凝ったUIはないと思うんですが、AVPlayer、ExoPlayerのデフォルトのUIは使えないので、自分でウィジェットをレイアウトする必要があります。
次は、DRM(Digital Rights Management)です。イシューを見てもらうとわかるんですが、video_playerはPlatform ViewじゃなくてTexture Widgetを使っているので、DRMは使えないと思います。
次はCookieで、iOSの話です。AVURLAsset時にCookieを渡したい場合が要件としてあったりするんですが、その場合、通常ではpotions: [AVURLAssetHTTPCookiesKey]をオプションに設定するとCookieが設定できます。
Flutterもこれができるのかなと思ったら、そうではありませんでした。けっこう議論を生んでいるようで、イシューがよく出てクローズしています。PR(Pull Request)もバラバラと出ているんですが、出して満足する人がいたり、レビューが放置されたりで、いまだにマージされていません。
React Nativeのvideo_player版もあって、そこでも同じような議論がありました。React Nativeはマージすることを決めたみたいで、同じような機能が2020年にマージされています。
最後にエラーハンドリングです。括弧を付けているんですが、できなくもないけど、ちょっとどうなのかなといった意味合いです。まずVideoPlayerControllerをメチャクチャ大雑把に説明すると、ValueNotifierになっていて、VideoPlayerValueになっています。
VideoPlayerValueはプレーヤーの状態を管理しているオブジェクトで、errorDescriptionというプロパティが生えています。ErrorTypeやErrorCodeなど、よくある列挙型は特に定義されていません。
どんな感じになっているのか、実際に投げられている各プラットフォーム側のコードをいくつか抜粋しました。上はiOSで、FlutterErrorというオブジェクトを生成して、errorWithCodeとmessage details。Androidも似たような感じなんですが、errorDescriptionというプロパティに入るのがmessageの中のもので、iOSだったらVideo cannot be fast-forwarded beyond 2.0x、AndroidだったらVideo player had errorとなっています。Descriptionなのでどうなんだろうという感じです。
さらに各プラットフォームで、プレーヤーからエラーを受け取っている部分を見ていきたいと思います。まずiOSの部分です。これはObjective-Cなんですが、AVPlayerItem.statusをオブザーブしているさらにその中を抜粋しました。
StatusがFailedになったときに単純にエラーを投げています。エラーを見るとしたら、NotificationCenterのAVPlayerItemNewlogEntryなどを見ると思うんですが、そのあたりは特になにもしていません。
続いて、Androidです。AndoroidもExoPlayのonPlayerErrorが来たときに投げているだけで、メッセージもAndroidではVideo player had errorで、iOSではFailedToLoadVideoなのでちょっと違います。
まとめです。できないわけではなく、無理矢理やろうと思えばできると思うんですが、エラーハンドリングに適したかたちにはなっていないという印象です。
ただエラー以外に、stateの状態にisBufferingやBufferの範囲を示すBufferedプロパティなどがあるので、これを見れば十分な場合もあるのかなと思っています。けっこう細かくハンドリングしたければ、自分でやるしかないと思います。
次に実装を軽く追ってみたいと思います。基本的な仕組みは、BasicMessageChannelとEventChannelの組み合わせです。BasicMessageChannelは、プラットフォームとDart間で双方向にメッセージを送受信するためのAPIです。EventChannelはプラットフォームからDart側にイベントを通知するためのAPIです。
video_playerはFlutterプラグインで、確か唯一BasicMessageChannelを使っているプラグインです。よく似たプラグインとして、カメラプラグインみたいなものが取り上げられるんですが、カメラプラグインはMethodChannelしか使っていなかったはずです。
EventChannelがどんなふうに使われているかというと、プラットフォームのそれぞれのAVPlayerとExoPlayerで発生したイベントを、video_player_interfaceに通知して、video_playerはStreamでオブザーブします。
ちょっと説明を忘れたんですが、Flutterパッケージのほとんどは本体とホニャララプラットフォームインターフェイスに分かれていて、ホニャララプラットフォームインターフェイスが橋渡し的な役割を担っています。
実際にMessageChannelでやりとりしているのは、ホニャララプラットフォームインターフェイスで、video_playerにそれをインジェクトして、DI(Dependency Injection)して叩くっていう感じです。
実際のEventChannelの内容はこれしかなくて、初期化したよとか、再生完了したよとか、bufferingとか命名どおりです。
次は、BasicMessageChannelの例です。video_player側が、現在の再生位置を欲しいとインターフェイス側に投げます。そうするとインターフェイスがプラットフォーム側に「現在の再生位置をくれ」とメッセージを送ります。するとプラットフォーム側が、プラットフォーム内で処理してreplayを返すので、それをFutureで返します。
実際の関数内がどんな感じなのか、実際のコードを見ていきます。あとで説明するんですが、これは自動生成されたものなのでけっこうゴチャっとしています。
1行目に出てきているTextureMessageの中身を軽く説明します。これが実際にやりとりする内容が入っているプロパティで、textureIdが受け渡ししたいものです。encodeとdecodeはそのまま、encodeとdecodeするためのもので、どのmessageにも絶対入っています。
まずChannelを生成します。このChannelはAPIごとに作成されて、だいたい末尾のドットポジションが、.create.initialize.disposeなどに変わります。それを送って、thinkawaitで待ちます。
エラーハンドリングをして、ここでエラーが入ってきたらエラーを投げて、返したいものにdecodeをして返します。
(次回へつづく)
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略