2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
川上健太郎氏:今まで紹介したとおり、けっこう便利なんですが、当然足りない機能やできないこともあります。実際にプロダクトに導入するにあたって、足りなさそうな機能やできないことをリストアップしてみました。
まず画質設定です。これは単純に実装されていないので、ビットレートを設定できないです。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.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.04
いつも遅刻や自慢話…自分勝手な人にイラっとした時の切り返し 不平等な関係を打開する「相手の期待」を裏切る技
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.03
職場の同僚にイライラ…ストレスを最小限に抑える方法 臨床心理士が語る、「いい人でいなきゃ」と自分を追い込むタイプへの処方箋
2024.12.05
「今日こそやろう」と決めたのに…自己嫌悪でイライラする日々を変えるには
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み