Flutter development practice-just_audio realizes playing audio, pausing audio, setting volume, etc.

Flutter development practice-just_audio realizes playing audio, pausing audio, setting volume, etc.

During the recent development process, I encountered the need to play background sound and other audio playback. Here, just_audio is used to play audio, pause audio, set volume, etc.

insert image description here

1. Introduce just_audio

Introduce just_audio in pubspec.yaml

  just_audio: ^2.7.0

On iOS, video_player uses AVPlayer for playback.
On Android, video_player uses ExoPlayer.

2. Setup before use

2.1 Settings in iOS
Add settings to info.plist in iOS project to support Https, HTTP video address

<key>NSAppTransportSecurity</key>
<dict>
	<key>NSAllowsArbitraryLoads</key>
	<true/>
</dict>

2.2 Settings in Android
You need to add network permissions in the /android/app/src/main/AndroidManifest.xml file

<uses-permission android:name="android.permission.INTERNET"/>

3. Just_audio realizes playing audio, pausing audio, setting volume, etc.

After introducing just_audio, AudioPlayer can be used to play audio

3.1 Commonly used operations are as follows

  • play
await _audioPlayer.play();
  • pause
await _audioPlayer.pause();
  • seek
await _audioPlayer.seek(position);
  • stop
await _audioPlayer.pause();
await _audioPlayer.seek(Duration.zero);
  • set volume
await _audioPlayer.setVolume(volume);

3.2 Use just_audio to implement player

Here, the player is used to obtain the SDAudioPlayerState state, control the pause of the audio, set the volume of the audio, and other operations

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();
  }
}

Four. Summary

Flutter development practice-just_audio realizes playing audio, pausing audio, setting volume, etc.
Learning records, keep improving every day.

Guess you like

Origin blog.csdn.net/gloryFlow/article/details/132199970