herokuサーバー上で、music21のpngファイル出力に失敗する
前回の記事でherokuサーバー上でmusic21を動かす際に、LilypondとmuseScoreのパス設定が必要、まだpng画像が生成されないことを書きました。
music21をherokuサーバーで動かす時に困ったこと - rakushoo blog
結論としては、Lilypond(2.20.0-1)内のgsバージョン不整合が原因でした。Buildpackでgsもインストールするようにし、Lilypondから参照するバイナリと差し替えることで対応したところ、png画像が出力されるようになりました。
解決までの経過
ローカルでは動くしパスも通ってるのに何故か画像が出力しない。 png変換でwarningが出ていました。
Converting to PNG... warning: `(gs -q -dSAFER -dEPSCrop -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dNOPAUSE -dBATCH -sDEVICE=png16m -dAutoRotatePages=/None -dPrinted=false -sOutputFile=Oleo.png -r101 -fOleo.eps)' failed (256) fatal error: failed files: "/app/media/output/Oleo"
とりあえず、gsなんちゃらのコマンドで失敗していると。ここで3日ほどハマったので、検討した手順だけ残しておきます。
- そもそも入力ファイルがどういう手順でpngに変換されるかを確認。
- ローカルでは、lyファイル、epsファイル(複数)、pngファイルが作成されている。この時点で拡張子なしのファイル(.lyファイル)のみ作成されていた。→ epsファイルの変換で失敗している、ぽい
- music21のソースをfolkして確認。コード見ても異常なし。
- herokuサーバーにログインして、lilypondを直接実行したところ、.epsファイルが一つ作成されるがやはりgsで失敗。
lilypondの不具合だということまではわかった
不具合は、music21ではなく、Lilypondが受け持つ処理で、gsコマンドが失敗している、とまでわかった。外部アプリの不具合は辛い。。まあ仕事じゃないし、諦めてローカルで画像を作るようにPCアプリにしようかとぼんやり考えながら休憩。
ふと、デバッグログとか無いかな?、とlilypondのヘルプを見たら大当たりでした。
ログレベルを設定して実行したところ、gsコマンドのバージョン不一致が原因とのこと。
/app/lilypond/usr/bin/lilypond -f png -dbackend=eps --loglevel=DEBUG -o /app/media/output/test /app/media/output/sample.ly 〜省略〜 [test.eps] Invokinggs -dSAFER -dEPSCrop -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dNOPAUSE -dBATCH -sDEVICE=png16m -dAutoRotatePages=/None -dPrinted=false -sOutputFile=test.png -r101 -ftest.eps'... gs: Interpreter revision (926) does not match gs_init.ps revision (921).
lilypond内のgsバージョン不整合が原因
インストールしたLilypond(2.20.0-1)から通るパスのgsバージョンは9.26だが、途中で必要となるgs_init.psバージョンが9.21と不整合となっていた。
Buildpackでgs(Ghostscript)9.21をインストールし、lilypondから使用するgsと差し替えることにし、無事に画像出力ができるようになった。
GitHub - rakushoo/heroku-buildpack-ghostscript: Ghostscript for Heroku Cedar
自分のアプリから呼び出したアプリ内の不具合調査は疲れるけど、良い経験になりました。