![見出し画像](https://assets.st-note.com/production/uploads/images/141310662/rectangle_large_type_2_3caac73677d869c6c6320d88871a6c1a.png?width=800)
OpenAI APIにiOSから動画を投げる実装のメモ #GPT-4o
これとか、
iOSからAPI叩いてGPT-4oに動画の要約させる実装もできた。コード整理して公開する予定です。 pic.twitter.com/djy0qI4I0q
— 堤修一 / Shuichi Tsutsumi (@shu223) May 17, 2024
これの実装をやった際のメモ。
iOSからAPIでGPT-4oにリアルタイム動画理解させるデモ、短くしたバージョン pic.twitter.com/znRhtv4cJf
— 堤修一 / Shuichi Tsutsumi (@shu223) May 20, 2024
送信するフレーム数・画像サイズ
画像をData型にする際に、当初は
guard let imageData = cgImage.dataProvider?.data as? Data else { fatalError() }
という実装にしていた。
この場合、1920x1080であれば1フレームあたり 8294400 bytes = 8.29 MB(※画像の内容により変動はする)。
"invalid_request_error" エラー
上述のデータサイズだと、3フレームも送れば20 MB制限に引っかかってエラーになる。
APIErrorResponse(error: OpenAI.APIError(message: "You uploaded an unsupported image. Please make sure your image is below 20 MB in size and is of one the following formats: [\'png\', \'jpeg\', \'gif\', \'webp\'].", type: "invalid_request_error", param: nil, code: Optional("invalid_image_format")))
そもそも送信にも時間がかかってレスポンスも遅くなる。
JPEGエンコード
ので、以下のようにJPEGエンコードしてから送信するようにした:
guard let imageData = UIImage(cgImage: cgImage).jpegData(compressionQuality: 0.8) else { fatalError() }
こうすると1920x1080で1フレームあたり 52868 bytes = 0.53 MB。
100分の1になった。
そもそも最初の実装にしていた理由は、UIImageを使いたくない(UIKitに依存したくない)からだった。
compressionQualityは0.5、あるいは0.3ぐらいでも全然OKで、もっと圧縮できるのだが、ネットが速い家で試しているし、エンコード品質を下げることによるデータサイズ圧縮は送信時間には影響するもののOpenAI側のレスポンス速度の短縮にはつながってない感じがしたので、デモでは0.5にしている。
画像のリサイズ・クロップ
GPT-4oの紹介ページのLacture summarizationデモでは45分の動画を要約している。
が、手元で60秒の動画から1秒ごとに60フレーム送信しようとするとタイムアウトになってしまった。
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
まぁ普通は60枚の画像をAPIで送ったりはしない。
OpenAIとしてはどれぐらいの間隔でフレーム抽出して、どれぐらいにリサイズしてるのかなと調べた記事がこちら:
リサイズ・クロップはCore Imageで行っている:
func transformed(by matrix: CGAffineTransform) -> CIImage
func cropped(to rect: CGRect) -> CIImage
画像理解の忠実度 / detail パラメータ
最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/