🎙️

Ionic Capacitor + Vuejs で音声を流す

2022/09/19に公開1

友人から飲み会代で頼まれたアプリ開発で Ionic Capacitor を使ってみることに。
職場で Vuejs を使っているので、慣れも兼ねて、表題の組み合わせにしています。

ただ Vuejs でのアプリ開発の勢力圏は小さいみたいで、文献の無さにかなり苦労しています..涙
アプリ開発で Modern JS を使うならば React とか Angular をお勧めしたい。

Capacitor の Native Audio を使います

https://github.com/capacitor-community/native-audio

というわけで表題の件ですが Capacitor の Native Audio を使います。
調べると以下の方法が上がってきますが、断念したこともログっておきます。

断念した方法

  1. HTMLAudioElement を使う
    1. new Audio() でインスタンスを作ってペイロードやプレイをする
    2. アプリで再生できなかったのと、WebブラウザでもSafariに制約があり検証もしづらく断念
  2. HOWLER.js を使う
    1. new Howl() でインスタンスを作ってペイロードやプレイをする
    2. HTMLAudioElement と比べてSafariにも対応しているが、結局アプリでは再生できずで断念
  3. アーロン・K・サンダース氏ionic-html5-audio-vue ライブラリを使う
    1. Ionic Capacitor + Vue の組み合わせの見識者さんで、実装方法の動画を上げてたりするおじさまのライブラリ。これ系で検索するときに必ずお見かけする方なんで、候補にあがりました
    2. 2年前で更新が止まっているので、まさか、と思いましたが Vue 3系に対応せず。なので断念
  4. Cordova Plugin Native Audio を入れる
    1. ハイブリットアプリのエンジン Cordova が提供するプラグイン
    2. Vue に入れた途端 Angular のライブラリを求められる始末。断念

実装内容(サンプル)

パッケージインストール

$ npm install @capacitor-community/native-audio

JS

// ライブラリをインポート
import { NativeAudio } from '@capacitor-community/native-audio'

export default defineComponent({
  name: 'HomePage',

  data: function () {
    return {
      photoSrc: "",
    };
  },
  
  // タイミングはどこでも良いけど、インスタンス作成
  mounted() {
    NativeAudio.preload({
      assetId: "complete",
      assetPath: "public/assets/sounds/otsukaresama.mp3",
      audioChannelNum: 1,
      isUrl: false
    });
  },

  methods: {
    // 作っているアプリが写真をアップロードして証拠を残して納品、という感じなので、
    // 写真撮影と同時に音声を流すような仕様にしています。
    async getPhoto() {
      // 撮影
      const image = await Camera.getPhoto({
        quality: 90,
        resultType: CameraResultType.Uri,
        promptLabelPicture: "カメラで撮影",
        promptLabelPhoto: "写真を選択",
      });

      // カラ対策
      this.photoSrc = image.webPath || "";

      // アラート表示 + 音声再生
      alert("おつかれさま!納品完了です");
      NativeAudio.play({
        assetId: 'complete',
        time: 0.0
      });
    },
  },
});

まぁそうでしょ、って結果なんですけど、これにたどり着くまでに2日くらいかかった。。
でもこれで進捗したから、美味い酒が飲める!


まったく関係無いですけど「よつばと」の原画展があるみたいですね。

https://twitter.com/marui_anime/status/1570730220583546880

唯一と言っていいほど好きな漫画なので、コロナがまた落ち着いたら、行ってみたいなー、と思ってます。

Discussion

クリオネア2世クリオネア2世

audioタグを用いてもmp3を再生することが可能でした。
私の環境では何故か Native Audio を用いても音が再生されなかったため(おそらく何処か私の設定が間違っていると思われます)コメントさせていただきます。
以下は参考のためのコードです。このうち、再生ボタンだけ実装しましたが再生されました。

<template>
  <div id="app">
    <!-- Audio タグ -->
    <audio ref="audioPlayer">
      <source src="path/to/your/audiofile.mp3" type="audio/mpeg" />
      お使いのブラウザは audio タグをサポートしていません。
    </audio>

    <!-- 再生ボタン -->
    <button @click="playAudio">再生</button>
    
    <!-- 停止ボタン -->
    <button @click="pauseAudio">停止</button>
    
    <!-- 再生位置を変更するボタン -->
    <button @click="setAudioTime(10)">10秒へ移動</button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'App',
  methods: {
    playAudio() {
      const audio = this.$refs.audioPlayer as HTMLAudioElement;
      audio.play();
    },
    pauseAudio() {
      const audio = this.$refs.audioPlayer as HTMLAudioElement;
      audio.pause();
    },
    setAudioTime(time: number) {
      const audio = this.$refs.audioPlayer as HTMLAudioElement;
      audio.currentTime = time;
    }
  }
});
</script>

<style scoped>
/* 任意のスタイルを追加 */
button {
  margin-right: 10px;
}
</style>