Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize videos and gif images #4091

Open
acid-chicken opened this issue Feb 2, 2019 · 42 comments
Open

Optimize videos and gif images #4091

acid-chicken opened this issue Feb 2, 2019 · 42 comments
Labels
💬Discussion Being discussed or needs discussion 🔥high priority packages/backend Server side specific issue/PR

Comments

@acid-chicken
Copy link
Member

acid-chicken commented Feb 2, 2019

Summary

FFmpegが依存関係に導入されたので、ついでにGIF画像や動画ファイルを表示用に最適化された動画ファイル(要議論)に変換して通信量の削減を図りたい。


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@acid-chicken acid-chicken added 💬Discussion Being discussed or needs discussion packages/backend Server side specific issue/PR Drive labels Feb 2, 2019
@mei23
Copy link
Contributor

mei23 commented Feb 2, 2019

  • ドライブという機能を提供している以上、アップロードしたファイルをあまり改変したくないところがあります。
  • また、動画は最初は自動再生はされずにサムネイルが表示されるだけなので、それほど影響ないのではと思います。
  • アニメーションgif=>mp4などの、形式変換を行ってしまうとその形式の画像が上げられなくなります
    (てゆうか、これMastodonにある大嫌いな機能)
  • 負荷

なので、ユーザーが上げたものは極力変換したくないです。

@acid-chicken
Copy link
Member Author

それもそうですね。「ファイルの最適化」というドライブの機能の一つとして実装するのはどうでしょう。

@syuilo
Copy link
Member

syuilo commented Feb 2, 2019

ふーむ それはあまり需要がなさそう

@acid-chicken
Copy link
Member Author

misskey.xyzなどの高容量を許容するインスタンスではあまり需要はないかもしれないが、そうでないインスタンスなどでは需要が発生しそう。

@mei23
Copy link
Contributor

mei23 commented Feb 2, 2019

アニメーションGIF/PNGなんかはstatic版を用意して使うなどしたほうがよさそう #2996 #2175

@AyaMorisawa AyaMorisawa changed the title Optimize videos and gifs Optimize videos and gif images Feb 4, 2019
@syuilo
Copy link
Member

syuilo commented Feb 4, 2019

Related to #3969

@tamaina
Copy link
Contributor

tamaina commented Feb 5, 2019

Related to #2098

@ibrokemypie
Copy link

ibrokemypie commented Feb 5, 2019

It would definitely help to reduce traffic if misskey would convert/compress files uploaded. Perhaps this could be an instance wide configuration option so it can be disabled if traffic isnt a problem?

edit:
or, misskey could keep the originals and produce compressed versions in addition, allowing users to decide whether compressed, faster loading files, are acceptable to them or not

@acid-chicken
Copy link
Member Author

これやっぱり iOS ユーザーが画面録画を MOV で投稿して閲覧不可とかあるのでやりたい。

@acid-chicken
Copy link
Member Author

あと WebM でこれの逆が発生する。

@SanMurakami
Copy link
Contributor

今更ですが

misskey.xyzなどの高容量を許容するインスタンスではあまり需要はないかもしれないが、そうでないインスタンスなどでは需要が発生しそう。

のようなインスタンスはFFmpegで動画等を変換するスペックもないのでは

@acid-chicken
Copy link
Member Author

ストレージとマシンスペックは別なのでは?

@SanMurakami
Copy link
Contributor

そのぐらいのストレージしか用意できないってことはマシンスペックも相対的に下がるのではって話です。

もちろん極端にストレージだけ少なくて、マシンスペックの高いインスタンスもあるでしょうが、殆どはVPSやクラウド等で運用されていると思うのでストレージにお金が出せない管理者のインスタンスは相対的にマシンスペックも下がると思います。

@acid-chicken
Copy link
Member Author

まあそれはそうですね。ぶっちゃけストレージの件は Outdated な話題なので、どちらかというとコーデックと再生可能なデバイスの関係に視点を置いた方が良いかも知れません。

@SanMurakami
Copy link
Contributor

あと、代案としてはAWS Elemental MediaConvert等の外部サービスに対応する等ですかね
まぁこれもそれなりにお金が掛かるので、小規模インスタンスの運営者にとっては厳しいかもしれませんが。
https://aws.amazon.com/jp/mediaconvert/

@acid-chicken
Copy link
Member Author

うーん、まあ小規模インスタンスなら Transloadit の無料枠とかで事足りそうではあると思うのですが。

@SanMurakami
Copy link
Contributor

そんなサービスがあったんですね

あとはいくらスペックの高いインスタンスでも流石に動画の変換はサーバー全体に負荷がかかるので、FFmpegだけ別で実行できるシステムを組んだほうが良さそうな気がしますね。
(Summaly proxyみたいな形で)

@tamaina
Copy link
Contributor

tamaina commented Feb 15, 2022

とりあえず長い動画については置いておいて、 #3969 (gif, apng, animated webp, 短い無音動画の処理) ぐらいはやりたい

@tamaina
Copy link
Contributor

tamaina commented Feb 15, 2022

長い動画はPeerTubeの連携を強化する(アカウント連携でアップロード→引用できるようにするとか?)とかでもよさそう

@tamaina
Copy link
Contributor

tamaina commented Jan 5, 2023

正直クライアントサイドで再エンコードさせたい

なぜクライアントサイド?

とにかくGPU支援でないと動画エンコードは厳しい。
適当なVPSでGPU支援が受けられるわけではない。

再エンコード先のターゲットは?

Misskeyは動画サイトではないので、720p60を上限にして良さそう(その代わり画質をちょっとよくしたい)

問題はコーデック(とコンテナ)だが…
ビデオは、結局コンシューマー向けのSoC/GPUで圧縮するとなるとH264しかない?
オーディオは、Safariはopusに対応していないらしいのでaacか?

手法

A: WebCodecs, VideoEncoderを使う

ブラウザネイティブAPIであるWebCodecs, VideoEncoderなどを使う
ネイティブAPIなんだから一番早いんじゃないだろうか(超適当)

でだ、なんと、WebCodecsではコンテナを扱うことができない!
w3c/webcodecs#24

ということでWeb APIだけではMux/Demuxできないので他の手段を用いる必要がある(ffmpegと組み合わせればいける、Uint8Arrayでしか引渡できないのでメモリを食い潰す懸念があるが、Misskeyのアップロード制限は100MB以下が多いため問題になる場面は少ないだろう)

FirefoxはWebCodecsに対応していないが、圧縮しなければ良さそう

B: wasmでなんとかする?

ffmpeg.wasmでffmpegが扱える
https://github.com/ffmpegwasm/ffmpeg.wasm

GPU支援なんてなく、CPUエンコードなのであまり現実的ではない(wasmからGPUの動画エンコーダーを扱うのは極めて困難ではなかろうか…)

@rinsuki
Copy link
Contributor

rinsuki commented Jan 5, 2023

  • 結局たぶんユーザーの手元でffmpegなりで変換してもらうのが一番効率的なので、とりあえず最初に「お前の上げようとしてるファイルの互換性は微妙だが本当にいいのか?」と聞く案を推したい
  • Web Codecs でもいいけどSafariとFirefoxがいつ来るかが微妙
  • wasmでもサーバーサイドでもいいけど、推奨外のフォーマット上げられたらどこかで「とりあえず見れる」程度に再エンコした互換性重視ファイルを置くのはありかも (昔の〜100MB制限のあったニコニコのイメージ)

@tamaina
Copy link
Contributor

tamaina commented Jan 5, 2023

  • 結局たぶんユーザーの手元でffmpegなりで変換してもらうのが一番効率的なので、とりあえず最初に「お前の上げようとしてるファイルの互換性は微妙だが本当にいいのか?」と聞く案を推したい

一般人は動画の再エンコードなんてしないし私が面倒

* Web Codecs でもいいけどSafariとFirefoxがいつ来るかが微妙

SafariはTPに来ているらしいので製品実装してくれると信じている
Firefoxは考えないことにする

* wasmでもサーバーサイドでもいいけど、推奨外のフォーマット上げられたらどこかで「とりあえず見れる」程度に再エンコした互換性重視ファイルを置くのはありかも (昔の〜100MB制限のあったニコニコのイメージ)

クライアントサイドで複数ファイル生成させるのはサードパーティ対応的に微妙かなと。微小サイズならサーバーサイドでCPUエンコードでもさほど問題にはならないかも(画像含めて互換性重視ファイルの生成の機運が高まっている?)

通信量削減狙うならよほどソースが高ビットレートでない限りGPUで再エンコはなさめ (あれはある程度画質と帯域のコスパを犠牲にして速度を求めるものなので
#9474 (comment)

avc/H.264をターゲットにしてしまうと結局これになってしまう

@rinsuki
Copy link
Contributor

rinsuki commented Jan 5, 2023

クライアントサイドで複数ファイル生成させるのはサードパーティ対応的に微妙かなと

それを言い出すと結局クライアントサイド再エンコ自体が微妙っちゃ微妙

@tamaina
Copy link
Contributor

tamaina commented Jan 5, 2023

それを言い出すと結局クライアントサイド再エンコ自体が微妙っちゃ微妙

ふむ?クライアントサイドでエンコードする場合オリジナルはアップロードしない予定
(画像のように、オリジナルをアップロードしたい場合はトグルしてアップロードする、サーバーで処理しないため公開版とオリジナル両方をMisskeyに保持させたい場合は両方アップロードする必要はある)

再エンコードの品質はクライアントに依存するにはするが、マシなファイルがアップロードされるだろうという性善説を取っておく

@acid-chicken
Copy link
Member Author

参考: Chocobozzz/PeerTube#947

@tamaina
Copy link
Contributor

tamaina commented Jan 5, 2023

参考: Chocobozzz/PeerTube#947

動画トランスコードを他のサーバーで実行させたい、(PeerTube(やMisskey)は分散型を標榜しているので下手にTransloaditやAWS Elemental MediaConvertを実装してしまうとロックインに繋がるのでナシ)、でも動画トランスコードを他のサーバーで実行させるような規格やOSSは低調

という感じかしら

@tamaina
Copy link
Contributor

tamaina commented Jan 5, 2023

(外部のサーバーで動画トランスコードができるからと言って運営者の負担がそこまで減るわけではないんだよな…)

@saschanaz
Copy link
Member

でだ、なんと、WebCodecsではコンテナを扱うことができない!

https://w3c.github.io/webcodecs/samples/ ではmp4box.jswebm-writerを使っていますので同じ方法で何とか実装できそうです(mux/demux自体はそこまでCPUリソース必要ないはずですので)

試してみたい

@acid-chicken
Copy link
Member Author

ISOBMFF のパース(→そのまま再生可能な形式にできそうなら muxing も)は普通にやってよいと思うというか割と優先度高めでやりたい

@acid-chicken
Copy link
Member Author

無理にクライアントでやらなくてもいいし圧縮しなくてもいいからさっさとやりたくなってきた

@acid-chicken
Copy link
Member Author

iOS からのアップロードだと yuvj420p になるけど Web で広く再生可能なピクセルフォーマットなのか要調査って感じだ

@acid-chicken
Copy link
Member Author

こんなところか

  • オリジナルファイルを保持 → 今まで通り
  • 再マルチプレクスのみ → ffmpeg -i in.ext -c:v copy -c:a copy -movflags +faststart -fflags +bitexact out.ext
  • 画質を指定して再エンコード (MP4 / MOV / 3GP) → ffmpeg -i in.ext -c:v libx264 -c:a copy -crf ${quality} -pix_fmt yuv420p -profile:v main -threads:v 1 -movflags +faststart -fflags +bitexact out.ext

@syuilo
Copy link
Member

syuilo commented Jun 7, 2023

無理にクライアントでやらなくてもいいし圧縮しなくてもいいからさっさとやりたくなってきた

わかる

@saschanaz
Copy link
Member

無理にクライアントでやらなくてもいいし

大型サーバーの負担がかなり大きくなりそうな気がします

圧縮しなくてもいいから

これはつまりどうなりますか?

@syuilo
Copy link
Member

syuilo commented Jun 7, 2023

大型サーバーの負担がかなり大きくなりそうな気がします

負荷に耐えられるサーバーを用意できる場合だけオンにすれば良さそう

@tamaina
Copy link
Contributor

tamaina commented Jun 7, 2023

圧縮しなくてもいいから
再マルチプレクス

-movflags +faststartする(全ロードを待たずにすぐ再生できるようにする)

@acid-chicken
Copy link
Member Author

  • 再マルチプレクスのみ → ffmpeg -i in.ext -c:v copy -c:a copy -movflags +faststart -fflags +bitexact out.ext

すれば再生確率が上がるが iOS 動画とかは無理

  • 画質を指定して再エンコード (MP4 / MOV / 3GP) → ffmpeg -i in.ext -c:v libx264 -c:a copy -crf ${quality} -pix_fmt yuv420p -profile:v main -threads:v 1 -movflags +faststart -fflags +bitexact out.ext

すれば大概のデバイスで再生できていい感じになる

@acid-chicken
Copy link
Member Author

フロントエンドの実装は

  • 画像をアップロード
  • 動画をアップロード
  • 音声をアップロード
  • ファイルをアップロード

に分けてオプションが散らからないようにすればいいかなと思ってる

@acid-chicken
Copy link
Member Author

あるいはもうなんかファイルをアップロードするダイアログかなんか新設しても良いかもだけど

@acid-chicken
Copy link
Member Author

一回 Cloudflare Stream にアップロードして再エンコードされたやつをダウンロードして削除したらいい感じになる説

@tamaina
Copy link
Contributor

tamaina commented Dec 11, 2023

一つのサービスに依存するような実装はなしで(同一のAPIを受け付けるサーバーがOSSライセンスで提供されているならアリ)

@tamaina
Copy link
Contributor

tamaina commented Dec 11, 2023

同一のAPIを受け付けるサーバーがOSSライセンスで

(このくらいなら自分たちで作れるのでは

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬Discussion Being discussed or needs discussion 🔥high priority packages/backend Server side specific issue/PR
Projects
None yet
Development

No branches or pull requests

8 participants