🎶
flutter 効果音・BGMをループ再生 audioplayers
◎初めに
audioplayers
というパッケージを利用し、効果音やBGMをループ再生させる方法を記述します。
デモとして、標準のカウントアップアプリに効果音をループで実装してみます。
右下のfloatingActionButtonを押すと効果音が流れるようにします。
前提
Flutter 3.0.2
audioplayers 0.20.1
参考
◎audioplayers実装
1:audioplayersパッケージのインストール
pubspec.yamlに下記を追加
audioplayers: ^0.20.1
ターミナルでpubgetを実行
flutter pub get
2:音声ファイルの用意
プロジェクト直下にassetsフォルダを作成し、その中に利用したい音声ファイルを入れる。
pubspec.yaml
ファイルに下記を記述
assets:
- assets/
2:main.dartへの実装
_MyHomePageState
の中に変数を2つ定義
①main.dart内の final audioPlayer = AudioPlayer();
bool isPlaying = false; //再生中か否かを判断する為
②initStateを作成し、モードの指定と、listenを行う
audioPlayer.setReleaseMode(ReleaseMode.LOOP);
でReleaseModeの中に用意されている、LOOP再生を指定。(詳細は参考の公式ドキュメントを確認)
isPlaying = state == PlayerState.PLAYING;
で初めに定義した変数isPlaying
を更新。
@override
void initState() {
super.initState();
//LOOPの設定
audioPlayer.setReleaseMode(ReleaseMode.LOOP);
//再生中か停止中かの状態を取得
audioPlayer.onPlayerStateChanged.listen((state) {
setState(() {
isPlaying = state == PlayerState.PLAYING;
});
});
}
③floatingActionButton内の処理を記述
floatingActionButtonを下記のように書き換えます。
floatingActionButton: FloatingActionButton(
onPressed: () async{
if (isPlaying){
await audioPlayer.pause();
}else{
final player = AudioCache(prefix: 'assets/');
final url = await player.load('roulette_bgm.mp3');
await audioPlayer.play(url.path, isLocal: true);
}
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
再生中だった場合は、停止させる。
if (isPlaying){
await audioPlayer.pause();
else内は、停止中だった場合に、再生させる処理
下記2行でFlutterプロジェクトファイル内の音声ファイルを読み込みセットする
final player = AudioCache(prefix: 'assets/');
final url = await player.load('roulette_bgm.mp3');
下記1行でセットした音声を再生
await audioPlayer.play(url.path, isLocal: true);
エラーが出る場合
自分が動かした際に、音声が短すぎた為か、2回目以降のLOOP再生に入った後に停止ボタンがうまく作動しなくなりました。(loopに入るとisPlayingがfalseに戻ってしまう)
根本的に修正することはできておりませんが、即席代替案として、ボタンをクリックする度にカウントアップを行い判断する形で解消しました。
var isPlayingnum = 1; //2の倍数なら再生中、それ以外は停止中
if (isPlayingnum % 2 != 0){
await audioPlayer.pause();
}else{
final player = AudioCache(prefix: 'assets/');
final url = await player.load('roulette_bgm.mp3');
await audioPlayer.play(url.path, isLocal: true);
}
終わりに😁
Twitterでも情報発信しておりますので、ぜひフォローお願い致します!
全コード
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final audioPlayer = AudioPlayer();
bool isPlaying = false; //再生中か否かを判断する
@override
void initState() {
super.initState();
audioPlayer.setReleaseMode(ReleaseMode.LOOP);
audioPlayer.onPlayerStateChanged.listen((state) {
setState(() {
isPlaying = state == PlayerState.PLAYING;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async{
if (isPlaying){
await audioPlayer.pause();
}else{
// audioPlayer.setReleaseMode(ReleaseMode.LOOP);
final player = AudioCache(prefix: 'assets/');
final url = await player.load('roulette_bgm.mp3');
await audioPlayer.play(url.path, isLocal: true);
}
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Discussion
listenしなくてもこれくらいの機能ならisPlayingのbool型判定だけでループ再生できますよ。
ご教授頂きありがとうございます!🙇