Flutter開発実践 - just_audio では、音声の再生、一時停止、音量設定などを実現します。

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 では、音声の再生、一時停止、音量設定などを実現します。
学習記録、日々改善を続けてください。

おすすめ

転載: blog.csdn.net/gloryFlow/article/details/132199970