質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Emscripten

Emscripten は JavaScript に変換するコンパイラです。 C/C++ から生成される LLVM ビットコードをJavaScript に変換します。

FFmpeg

FFmpegは、動画と音声を交換できるフリーソフトウェアです。UNIX系OSから派生した、MS-DOSから操作するコマンドラインツールです。libavcodecやlibavformat、libswscale、libavfilterなどを含みます。ライセンスは、コンパイルの際のオプションによりLGPLもしくはGPLに決定されます。対応コーデックや使用できるオプションが多く、幅広く利用されています。

Q&A

1回答

1054閲覧

FFmpeg を Emscripten をつかって JavaScript で使えるようにしたい

leonardo

総合スコア10

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Emscripten

Emscripten は JavaScript に変換するコンパイラです。 C/C++ から生成される LLVM ビットコードをJavaScript に変換します。

FFmpeg

FFmpegは、動画と音声を交換できるフリーソフトウェアです。UNIX系OSから派生した、MS-DOSから操作するコマンドラインツールです。libavcodecやlibavformat、libswscale、libavfilterなどを含みます。ライセンスは、コンパイルの際のオプションによりLGPLもしくはGPLに決定されます。対応コーデックや使用できるオプションが多く、幅広く利用されています。

0グッド

1クリップ

投稿2019/03/12 13:59

編集2019/03/12 15:08

JavaScript で FFmpeg を使用したいと考えています。

videoconverter.js (https://github.com/bgrins/videoconverter.js) や ffmpeg.js (https://github.com/Kagami/ffmpeg.js) は既に試しておりますが、使用している FFmpeg のバージョンが2.0系と古く、今のiPhone や Android の動画形式(hevc, h.265) のエンコードができずにいます。

また、最新の FFmpeg 3.0 以上とコーデックを追加することで、上記形式のエンコードが JavaScript で可能であることは以下のサイトで試しております。
https://neo.idletime.tokyo/web/idleencoder_js/index.html

そのため、技術的には問題ないと思うのですが Emscripten の知識が足らず、 JavaScript で使えるまでに至っていない状態です。
idleencoder のサイトではソースコードを公開しておりますが、 情報が少なくコンパイルできていません。

そこで、 ffmpeg.js, videoconverter.jsMakefile を参考にしまして以下のように作業を行いました。

terminal

1% git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg 2% cd ffmpeg 3% emconfigure ./configure --cc=emcc --ar=emar --ranlib=emranlib --prefix=$(pwd)/../dist --enable-cross-compile --target-os=none --arch=x86_32 --cpu=generic --disable-stripping --enable-shared --disable-programs --disable-asm --disable-doc --disable-devices --disable-pthreads --disable-w32threads --disable-network --disable-debug --disable-xlib --disable-zlib --disable-sdl2 --disable-iconv --disable-everything --enable-protocol=file --enable-decoder=hevc --enable-parser=hevc --enable-demuxer=hevc --enable-decoder=h264 --enable-parser=h264 --enable-demuxer=h264 4% emmake make -j4 5% emmake make install

上記コマンドを実行して dist ディレクトリに include/ lib/ share/ の3つのディレクトリが生成されました。
一方で、参考にした Makefile ではこの時点で ffmpeg というバイナリファイルが生成されているように見受けられましたが、 ffmpeg バイナリファイルはみつかりませんでした。
https://github.com/Kagami/ffmpeg.js/blob/master/Makefile#L302
https://github.com/bgrins/videoconverter.js/blob/master/build/build_all_codecs.sh#L80 など

idleencoder のサイト(https://neo.idletime.tokyo/web/idleencoder_js/index.html) にも

ffmpegが作成されたらfinalというスクリプトがあるので

という一文があり、 ffmpeg のバイナリファイルが生成されるのではと考えているのですが、依然としてわからずにいます。

どのようにして FFmpeg を JavaScript で実行できるところまで持っていくことができるでしょうか
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

正直な話、私もあまり詳しくはないのですが、
多分待っててもEmscriptenに詳しい回答者は出てこないと思うので進めます。

以前Ogg Vorbisという音楽フォーマットを作る為に、
GitHubに上がっているソースコードをEmscriptenでJavaScriptにトランスパイルして私のWebサイトに実装するという事をやった経験があります。
相当前なので多くは忘れてしまいましたが、いくらかは助言出来るかと思います。


ffmpeg のバイナリファイルが生成されるのではと考えているのですが、依然としてわからずにいます。

ここが勘違いです。
ChromeやFirefoxなどのブラウザが動作する言語はJavaScriptだけです。
つまり、Emscriptenが吐き出す結果はJavaScriptファイルです。

良い機会なので軽くおさらいしましょう。
そもそもA言語とB言語を混ぜて使おうという試み自体はよくある話ですが、
LLVMというコンパイラ基盤があり、
Emscriptenはそのエコシステムを利用しています。

Javaのバイトコードの様なLLVM用のバイトコードに一度コンパイルし、
それを媒体に様々な言語に固め直したり、実行ファイルに固めなおしたりするようです。

このLLVM自体はその筋では結構メジャーなようで、
既に様々な言語からLLVM用のバイトコードに変換するコンパイラは既に存在します。
C言語用のコンパイラも存在しているのでLLVMのバイトコードに変換出来る。

じゃあEmscriptenが何やってるのかに関してですが、
LLVM用のバイトコードをJavaScriptのコードに固め直しています。
(CoffeeScript→JavaScriptのように別言語同士に変換するものをトランスパイラと呼びます)

したがってコンパイル結果はJavaScriptのコードです。
中身はとてもじゃないけど読めませんし、苦労して読んでも思想が違うので死にます。


どのようにして FFmpeg を JavaScript で実行できるところまで持っていくことができるでしょうか

WebAssemblyという技術が少しずつ整備されていっていますが、
まだWebAssemblyは使えません。
しかしその前身であるasm.jsは使えます。

そもそもC言語が何故速いかというと、徹底したメモリ管理にあります。
特定の場所から4バイト分の仕様許諾を取り、そこに変数Intで宣言した値を放り込む…みたいなことをやっています。
asm.jsは内部的にINT等のC言語と同じ様な型を実装し、仮想的なメモリ管理を行うことでC言語と似たような事をやろうとしています。

これはどっかのサイトに書いてあった事のうろ覚えですが、
普通のエンジニアがネイティブJSでコードを書くのに比べると2〜3倍程度の速度が出るようです。

この辺の思想の問題で、
Emscriptenを使ってLLVMからJavaScriptに固め直しただけのコードでは、
JavaScriptから利用することは出来ません。
JavaScriptにInt型とかねーし。。。

なので、Emscriptenでコンパイルする際、
JavaScriptのコードをセットで読み込ませてあげて、関数というC言語世界とやり取りする穴を開けてやる必要があります。
このJavaScriptファイルに関しては参考となる既存プロジェクトを読めばなんとかなるでしょう。


このEmscriptenは地獄でした。
仕事を辞めてニートになったんだしちょっと触ってみようというノリではじめましたが、
普通に死にましたね、トライアンドエラーで1ヶ月はかかりました。

仕事でやってるならご愁傷様という感じですが、
趣味だったら難度も挫折しながらゆっくり進めていく形になるかと思います。

根を詰めないように頑張ってください。

投稿2019/03/12 14:42

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

leonardo

2019/03/12 15:05

videoconverter.js では、出力された `ffmpeg` のバイトコードを `emcc` コマンドを用いて js へコンパイルしております。以下の箇所になります https://github.com/bgrins/videoconverter.js/blob/master/build/build_all_codecs.sh#L83 また、ffmpeg.js では WebWorker で動作させるために、前後に JavaScript のコードで挟んでおりますが、同様にして `emcc` を利用してコンパイルしております。 https://github.com/Kagami/ffmpeg.js/blob/master/Makefile#L315 自分の手元の環境では、質問文に記載しました手順により、ffmpeg のソースコードから ffmpeg のバイトコードへ変換をおこないましたが、ここで ffmpeg のバイトコードがどうしても生成されず、JavaScript コードに変換する手前で進めず、困っております。 こちら、なにか解法があればご教授いただけるとと思います。
miyabi-sun

2019/03/12 15:09

ん〜、その手前までは全部作られてるんですか? だったらEmscriptenの動作環境を作るのに失敗してるんじゃないですかね? DockerのイメージでEmscriptenインストールされてコマンド動きますよみたいなのが配布されているので、そこを起点に環境構築から進めてみては?
leonardo

2019/03/12 15:16

Emscripten の環境は以下の公式ドキュメントを参考に実行できているように見えています。 https://emscripten.org/docs/getting_started/downloads.html 一度、Docker を使ってみるなどして環境を変えて同じ結果になるか確認してみようと思います。 ありがとうございました。
oikashinoa

2019/03/13 15:01 編集

私もEmscriptenには詳しく無いですが、おもしろそうなんでみんなで解決しませんか? 1. [ソース](https://neo.idletime.tokyo/data/idleencoder.js-0.1.tar.xz)をダウンロード後に展開 2. emscripten インストール(Ubuntu使用なのでsudo apt 使用) 3. 各フォルダ(lame-3.99.5など)に入って以下を繰り替えす   1. emconfigure ./econfig (ffmpeg-3.0.1は./econfig_webm と ./econfig_x264 )    1. エラー出たらconfig.logを確認      1. 大抵はライブラリが足らない?インストールしたパッケージ       1. emscripten         1. ffmpegのコンパイル環境のために、[ffmpegをビルドする - Qiita](https://qiita.com/ottyajp/items/bd17ac06460816d62699)をみてパッケージ追加       2. libmp3lame-dev       3. libogg-dev       4. libvorbis-dev       5. libx264-dev    2. ffmpeg-3.0.1は一番最後かも   2. emmake make 4. 最後に./final って感じかなと思い進め中です。が、エラー出まくってて手探り中です。 leonardoさんがやっている手順をざっくりでいいのでおしえて頂けると嬉しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問