Fixed audio player rewind fastforward issue.
This commit is contained in:
parent
1c98c0ae0f
commit
57e7bfbf3f
|
@ -2,6 +2,7 @@ import 'dart:ui';
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:line_icons/line_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
@ -12,6 +13,7 @@ import '../state/download_state.dart';
|
|||
import '../state/audio_state.dart';
|
||||
import '../state/setting_state.dart';
|
||||
import '../type/episodebrief.dart';
|
||||
import '../util/extension_helper.dart';
|
||||
import '../util/general_dialog.dart';
|
||||
|
||||
class DownloadButton extends StatefulWidget {
|
||||
|
@ -50,10 +52,6 @@ class _DownloadButtonState extends State<DownloadButton> {
|
|||
}
|
||||
if (_dataConfirm) {
|
||||
Provider.of<DownloadState>(context, listen: false).startTask(episode);
|
||||
Fluttertoast.showToast(
|
||||
msg: 'Downloading',
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,28 +64,16 @@ class _DownloadButtonState extends State<DownloadButton> {
|
|||
);
|
||||
}
|
||||
|
||||
void _pauseDownload(EpisodeBrief episode) async {
|
||||
_pauseDownload(EpisodeBrief episode) async {
|
||||
Provider.of<DownloadState>(context, listen: false).pauseTask(episode);
|
||||
Fluttertoast.showToast(
|
||||
msg: 'Download paused',
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
);
|
||||
}
|
||||
|
||||
void _resumeDownload(EpisodeBrief episode) async {
|
||||
_resumeDownload(EpisodeBrief episode) async {
|
||||
Provider.of<DownloadState>(context, listen: false).resumeTask(episode);
|
||||
Fluttertoast.showToast(
|
||||
msg: 'Download resumed',
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
);
|
||||
}
|
||||
|
||||
void _retryDownload(EpisodeBrief episode) async {
|
||||
_retryDownload(EpisodeBrief episode) async {
|
||||
Provider.of<DownloadState>(context, listen: false).retryTask(episode);
|
||||
Fluttertoast.showToast(
|
||||
msg: 'Download again',
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> _checkPermmison() async {
|
||||
|
@ -107,17 +93,18 @@ class _DownloadButtonState extends State<DownloadButton> {
|
|||
|
||||
Future<bool> _useDataConfirem() async {
|
||||
bool ifUseData = false;
|
||||
final s = context.s;
|
||||
await generalDialog(
|
||||
context,
|
||||
title: Text('Cellular data warn'),
|
||||
content: Text('Are you sure you want to use cellular data to download?'),
|
||||
title: Text(s.cellularConfirm),
|
||||
content: Text(s.cellularConfirmDes),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
'CANCEL',
|
||||
s.cancel,
|
||||
style: TextStyle(color: Colors.grey[600]),
|
||||
),
|
||||
),
|
||||
|
@ -127,7 +114,7 @@ class _DownloadButtonState extends State<DownloadButton> {
|
|||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
'CONFIRM',
|
||||
s.confirm,
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
)
|
||||
|
@ -180,7 +167,8 @@ class _DownloadButtonState extends State<DownloadButton> {
|
|||
selector: (_, settings) => settings.downloadUsingData,
|
||||
builder: (_, data, __) => _buttonOnMenu(
|
||||
Icon(
|
||||
Icons.arrow_downward,
|
||||
LineIcons.download_solid,
|
||||
//size: 15,
|
||||
color: Colors.grey[700],
|
||||
),
|
||||
() => _requestDownload(task.episode, data)),
|
||||
|
|
|
@ -89,6 +89,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||
"back" : MessageLookupByLibrary.simpleMessage("Back"),
|
||||
"buffering" : MessageLookupByLibrary.simpleMessage("Buffering"),
|
||||
"cancel" : MessageLookupByLibrary.simpleMessage("CANCEL"),
|
||||
"cellularConfirm" : MessageLookupByLibrary.simpleMessage("Cellular data warn"),
|
||||
"cellularConfirmDes" : MessageLookupByLibrary.simpleMessage("Are you sure you want to use cellular data to download?"),
|
||||
"changeLayout" : MessageLookupByLibrary.simpleMessage("Change layout"),
|
||||
"changelog" : MessageLookupByLibrary.simpleMessage("Changelog"),
|
||||
"chooseA" : MessageLookupByLibrary.simpleMessage("Choose a"),
|
||||
|
|
|
@ -89,6 +89,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||
"back" : MessageLookupByLibrary.simpleMessage("Retour"),
|
||||
"buffering" : MessageLookupByLibrary.simpleMessage("Buffering"),
|
||||
"cancel" : MessageLookupByLibrary.simpleMessage("ANNULER"),
|
||||
"cellularConfirm" : MessageLookupByLibrary.simpleMessage("Cellular data warn"),
|
||||
"cellularConfirmDes" : MessageLookupByLibrary.simpleMessage("Are you sure you want to use cellular data to download?"),
|
||||
"changeLayout" : MessageLookupByLibrary.simpleMessage("Modifier l\'interface"),
|
||||
"changelog" : MessageLookupByLibrary.simpleMessage("Historique des modifications"),
|
||||
"chooseA" : MessageLookupByLibrary.simpleMessage("Choisir un"),
|
||||
|
|
|
@ -89,6 +89,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||
"back" : MessageLookupByLibrary.simpleMessage("返回"),
|
||||
"buffering" : MessageLookupByLibrary.simpleMessage("缓冲"),
|
||||
"cancel" : MessageLookupByLibrary.simpleMessage("取消"),
|
||||
"cellularConfirm" : MessageLookupByLibrary.simpleMessage("流量确认"),
|
||||
"cellularConfirmDes" : MessageLookupByLibrary.simpleMessage("您确定使用流量下载吗"),
|
||||
"changeLayout" : MessageLookupByLibrary.simpleMessage("修改布局"),
|
||||
"changelog" : MessageLookupByLibrary.simpleMessage("更新日志"),
|
||||
"chooseA" : MessageLookupByLibrary.simpleMessage("选择"),
|
||||
|
|
|
@ -139,6 +139,26 @@ class S {
|
|||
);
|
||||
}
|
||||
|
||||
/// `Cellular data warn`
|
||||
String get cellularConfirm {
|
||||
return Intl.message(
|
||||
'Cellular data warn',
|
||||
name: 'cellularConfirm',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Are you sure you want to use cellular data to download?`
|
||||
String get cellularConfirmDes {
|
||||
return Intl.message(
|
||||
'Are you sure you want to use cellular data to download?',
|
||||
name: 'cellularConfirmDes',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Change layout`
|
||||
String get changeLayout {
|
||||
return Intl.message(
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
|||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:marquee/marquee.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
@ -1271,31 +1272,41 @@ class _ControlPanelState extends State<ControlPanel>
|
|||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
padding: EdgeInsets.symmetric(horizontal: 25.0),
|
||||
padding: EdgeInsets.symmetric(horizontal: 0),
|
||||
onPressed:
|
||||
playing ? () => audio.rewind() : null,
|
||||
iconSize: 32.0,
|
||||
icon: Icon(Icons.fast_rewind),
|
||||
color: Colors.grey[500]),
|
||||
Selector<AudioPlayerNotifier, int>(
|
||||
selector: (_, audio) => audio.rewindSeconds,
|
||||
builder: (_, seconds, __) => Text('$seconds s',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.teko(
|
||||
textStyle: TextStyle(
|
||||
color: Colors.grey[500],
|
||||
fontSize: 20),
|
||||
))),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 30),
|
||||
height: 60,
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).brightness ==
|
||||
Brightness.dark
|
||||
? Colors.black12
|
||||
: Colors.white10,
|
||||
color:
|
||||
context.brightness == Brightness.dark
|
||||
? Colors.black12
|
||||
: Colors.white10,
|
||||
width: 1),
|
||||
boxShadow: Theme.of(context).brightness ==
|
||||
Brightness.dark
|
||||
? _customShadowNight
|
||||
: _customShadow),
|
||||
boxShadow:
|
||||
context.brightness == Brightness.dark
|
||||
? _customShadowNight
|
||||
: _customShadow),
|
||||
child: playing
|
||||
? Material(
|
||||
color: Colors.transparent,
|
||||
|
@ -1333,20 +1344,29 @@ class _ControlPanelState extends State<ControlPanel>
|
|||
child: Icon(
|
||||
Icons.play_arrow,
|
||||
size: 40,
|
||||
color:
|
||||
Theme.of(context).accentColor,
|
||||
color: context.accentColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Selector<AudioPlayerNotifier, int>(
|
||||
selector: (_, audio) =>
|
||||
audio.fastForwardSeconds,
|
||||
builder: (_, seconds, __) => Text('$seconds s',
|
||||
style: GoogleFonts.teko(
|
||||
textStyle: TextStyle(
|
||||
color: Colors.grey[500],
|
||||
fontSize: 20),
|
||||
))),
|
||||
IconButton(
|
||||
padding: EdgeInsets.symmetric(horizontal: 25.0),
|
||||
onPressed:
|
||||
playing ? () => audio.fastForward() : null,
|
||||
iconSize: 32.0,
|
||||
icon: Icon(Icons.fast_forward),
|
||||
color: Colors.grey[500]),
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
onPressed:
|
||||
playing ? () => audio.fastForward() : null,
|
||||
iconSize: 32.0,
|
||||
icon: Icon(Icons.fast_forward),
|
||||
color: Colors.grey[500],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -956,9 +956,6 @@ class _RecentUpdateState extends State<_RecentUpdate>
|
|||
}),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
borderRadius:
|
||||
BorderRadius.circular(100),
|
||||
child: IconButton(
|
||||
tooltip: s.changeLayout,
|
||||
padding: EdgeInsets.zero,
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
"@buffering": {},
|
||||
"cancel": "CANCEL",
|
||||
"@cancel": {},
|
||||
"cellularConfirm": "Cellular data warn",
|
||||
"@cellularConfirm": {},
|
||||
"cellularConfirmDes": "Are you sure you want to use cellular data to download?",
|
||||
"@cellularConfirmDes": {},
|
||||
"changeLayout": "Change layout",
|
||||
"@changeLayout": {},
|
||||
"changelog": "Changelog",
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
"@buffering": {},
|
||||
"cancel": "ANNULER",
|
||||
"@cancel": {},
|
||||
"cellularConfirm": "Cellular data warn",
|
||||
"@cellularConfirm": {},
|
||||
"cellularConfirmDes": "Are you sure you want to use cellular data to download?",
|
||||
"@cellularConfirmDes": {},
|
||||
"changeLayout": "Modifier l'interface",
|
||||
"@changeLayout": {},
|
||||
"changelog": "Historique des modifications",
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
"@buffering": {},
|
||||
"cancel": "取消",
|
||||
"@cancel": {},
|
||||
"cellularConfirm": "流量确认",
|
||||
"@cellularConfirm": {},
|
||||
"cellularConfirmDes": "您确定使用流量下载吗",
|
||||
"@cellularConfirmDes": {},
|
||||
"changeLayout": "修改布局",
|
||||
"@changeLayout": {},
|
||||
"changelog": "更新日志",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
|
@ -79,10 +80,10 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
|||
bool _playing = false;
|
||||
|
||||
/// Fastforward second.
|
||||
int _fastForwardSeconds;
|
||||
int _fastForwardSeconds = 0;
|
||||
|
||||
/// Rewind seconds.
|
||||
int _rewindSeconds;
|
||||
int _rewindSeconds = 0;
|
||||
|
||||
/// No slide, set true if slide on seekbar.
|
||||
bool _noSlide = true;
|
||||
|
@ -158,6 +159,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
|||
double get currentSpeed => _currentSpeed;
|
||||
bool get episodeState => _episodeState;
|
||||
bool get autoSleepTimer => _autoSleepTimer;
|
||||
int get fastForwardSeconds => _fastForwardSeconds;
|
||||
int get rewindSeconds => _rewindSeconds;
|
||||
|
||||
set setSwitchValue(double value) {
|
||||
_switchValue = value;
|
||||
|
@ -340,38 +343,6 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
|||
}
|
||||
});
|
||||
|
||||
// AudioService.queueStream
|
||||
// .distinct()
|
||||
// .where((event) => event != null)
|
||||
// .listen((event) {
|
||||
// if (event.length == _queue.playlist.length - 1 &&
|
||||
// _audioState == AudioProcessingState.skippingToNext) {
|
||||
// if (event.length == 0 || _stopOnComplete) {
|
||||
// _queue.delFromPlaylist(_episode);
|
||||
// _lastPostion = 0;
|
||||
// notifyListeners();
|
||||
// positionStorage.saveInt(_lastPostion);
|
||||
// final PlayHistory history = PlayHistory(
|
||||
// _episode.title,
|
||||
// _episode.enclosureUrl,
|
||||
// backgroundAudioPosition / 1000,
|
||||
// seekSliderValue);
|
||||
// dbHelper.saveHistory(history);
|
||||
// } else if (event.first.id != _episode.mediaId) {
|
||||
// _lastPostion = 0;
|
||||
// notifyListeners();
|
||||
// positionStorage.saveInt(_lastPostion);
|
||||
// _queue.delFromPlaylist(_episode);
|
||||
// final PlayHistory history = PlayHistory(
|
||||
// _episode.title,
|
||||
// _episode.enclosureUrl,
|
||||
// backgroundAudioPosition / 1000,
|
||||
// seekSliderValue);
|
||||
// dbHelper.saveHistory(history);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
AudioService.playbackStateStream
|
||||
.distinct()
|
||||
.where((event) => event != null)
|
||||
|
@ -403,13 +374,12 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
|||
Timer.periodic(Duration(milliseconds: 500), (timer) {
|
||||
double s = _currentSpeed ?? 1.0;
|
||||
if (_noSlide) {
|
||||
if (_playing) {
|
||||
if (_playing && !buffering) {
|
||||
getPosition = _currentPosition +
|
||||
((DateTime.now().difference(_current).inMilliseconds) * s)
|
||||
.toInt();
|
||||
_backgroundAudioPosition = getPosition < _backgroundAudioDuration
|
||||
? getPosition
|
||||
: _backgroundAudioDuration;
|
||||
_backgroundAudioPosition =
|
||||
math.min(getPosition, _backgroundAudioDuration);
|
||||
} else
|
||||
_backgroundAudioPosition = _currentPosition ?? 0;
|
||||
|
||||
|
@ -708,7 +678,6 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
_queue.removeAt(0);
|
||||
}
|
||||
await AudioServiceBackground.setQueue(_queue);
|
||||
// }
|
||||
if (_queue.length == 0 || _stopAtEnd) {
|
||||
_skipState = null;
|
||||
onStop();
|
||||
|
@ -801,9 +770,12 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
|
||||
Future<void> _seekRelative(Duration offset) async {
|
||||
var newPosition = _audioPlayer.playbackEvent.position + offset;
|
||||
if (newPosition < Duration.zero) newPosition = Duration.zero;
|
||||
if (newPosition > mediaItem.duration) newPosition = mediaItem.duration;
|
||||
await _audioPlayer.seek(newPosition);
|
||||
print(newPosition.inSeconds);
|
||||
// if (newPosition < Duration.zero) newPosition = Duration.zero;
|
||||
// if (newPosition > mediaItem.duration) newPosition = mediaItem.duration;
|
||||
|
||||
print(newPosition.inSeconds);
|
||||
onSeekTo(newPosition);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -850,13 +822,14 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
}
|
||||
|
||||
@override
|
||||
void onFastForward() {
|
||||
_seekRelative(fastForwardInterval);
|
||||
void onFastForward() async {
|
||||
await _seekRelative(fastForwardInterval);
|
||||
print('test');
|
||||
}
|
||||
|
||||
@override
|
||||
void onRewind() {
|
||||
_seekRelative(-rewindInterval);
|
||||
void onRewind() async {
|
||||
await _seekRelative(-rewindInterval);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
Loading…
Reference in New Issue