- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 flutter 中使用 audioplayers
库,我试图保存和恢复播放器位置,除了从第一个位置播放,就像缓存播放器搜索栏位置一样,在这段代码中,我尝试使用 SharedPreference
保存和恢复它,但我的实现不成功
class ApplicationSettings {
ApplicationSettings(StreamingSharedPreferences preferences)
: showIntro = preferences.getBool('showIntro', defaultValue: false),
pageViewIndex = preferences.getInt('pageViewIndex', defaultValue: 0),
audioPosition = preferences.getString('audioPosition', defaultValue: "{}")
;
final Preference<bool> showIntro;
final Preference<int> pageViewIndex;
final Preference<String> audioPosition;
}
AudioInformation
类:
part'audio_information.g.dart';
@JsonSerializable(nullable: true)
class AudioInformation {
final String productName;
final int audioPosition;
AudioInformation(this.productName, this.audioPosition);
factory AudioInformation.fromJson(Map<String, dynamic> json) => _$AudioInformationFromJson(json);
Map<String, dynamic> toJson() => _$AudioInformationToJson(this);
}
PlayerWidget
类:
enum PlayerState { stopped, playing, paused }
enum PlayingRouteState { speakers, earpiece }
class PlayerWidget extends StatefulWidget {
final String url;
final PlayerMode mode;
final String productName;
final String imageUrl;
PlayerWidget({Key key, @required this.url, this.mode = PlayerMode.MEDIA_PLAYER, @required this.productName, @required this.imageUrl}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _PlayerWidgetState(url, mode);
}
}
class _PlayerWidgetState extends State<PlayerWidget> {
_PlayerWidgetState(this.url, this.mode);
String url;
PlayerMode mode;
AudioPlayer _audioPlayer;
Duration _duration;
Duration _position;
PlayerState _playerState = PlayerState.stopped;
PlayingRouteState _playingRouteState = PlayingRouteState.speakers;
StreamSubscription _durationSubscription;
StreamSubscription _positionSubscription;
StreamSubscription _playerCompleteSubscription;
StreamSubscription _playerErrorSubscription;
StreamSubscription _playerStateSubscription;
StreamSubscription<PlayerControlCommand> _playerControlCommandSubscription;
get _isPlaying => _playerState == PlayerState.playing;
get _isPaused => _playerState == PlayerState.paused;
get _durationText => _duration?.toString()?.split('.')?.first ?? '';
get _positionText => _position?.toString()?.split('.')?.first ?? '';
Preference<String> _audioPosition;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_audioPosition = Provider.of<ApplicationSettings>(context).audioPosition;
}
@override
void initState() {
super.initState();
_initAudioPlayer();
_play();
}
@override
void dispose() {
_audioPlayer.dispose();
_durationSubscription?.cancel();
_positionSubscription?.cancel();
_playerCompleteSubscription?.cancel();
_playerErrorSubscription?.cancel();
_playerStateSubscription?.cancel();
_playerControlCommandSubscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return PreferenceBuilder(
preference: _audioPosition,
builder: (context, String audioDetail) {
/* SAVE position*/
AudioInformation _audio = AudioInformation('${widget.productName}', _duration?.inMilliseconds?.round()??0);
_audioPosition.setValue(_audio.toJson().toString());
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.audiotrack_outlined),
Expanded(
child: Text(
' - ${widget.productName}',
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
],
),
),
body: Stack(
children: [
Positioned.fill(
child: CachedNetworkImage(
imageUrl: widget.imageUrl,
fit: BoxFit.cover,
)),
Container(
width: double.infinity,
height: double.infinity,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0),
child: Container(
color: Colors.white.withOpacity(0.7),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.all(16.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(11.0),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.2), offset: Offset(0.0, 0.0), spreadRadius: 1.0)],
border: Border.all(color: Colors.black)),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: CachedNetworkImage(
imageUrl: '${widget.imageUrl}',
fit: BoxFit.cover,
width: 150.0,
),
),
),
Container(
margin: EdgeInsets.all(8.0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(color: Colors.white.withOpacity(0.5), border: Border.all(color: Colors.black), borderRadius: BorderRadius.circular(5.0)),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
key: Key('play_button'),
onPressed: _isPlaying ? null : () => _play(),
iconSize: 64.0,
icon: Icon(MdiIcons.playCircle),
color: Colors.black,
),
IconButton(
key: Key('pause_button'),
onPressed: _isPlaying ? () => _pause() : null,
iconSize: 64.0,
icon: Icon(MdiIcons.pauseCircle),
color: Colors.green[900],
),
IconButton(
key: Key('stop_button'),
onPressed: _isPlaying || _isPaused ? () => _stop() : null,
iconSize: 64.0,
icon: Icon(MdiIcons.stopCircle),
color: Colors.indigo[700],
),
],
),
Slider(
onChanged: (v) {
final position = v * _duration.inMilliseconds;
_audioPlayer.seek(Duration(milliseconds: position.round()));
/* SAVE position*/
AudioInformation _audio = AudioInformation('${widget.productName}', position.round());
_audioPosition.setValue(_audio.toJson().toString());
},
value: (_position != null && _duration != null && _position.inMilliseconds > 0 && _position.inMilliseconds < _duration.inMilliseconds)
? _position.inMilliseconds / _duration.inMilliseconds
: 0.0,
),
],
),
),
_durationText != null && _durationText.toString().isNotEmpty
? Container(
height: 43.0,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(color: Colors.white.withOpacity(0.5), border: Border.all(color: Colors.black), borderRadius: BorderRadius.circular(5.0)),
child: Text(
_position != null
? '${_positionText ?? ''} / ${_durationText ?? ''}'
: _duration != null
? _durationText
: ' --- ',
style: TextStyle(fontSize: 24.0),
),
)
: Container(
height: 43.0,
),
],
),
],
),
);
});
}
void _initAudioPlayer() {
_audioPlayer = AudioPlayer(mode: mode);
_durationSubscription = _audioPlayer.onDurationChanged.listen((duration) {
setState(() => _duration = duration);
});
_positionSubscription = _audioPlayer.onAudioPositionChanged.listen((p) => setState(() {
_position = p;
}));
_playerCompleteSubscription = _audioPlayer.onPlayerCompletion.listen((event) {
_onComplete();
setState(() {
_position = _duration;
});
});
_playerErrorSubscription = _audioPlayer.onPlayerError.listen((msg) {
print('audioPlayer error : $msg');
setState(() {
_playerState = PlayerState.stopped;
_duration = Duration(seconds: 0);
_position = Duration(seconds: 0);
});
});
_playerControlCommandSubscription = _audioPlayer.onPlayerCommand.listen((command) {
print('command');
});
_audioPlayer.onPlayerStateChanged.listen((state) {
if (!mounted) return;
});
_audioPlayer.onNotificationPlayerStateChanged.listen((state) {
if (!mounted) return;
//setState(() => _audioPlayerState = state);
});
_playingRouteState = PlayingRouteState.speakers;
}
Future<int> _play() async {
final playPosition = (_position != null && _duration != null && _position.inMilliseconds > 0 && _position.inMilliseconds < _duration.inMilliseconds) ? _position : null;
final result = await _audioPlayer.play(url, position: playPosition);
if (result == 1) setState(() => _playerState = PlayerState.playing);
_audioPlayer.setPlaybackRate(playbackRate: 1.0);
/* RESTORE position*/
if (_audioPosition?.getValue() != null) {
final _res = jsonDecode(_audioPosition.getValue());
int pos = _audioPosition.getValue() == '{}' ? 0 : _res['audioPosition'];
_audioPlayer.seek(Duration(milliseconds: pos));
}
return result;
}
Future<int> _pause() async {
final result = await _audioPlayer.pause();
if (result == 1) setState(() => _playerState = PlayerState.paused);
return result;
}
Future<int> _stop() async {
final result = await _audioPlayer.stop();
if (result == 1) {
setState(() {
_playerState = PlayerState.stopped;
_position = Duration();
});
}
return result;
}
void _onComplete() {
setState(() => _playerState = PlayerState.stopped);
}
}
最佳答案
在 PreferenceBuilder widget 中,您应该删除第一个“Save Position”代码,当 widget 第一次构建时,脚手架返回之前的那两行代码用零值覆盖保存的音频位置的值,这是因为第一次构建小部件时,持续时间为 null。在 sharedpreference 中保存音频位置的更好位置是在
_audioplayer.onAudioPositionChanged()
功能在
_initAudioPlayer()
函数。您可以查看下面的代码片段以了解我在说什么
AudioInformation _audio = AudioInformation('${widget.productName}', p?.inMilliseconds?.round() ?? 0);
_audioPosition.setValue(_audio.toJson().toString());
setState(() {
_position = p;
});
});
这应该可以解决您面临的问题
关于Flutter 保存并恢复 AudioPlayer 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65145783/
当我在 iOS 上测试它时,它工作正常,但是当我尝试在 XCode 上存档时,它给出以下错误: Module 'audioplayers' not found 我使用audioplayers 0.13
我想使用 quiver async 中的节拍器类和 audioplayers 包在 Flutter 中编写一个节拍器应用程序。但是,音频播放器发出的咔嗒声总是延迟播放。有时会有几个小节没有声音,然后是
我将程序的文本复制到另一台计算机,但导入 sun.audio.AudioPlayer 时出现问题类(class)。编译器在导入字符串下划线,当我将鼠标放在它上面时,有这段文字,我不太明白: Acces
我在MATLAB中使用sound()函数生成音调。以下功能会以440Hz的频率播放4秒钟的声音: duration = 4 toneFreq = 440 samplesPerSecond = 4410
我在 flutter 中使用 audioplayers 库,我试图保存和恢复播放器位置,除了从第一个位置播放,就像缓存播放器搜索栏位置一样,在这段代码中,我尝试使用 SharedPreference
我是Flutter的初学者。 我正在使用Audioplayers Flutter库来播放assets/sounds/my_sound.mp3中的素材声音。我正在这样使用AudioCache: Audi
我正在尝试使用 audioplayers flutter 插件在以下链接播放广播 https://video2b.vixtream.net/radio/v/fbcfm 我尝试设置网址,但这不起作用。
我如何可以多次播放同一音频文件,而不是循环播放,但我希望能够精确地播放多少次,所以我遵循此tutorial进行了基础(即播放/暂停功能)。我正在为其余的工作而苦苦挣扎。 我使用了audioplayer
为什么以下代码对我不起作用? :S AudioPlayer.player.start(file1); while(AudioPlayer.player.isAlive()) {} AudioPlaye
我发现使用 AVFoundation 可以直接播放单轨道,但在查看苹果指南后,我似乎无法播放多首轨道。我做这项工作哪里出错了?下面的 queuePlayer 是 AVQueuePlayer 的实例,据
这里有点不知所措。我正在使用 Xcode 7 和 Swift 2,我正在尝试寻找实际有效的流式音频示例。 本质上我希望能够流式传输,但我也试过这个:Swift Radio Streaming AVPl
我在我的应用程序中使用包 flutter 音频播放器来播放来自谷歌云 tts 的音频。 它在 iOS 模拟器上运行良好,但是当我构建 apk 时出现以下错误: e: /Users/josuha/Doc
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 8年前关闭。 Improve this questi
import javax.swing.*; import sun.audio.*; import java.awt.event.*; import java.io.*; public class So
我正在尝试使用 flutter 的音频播放器库播放简单的声音。当我尝试这样做时,出现了无法加载 Assets 错误。我已经在这个站点上查看了几个相关问题,所有这些问题似乎都只建议检查 pubspec.
在我的 swing 应用程序中,我使用类在单击鼠标时播放声音。我遇到的问题是,当我调用类(class)时,声音只播放一次,而当突然单击另一个按钮时,它不会播放声音。我尝试在我的代码中延迟,但 id 仍
import javax.swing.*; import sun.audio.*; import java.awt.event.*; import java.io.*; public class So
我正在使用以下代码将声音文件播放两次。第二个声音在第一个声音之后立即播放 是否可以在它们之间留出时间间隔(1 秒)?我试图通过阅读 Apple Docs 找到解决方案 var letterSound:
我有一个在 AVAudioPlayer 中播放的主菜单声音文件。 我想创建一个选项按钮,将我带到另一个 View Controller 。当我单击开关以选择“关闭”主菜单声音时。如何停止播放音频? 如
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我是一名优秀的程序员,十分优秀!