目次

目次

【ExoPlayer】 flac拡張ライブラリをGitHub Actionsで作成できるようにしてみた

アバター画像
深沢雛子
アバター画像
深沢雛子
最終更新日2024/08/09 投稿日2024/08/09

はじめに

Androidアプリ開発グループの深沢です。 今回、ビルド環境によってflac拡張ライブラリがうまく作成できないことがありましたので、環境に依存しないようCIで作成するようにした話を紹介したいと思います。

ExoPlayerとハイレゾ楽曲

私の携わっているアプリではハイレゾ楽曲再生に対応しています。ハイレゾ楽曲にはWAVやFLACなどいくつかの形式があるのですが、このアプリではFLACをサポートしています。ExoPlayerでFLAC楽曲を再生できるようにするには、FLACをデコードするための拡張ライブラリが必要で、これはExoPlayerのバージョン毎に更新する必要があります。作成手順など詳しくはこちらをご確認ください。

起きたこと

先日targetSDKを34に上げる対応をしたところ、楽曲が再生されなくなってしまいました。調べてみると、現行アプリのExoPlayerバージョンでは PlayerNotificationManager#registerReceiver()が使用されており、これがAPI34では対応されていなかったためということがわかりました。ExoPlayerのバージョンを最新のものに変更するとPlayerNotificationManager#registerReceiver()が使用されていないことがわかったので、ExoPlayerのバージョンアップを行いました。このことに伴って、拡張ライブラリの作り直しが必要になり、私は拡張ライブラリをローカルで作成しました。aarファイルは出力され、アプリに組み込むことはできたのですが、FLAC音源がXperia/Android9などの特定端末では再生できないという事象が起きました。

原因究明

コードを確認すると、Playerをセットするときに FlacLibrary.isAvailable()というメソッドがfalseで返っていました。これはFlacLibraryが機能していないことを意味しており、FLAC対応のハードウェアデコーダーが入っていない機種では再生ができなくなっていました。 先ほどデコードするための拡張ライブラリが必要と書きましたが、一部端末ではライブラリを使用しなくても端末内のハードウェアデコーダーがFLAC楽曲を再生できるようにデコードしてくれるので、ハイレゾ楽曲が問題なく再生できました。そのため、不具合の発見が遅れてしまったので、ExoPlayerを使用するときは FlacLibrary.isAvailable()を用いて確認するようにしましょう… ちなみに、デバイスに搭載されているハードウェアデコーダーを調べる方法もあるようです。参考

原因特定のため色々試して拡張ライブラリを作成してみたところ、javaバージョンなどの環境が違う状態で拡張ライブラリを作成すると、 FlacLibrary.isAvailable()がtrueで返ってきていることがわかりました。このライブラリを使用すると、Xperiaでもハイレゾ楽曲が再生できたため、今回の事象の要因はビルド環境であることがわかりました。

そこで、今回はGitHubActionsを用いてビルド環境を統一し、誰でも機能するflac拡張ライブラリが作成できるようにしました。

拡張ライブラリ自動作成方法

  • .github/workflows内にymlファイルを作成します。
  • ワークフロー名などを設定します。
name: Make Flac Library
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
# トリガーは自由に設定してください。
on:
  workflow_dispatch:
jobs:
  Make-flac-library:
    runs-on: ubuntu-latest
  • Android NDKをダウンロードして、android-ndk-r21eのパスを変数化します。ubuntuを使用しているので、linux版でダウンロードしてください。
- name: Download and set up Android NDK
    run: |
      echo "Downloading Android NDK"
      wget https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64zip
      unzip android-ndk-r21e-linux-x86_64.zip -d $HOME
      echo "NDK_PATH=$HOME/android-ndk-r21e" >> $GITHUB_ENV
      echo "NDK set up at $NDK_PATH"
  • ExoPlayerの特定のバージョンをクローンし、チェックアウトします。

まず、GitHubリポジトリのSettings>Secrets and variables>Actions>Variablesタブに移動します。そこでNew Repository variablesボタンを押下してください。そうしたら、変数が設定できますので、Name:EXOPLAYER_VERSION, Value:任意のExoPlayerバージョン(今回はr2.19.1)を入力して、Add variableボタンを押下してください。これにより、ExoPlayerのバージョンを設定することができました。バージョンを変更したいときは、同じ場所から編集ができます。

clip-20240723161300.jpg

次に、ymlファイルに以下のようにクローン&チェックアウトするようステップを追加します。

ExoPlayer/ExoPlayer/extension/flac/src/main/をそれぞれ変数化します。

- name: Set Flac Module Path
  run: |
    echo "Cloning ExoPlayer repository"
    git clone https://github.com/google/ExoPlayer.git
    cd ExoPlayer
    git checkout tags/${{ vars.EXOPLAYER_VERSION }}
    echo FLAC_MODULE_PATH=$(pwd)/extensions/flac/src/main >> $GITHUB_ENV
    echo EXOPLAYER=$(pwd) >> $GITHUB_ENV
    echo "FLAC_MODULE_PATH set to $FLAC_MODULE_PATH"
  • 続いて、ExoPlayer/local.propertiesを作成し、sdkのパスを記載します。
- name: Create local.properties
  run: |
    echo "sdk.dir=/usr/lib/android-sdk" > $EXOPLAYER/local.properties
    echo "local.properties file created at $EXOPLAYER/local.properties"
    cat $EXOPLAYER/local.properties
  • flacライブラリのダウンロードを行い、flac/に移動させます。
- name: Download and extract Flac Library
  run: |
    cd "${FLAC_MODULE_PATH}/jni"
    curl https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.3.2.tar.xz | tar xJ
    mv flac-1.3.2 flac
    echo "Flac Library download and extracted"
  • Android.mkにコンパイルフラグを追加します。
- name: Update Android.mk
  run: |
    cd "${FLAC_MODULE_PATH}/jni"
    echo "LOCAL_CPPFLAGS := -std=c++11" >> Android.mk
    echo "Added LOCAL_CPPFLAGS to Android.mk"
    cat $FLAC_MODULE_PATH/jni/Android.mk
  • ndk-buildスクリプトを作成します。
- name: Create ndk-build 
  run: |
    echo '#!/bin/sh' > ${NDK_PATH}/ndk-build.sh
    echo 'DIR="$(cd "$(dirname "$0")" && pwd)"' >> ${NDK_PATH}/ndk-build.sh
    echo 'arch -x86_64 /bin/bash $DIR/build/ndk-build "$@"' >> ${NDK_PATHndk-build.sh
    echo "ndk-build script created"
  • ndk-buildを実行して、JNIライブラリを作成します。
- name: Build JNI Library
  run: |
    cd "${FLAC_MODULE_PATH}/jni"
    $NDK_PATH/ndk-build APP_ABI=all -j4
    echo "JNI Library build"
  • gradlewを実行します。これで${{ env.EXOPLAYER }}/extensions/flac/buildout/outputs/aar/にaarファイルが作成されます。
- name: Build extension-flac
  run: |
    cd "${EXOPLAYER}"
    ./gradlew :extension-flac:assembleRelease
    echo "extension-flac assembled"
  • 作成されたaarファイルをGitHubからダウンロードできるようにします。
- name: Upload AAR file
  uses: actions/upload-artifact@v2
  with:
    name: extension-flac-aar
    path: ${{ env.EXOPLAYER }}/extensions/flac/buildout/outputs/aar/extension-flac-release.aar

いざ実行

これで、ワークフローは完成です。実際に実行してみます。 実行が成功すると、ログの下でaarファイルがダウンロードできるようになります。

clip-20240723161440.png

このファイルをアプリに組み込んで、実際にFLAC楽曲を再生してみます。

以前作成した拡張ライブラリ使用時

before.gif

今回作成した拡張ライブラリ使用時

after.gif

以前作成した拡張ライブラリを使用すると、再生しようとしてもできなかったのですが、今回作成したものを使用したところ、無事Xperia/Android9でも再生することができました。

コードを確認すると、 FlacLibrary.isAvailable()がtrueになっており、無事flac拡張ライブラリが機能していることがわかりました。

bb073810789ef0cef19dfd5cc5973e97.png

以下、ymlファイルの全体です。説明としては省きましたが、変数確認ステップなど確認のため記載していたものも載せています。

name: Make Flac Library
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
# トリガー
on:
  workflow_dispatch:
jobs:
  Make-flac-library:
    runs-on: ubuntu-latest
    steps:        
      # Android NDKをダウンロード
      - name: Download and set up Android NDK
      # Ubuntuを使用しているのでlinuxを使用
        run: |
          echo "Downloading Android NDK"
          wget https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip
          unzip android-ndk-r21e-linux-x86_64.zip -d $HOME
          echo "NDK_PATH=$HOME/android-ndk-r21e" >> $GITHUB_ENV
          echo "NDK set up at $NDK_PATH"

      # ExoPlayerの特定バージョンをクローン&チェックアウト
      - name: Set Flac Module Path
        run: |
          echo "Cloning ExoPlayer repository"
          git clone https://github.com/google/ExoPlayer.git
          cd ExoPlayer
          git checkout tags/${{ vars.EXOPLAYER_VERSION }}
          echo FLAC_MODULE_PATH=$(pwd)/extensions/flac/src/main >> $GITHUB_ENV
          echo EXOPLAYER=$(pwd) >> $GITHUB_ENV
          echo "FLAC_MODULE_PATH set to $FLAC_MODULE_PATH"

      # 環境変数の確認
      - name: Verify Environment Variables
        run: |
          echo "Verifying Environment Variables"
          echo "FLAC_MODULE_PATH is: $FLAC_MODULE_PATH"
          echo "EXOPLAYER is: $EXOPLAYER"
          echo "NDK_PATH is: $NDK_PATH"

      # local.propertiesにsdkのパスを記載
      - name: Create local.properties
        run: |
          echo "sdk.dir=/usr/lib/android-sdk" > $EXOPLAYER/local.properties
          echo "local.properties file created at $EXOPLAYER/local.properties"
          cat $EXOPLAYER/local.properties

      # Flacライブラリのダウンロードと解凍
      - name: Download and extract Flac Library
        run: |
          cd "${FLAC_MODULE_PATH}/jni"
          curl https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.3.2.tar.xz | tar xJ
          mv flac-1.3.2 flac
          echo "Flac Library download and extracted"

      # Android.mkにフラグを追加
      - name: Update Android.mk
        run: |
          cd "${FLAC_MODULE_PATH}/jni"
          echo "LOCAL_CPPFLAGS := -std=c++11" >> Android.mk
          echo "Added LOCAL_CPPFLAGS to Android.mk"
          cat $FLAC_MODULE_PATH/jni/Android.mk

      # ndk-buildを作成
      - name: Create ndk-build 
        run: |
          echo '#!/bin/sh' > ${NDK_PATH}/ndk-build.sh
          echo 'DIR="$(cd "$(dirname "$0")" && pwd)"' >> ${NDK_PATH}/ndk-build.sh
          echo 'arch -x86_64 /bin/bash $DIR/build/ndk-build "$@"' >> ${NDK_PATH}/ndk-build.sh
          echo "ndk-build script created"

      # JNIライブラリを構築
      - name: Build JNI Library
        run: |
          cd "${FLAC_MODULE_PATH}/jni"
          $NDK_PATH/ndk-build APP_ABI=all -j4
          echo "JNI Library build"

      # gradlew実行
      - name: Build extension-flac
        run: |
          cd "${EXOPLAYER}"
          ./gradlew :extension-flac:assembleRelease -Pandroid.useAndroidX=true -Pandroid.enableJetifier=true
          echo "extension-flac assembled"

      # ファイルを表示
      - name: List build outputs
        run: |
          echo "Listing build outputs"
          ls -a $EXOPLAYER/extensions/flac/buildout/outputs/aar

      # aarファイルをダウンロード
      - name: Upload AAR file
        uses: actions/upload-artifact@v2
        with:
          name: extension-flac-aar
          path: ${{ env.EXOPLAYER }}/extensions/flac/buildout/outputs/aar/extension-flac-release.aar

flac拡張ライブラリを作成するときは是非参考にしてみてください。

アバター画像

深沢雛子

目次