実装した機能
アラーム音声を毎回ランダムに再生する機能
中身
const voiceFiles = {
1: require("../voice/voice1.mp3"),
2: require("../voice/voice2.mp3"),
3: require("../voice/voice3.mp3"),
4: require("../voice/voice4.mp3"),
5: require("../voice/voice5.mp3"),
6: require("../voice/voice11.mp3"),
7: require("../voice/voice12.mp3"),
8: require("../voice/voice13.mp3"),
9: require("../voice/voice14.mp3"),
10: require("../voice/voice21.mp3"),
};
//AlarmScreenコンポーネント内
//checkAlarms関数内
// ランダムなインデックスを取得
const randomIndex = Math.floor(Math.random() * 10) + 1;
// ランダムに選択された音声ファイルを再生
playAlarmSound(voiceFiles[randomIndex]);
// 10秒ごとに音声を再生
const intervalId = setInterval(() => {
playAlarmSound(voiceFiles[randomIndex]);
}, 10000);
Math.floor(Math.random() * 10) + 1
-
Math.random()関数は[0, 1)の範囲で浮動小数点数を返す
ex.)0.123456789 -
Math.random()に10を掛けることで、[0, 10)の範囲の浮動小数点数が得られる
ex.)0.123456789 * 10 = 1.23456789 -
Math.floor()関数は、与えられた数値以下で最大の整数を返す
ex.)Math.floor(1.23456789)は1 -
1を加えることで、最終的に1から20までの整数が得られる
playAlarmSound();
const playAlarmSound = async (file) => {
try {
const { sound } = await Audio.Sound.createAsync(file, {
shouldPlay: true,
});
setSound(sound);
} catch (error) {
console.error("音声ファイルの読み込みまたは再生に失敗しました", error);
}
};
Audio.Sound.createAsync
引数で、ファイルの指定、即時再生のbooleanを指定する。
また、createAsyncメソッドはPromiseを返す。
成功の時は、解決値としてサウンドオブジェクトが返される。このオブジェクトには、soundというキーが含まれており、これが再生や停止、情報の取得などを行うためのサウンドオブジェクトとなる。エラーの際はcatchでエラーログを返す。
https://docs.expo.dev/versions/latest/sdk/audio/
詰まったこと
当初はmp3ファイルを変数で指定して、ランダムに呼び出そうと考えていたが、requireが静的パスしか受け付けていない点で詰まった。最終的に上記記載の通り、オブジェクト{ID:require("静的パス")}
で指定し回避した。
以下ダメな例をメモとして残します。
${randomNumber}
があると無効な呼び出しとされ、そもそもexpo appの画面が表示されない。また、loadAsync()
を使っても回避不可でした。
screens\AudioScreen.js: screens\AudioScreen.js:Invalid call at line 18: require(`../assets/audio${randomNumber}.mp3`)
const AudioScreen = ({ navigation }) => {
useEffect(() => {
const playRandomAudio = async () => {
// 1から3のランダムな番号
const randomNumber = Math.floor(Math.random() * 3) + 1;
const soundObject = new Audio.Sound();
try {
// ランダムに選ばれた番号に基づいて、対応する音声ファイルを読み込む
await soundObject.loadAsync(
require(`../assets/audio${randomNumber}.mp3`)
);
await soundObject.playAsync();
} catch (error) {
console.error("Error loading sound", error);
}
};
const playRandomSound = async () => {
// 1から3のランダムな番号
const randomNumber = Math.floor(Math.random() * 3) + 1;
const soundObject = new Audio.Sound();
try {
const soundPath = `./assets/audio${randomNumber}.mp3`;
const requirePath = require(soundPath);
await soundObject.loadAsync(requirePath);
await soundObject.playAsync();
setSound(soundObject);
} catch (error) {
console.error("サウンドの読み込みエラー", error);
}
};