Flutter開発実践 - just_audio では、音声の再生、一時停止、音量設定などを実現します。
最近の開発プロセス中に、バックグラウンド サウンドやその他のオーディオ再生の必要性が発生しました。ここでは、just_audio を使用してオーディオの再生、一時停止、音量の設定などを行います。
1. just_audio の導入
pubspec.yaml に just_audio を導入する
just_audio: ^2.7.0
iOS では、video_player は再生に AVPlayer を使用します。
Android では、video_player は ExoPlayer を使用します。
2. 使用前のセットアップ
2.1 iOS での設定
Https、HTTP ビデオ アドレスをサポートするために、iOS プロジェクトの info.plist に設定を追加します。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2.2 Android での設定
/android/app/src/main/AndroidManifest.xml ファイルにネットワーク権限を追加する必要があります
<uses-permission android:name="android.permission.INTERNET"/>
3. Just_audio は、オーディオの再生、一時停止、音量の設定などを実現します。
just_audio を導入すると、AudioPlayer を使用してオーディオを再生できるようになります
3.1 共通の操作は次のとおりです。
- 遊ぶ
await _audioPlayer.play();
- 一時停止
await _audioPlayer.pause();
- 求める
await _audioPlayer.seek(position);
- 停止
await _audioPlayer.pause();
await _audioPlayer.seek(Duration.zero);
- 音量を設定する
await _audioPlayer.setVolume(volume);
3.2 just_audio を使用してプレーヤーを実装する
ここで、プレーヤーは SDAudioPlayerState 状態の取得、オーディオの一時停止の制御、オーディオの音量の設定、およびその他の操作に使用されます。
import 'package:flutter_app/manager/logger_manager.dart';
import 'package:just_audio/just_audio.dart';
// 播放回调
typedef SDAudioPlayerCallBack = void Function(
SDAudioPlayerState state, SDAudioPlayerError? error);
// 播放音频的状态
enum SDAudioPlayerState {
idle, // 默认
loading, // 加载中
buffering, // 缓存中
ready, // 可播放
completed, // 播放完成
}
// 播放音频出现错误
class SDAudioPlayerError {
String? message;
}
// 定义优先级的类
class SDMusicConfig {
// 音频文件地址
late String audioUrl = '';
late bool runLoop = false; // 是否循环播放
// 构造函数
SDMusicConfig(this.audioUrl, this.audioPriority, this.runLoop);
}
// 播放音频文件
class SDMusicPlayer {
// 音频播放
late AudioPlayer _audioPlayer;
// 优先级
late SDMusicConfig _musicConfig;
late bool _playing = false; // 是否正在播放
late SDAudioPlayerState _playerState = SDAudioPlayerState.idle; // 状态
late SDAudioPlayerCallBack? _playerCallBack;
SDMusicPlayer(this._audioPlayer, this._musicConfig){
setAudioUrl(this._musicConfig.audioUrl);
openPlayCallBack((state, error) {
});
}
SDMusicConfig getMusicConfig() {
return _musicConfig;
}
void openPlayCallBack(SDAudioPlayerCallBack playerCallBack) {
_playerCallBack = playerCallBack;
_audioPlayer.playerStateStream.listen((state) {
_playing = state.playing;
switch(state.processingState) {
case ProcessingState.idle: {
_playerState = SDAudioPlayerState.idle;
break;
}
case ProcessingState.loading: {
_playerState = SDAudioPlayerState.loading;
break;
}
case ProcessingState.buffering: {
_playerState = SDAudioPlayerState.buffering;
break;
}
case ProcessingState.ready: {
_playerState = SDAudioPlayerState.ready;
break;
}
case ProcessingState.completed: {
_playerState = SDAudioPlayerState.completed;
if (_musicConfig.runLoop == true) {
// 循环播放的时候
seek(Duration.zero);
play();
} else {
stop();
}
break;
}
default:
}
if (_playerCallBack != null) {
_playerCallBack!(_playerState, null);
}
});
}
// var duration = await player.setUrl('https://foo.com/bar.mp3');
Future<void> setAudioUrl(String url) async {
SDAudioPlayerError? error;
if (url.isNotEmpty) {
// Set the audio source but manually load audio at a later point.
try {
_audioPlayer.setUrl(url, preload: true);
// Acquire platform decoders and start loading audio.
var duration = await _audioPlayer.load();
print("url:${url} duration:${duration}");
} on PlayerException catch (e) {
// iOS/macOS: maps to NSError.code
// Android: maps to ExoPlayerException.type
// Web: maps to MediaError.code
// Linux/Windows: maps to PlayerErrorCode.index
print("SDAudioPlayer Error code: ${e.code}");
// iOS/macOS: maps to NSError.localizedDescription
// Android: maps to ExoPlaybackException.getMessage()
// Web/Linux: a generic message
// Windows: MediaPlayerError.message
print("SDAudioPlayer Error message: ${e.message}");
error = SDAudioPlayerError();
error.message = e.message;
} on PlayerInterruptedException catch (e) {
// This call was interrupted since another audio source was loaded or the
// player was stopped or disposed before this audio source could complete
// loading.
LoggerManager()
.debug("SDAudioPlayer Connection aborted: ${e.message}");
error = SDAudioPlayerError();
error.message = e.message;
} catch (e) {
// Fallback for all errors
print("e: ${e}");
error = SDAudioPlayerError();
error.message = e.toString();
}
} else {
error = SDAudioPlayerError();
error.message = '播放地址不能为空';
}
if (_playerCallBack != null) {
_playerCallBack!(_playerState, error);
}
}
void play() async {
// Usually you don't want to wait for playback to finish.
if (_musicConfig.audioUrl != null && _musicConfig.audioUrl.isNotEmpty) {
if (_playing == false) {
// 正在播放
await _audioPlayer.play();
}
}
}
void pause() async {
if (_musicConfig.audioUrl != null && _musicConfig.audioUrl.isNotEmpty) {
await _audioPlayer.pause();
}
}
void stop() async {
if (_musicConfig.audioUrl != null && _musicConfig.audioUrl.isNotEmpty) {
await _audioPlayer.pause();
await _audioPlayer.seek(Duration.zero);
}
}
void seek(Duration position) async {
if (_musicConfig.audioUrl != null && _musicConfig.audioUrl.isNotEmpty) {
await _audioPlayer.seek(position);
}
}
void setVolume(double volume) async {
if (_musicConfig.audioUrl != null && _musicConfig.audioUrl.isNotEmpty) {
await _audioPlayer.setVolume(volume);
}
}
// 不需要该播放器,则需要调用该方法
void dispose() async {
await _audioPlayer.dispose();
}
}
4. まとめ
Flutter開発実践 - just_audio では、音声の再生、一時停止、音量設定などを実現します。
学習記録、日々改善を続けてください。