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

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

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

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

FFmpeg

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

Q&A

1回答

1364閲覧

exec関数を使って特定のライブラリを実行したい

bokupiroki

総合スコア54

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

FFmpeg

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

0グッド

0クリップ

投稿2021/07/06 03:09

編集2021/07/06 11:23

前提・実現したいこと

  • ffmpegというライブラリを使って、サイト上で2つの音源を合成(ミックス)できるようにしたい
  • phpのexec関数を利用して処理を行おうとしています。
  • 開発環境はMac上のDocker

発生している問題・エラーメッセージ

何もおこりません。
特にエラーらしきメッセージも出ず困ってます。

↓該当アクションにアクセスしたときのブラウザ上の表示

Array ( )

output.mp3は生成されません。

該当のソースコード

php

1public function cmd(){ 2 $cmd = 'cd ../storage/app/private && /usr/bin/ffmpeg -i motoongen.wav -i ongen.m4a -filter_complex amix=inputs=2:duration=longest output.mp3'; 3 exec($cmd,$opt); 4 print_r($opt); 5 }

試したこと

①コンテナ内で直接コマンドを実行すれば成功しました

root@90418f2ef79f:/var/www/ecapp02/storage/app/private# /usr/bin/ffmpeg -i motoongen.wav -i ongen.m4a -filter_complex amix=inputs=2:duration=longest output.mp3

output.mp3は生成されます。

②exec関数が正常に動作すること確認
ffmpegの記述の部分をpwdに変えて動作確認しました。

php

1public function cmd(){ 2 $cmd = 'cd ../storage/app/private && pwd'; 3 exec($cmd,$opt); 4 print_r($opt); 5 } 6 7//ブラウザ上に表示される結果 8Array ( [0] => /var/www/ecapp02/storage/app/private )

実行結果が表示されたので、exec関数自体は動いているように見えます。

③ライブラリの参照先の調査
おそらくなのですが、
コマンドを叩いて実行するときに参照しているライブラリ保存先と
exec関数利用時に参照するライブラリの保存先が異なるのではないか?
と考えました。(的外れでしたら申し訳ありません)

コンテナ内にてwhichコマンドで確認すると

root@90418f2ef79f:/var/www/ecapp02/storage/app/private# which ffmpeg /usr/bin/ffmpeg

と表示されることから、ライブラリffmpegは/use/binに保存されているようです。

exec関数利用時にもし別の場所が参照されているのであれば、
そのディレクトリにffmpegのライブラリをコピーすればいいのでは?
と考えています。

ですがexec関数がライブラリ実行時にどのディレクトリを参照しているか、
調べ方がわかりません。

参考にしたサイト
ffmpegをphpのexecで動かそうとしてハマる

④実行権限があるのか
まず、exec関数実行ユーザーを調べました。

public function cmd(){ $user = exec('whoami'); dd($user); } // ブラウザに表示された結果 "www-data"

↑php実行ユーザーは「www-data」のようです。

www-dataがlsした場合ffmpegが存在するのか確認しました。

php

1public function cmd(){ 2if (!exec('cd /usr/bin/ && ls 2>&1', $array)) { 3 echo "NG"; 4} 5 var_dump($array); 6 } 7} 8 9//ブラウザに表示された結果 10array(771) { [0]=> string(8) "411toppm" [1]=> string(9) "JxrDecApp" [2]=> string(9) "JxrEncApp" [3]=> string(3) "X11" [4]=> string(1) "[" [5]=> string(7) "aclocal" [6]=> string(12)~~(中略)

↑たくさん表示されましたがffmpegはなかったです。

root@90418f2ef79f:/usr/bin# chmod 755 ffmpeg
を叩いて権限を変更してから再度試しましたが、結果は同じでlsしても見つからない状態です。

試しに
root@90418f2ef79f:/usr/bin# chmod 777 ffmpeg
にしてみても結果は同じでした。

参考にしたサイト

www-dataユーザーがバイナリファイルを実行するための権限

補足情報(FW/ツールのバージョンなど)

Laravel Framework 6.20.20
PHP 7.3.28-2+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Jun 4 2021 21:23:19) ( NTS )
Docker 20.10.6

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

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

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

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

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

guest

回答1

0

https://www.php.net/manual/ja/function.exec.php

https://qiita.com/smd8122/items/65b552f1d53bfb7fad9a
を参考にして標準エラーを取得して表示すると原因が掴めると思います

勘としては、

  • 相対パスで指定しているところを絶対パスに変更
  • ライブラリのパーミッションとオーナー、グループをPHPの実行ユーザーが実行できるように調整

すれば動きそうな気がします

投稿2021/07/06 03:33

編集2021/07/06 05:16
tanat

総合スコア18727

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

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

bokupiroki

2021/07/06 04:33

ありがとうございます。 ご提示いただいたqiitaの記事を参考に、標準エラーを出力したところ array(1) { [0]=> string(33) "sh: 1: /usr/bin/ffmpeg: not found" } とブラウザに表示されました。 おっしゃるようにパスの書き方が良くないのかもしれないと思いました。 質問欄のソースコードの 「/usr/bin/ffmpeg ~~~」という書き方ではNGなのでしょうか。 「/user」から記述しているので、絶対パスのつもりでした。 初歩的な勘違いでしたら申し訳ありません。
tanat

2021/07/06 05:13

絶対パス、相対パスについては cd ../storage/app/private の方を指しての回答でした。 /usr/bin/ffmpeg は絶対パスですね。 ただ、PHP実行ユーザーから見た場合に見当たらないという事なので、 chroot環境で実施しているなどありそうです。 exec()で/usr/bin をlsしてみてffmpegが存在しているか確認してみて下さい。 古い情報ですが https://stackoverflow.com/questions/17006136/exec-with-php-fpm-on-nginx-under-chroot-returns-nothing が参考になるかもしれません
bokupiroki

2021/07/06 09:31

ありがとうございます。 確かに、execでlsしてもffmpegの存在が確認できませんでした。 array(1) { [0]=> string(62) "ls: cannot access '/usr/bin/ffmpeg': No such file or directory" } 権限を与えるために root@90418f2ef79f:/usr/bin# chmod 755 ffmpeg などを実行してみましたが、同じでした。 詳細を質問欄に追記したので、確認いただけると幸いです。
bokupiroki

2021/07/06 09:42

すみません、ls ffmepgしても何も出ないですよね 後ほど書き直します
tanat

2021/07/06 09:51 編集

> すみません、ls ffmepgしても何も出ないですよね 何も出ないことは無いですね。 エラーメッセージ通り、 PHPから見た場合、/usr/bin/ffmpegが存在しないんだと思いますよ。 > 開発環境はMac上のDocker だけでは詳細が分からないのでこれ以上の回答は難しいですが、 恐らく、chroot環境でPHPが実行されているため、 PHPから見る/usr/bin と実際の/usr/bin が異なっている という状況なんだと想像しています。 まずは chrootについてよくわからない場合は `linux chroot`で調べて概要を把握してみて下さい。 その後、先のリンクや https://teratail.com/questions/313143 `apache chroot` `php-fpm chroot` `nginx chroot` など、PHP実行環境+chrootをキーワードにして調べてみると解決するかもしれません。
tanat

2021/07/06 12:21

上記の想定が正しかった場合、 1. chrootの設定先ディレクトリを確認 2. そのディレクトリに/usr/bin/ffmpegをコピー(シンボリックリンクでもいけるかも?) もしくは chrootを解除するか、chrootの設定先を/に設定する(https://teratail.com/questions/313143 の解決方法)となります
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問