mirror of
https://github.com/stonega/tsacdop
synced 2025-01-05 19:47:56 +01:00
Skip silence feature.
This commit is contained in:
parent
aa1c4843d3
commit
7a48df7f05
@ -262,6 +262,30 @@ class LastPosition extends StatelessWidget {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Selector<AudioPlayerNotifier, bool>(
|
||||
selector: (_, audio) => audio.skipSilence,
|
||||
builder: (_, data, __) => FlatButton(
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.flash_on, size: 18),
|
||||
SizedBox(width: 5),
|
||||
Text(s.skipSilence),
|
||||
],
|
||||
),
|
||||
color: data ? context.accentColor : Colors.transparent,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100.0),
|
||||
side: BorderSide(
|
||||
color: data
|
||||
? context.accentColor
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface
|
||||
.withOpacity(0.12))),
|
||||
textColor: data ? Colors.white : null,
|
||||
onPressed: () => audio.setSkipSilence(skipSilence: !data))),
|
||||
SizedBox(width: 10),
|
||||
FutureBuilder<PlayHistory>(
|
||||
future: getPosition(episode),
|
||||
builder: (context, snapshot) {
|
||||
@ -287,15 +311,24 @@ class LastPosition extends StatelessWidget {
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(100.0),
|
||||
side:
|
||||
BorderSide(color: Colors.green[700])),
|
||||
side: BorderSide(
|
||||
color: context.accentColor)),
|
||||
highlightedBorderColor: Colors.green[700],
|
||||
onPressed: () => audio.seekTo(
|
||||
(snapshot.data.seconds * 1000).toInt()),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(s.timeLastPlayed(
|
||||
snapshot.data.seconds.toTime)),
|
||||
SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CustomPaint(
|
||||
painter: ListenedPainter(
|
||||
context.textColor,
|
||||
stroke: 2.0),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Text(snapshot.data.seconds.toTime),
|
||||
],
|
||||
),
|
||||
)
|
||||
@ -309,7 +342,8 @@ class LastPosition extends StatelessWidget {
|
||||
width: 40,
|
||||
child: Transform.rotate(
|
||||
angle: math.pi * 0.7,
|
||||
child: Icon(Icons.brightness_2, size: 18)))
|
||||
child: Icon(Icons.brightness_2,
|
||||
size: 18, color: context.accentColor)))
|
||||
: Center(),
|
||||
)
|
||||
],
|
||||
@ -1181,11 +1215,10 @@ class _ControlPanelState extends State<ControlPanel>
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
SizedBox(
|
||||
height: 80.0,
|
||||
padding: EdgeInsets.only(left: 60, right: 60),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Expanded(
|
||||
@ -1193,6 +1226,7 @@ class _ControlPanelState extends State<ControlPanel>
|
||||
selector: (_, audio) => audio.episode.title,
|
||||
builder: (_, title, __) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 60, right: 60),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, size) {
|
||||
var span = TextSpan(
|
||||
@ -1312,7 +1346,7 @@ class _ControlPanelState extends State<ControlPanel>
|
||||
width: 100,
|
||||
child: Text(
|
||||
data.item1.feedTitle,
|
||||
maxLines: 1,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.fade,
|
||||
),
|
||||
),
|
||||
|
@ -34,6 +34,8 @@ const String tapToOpenPopupMenuKey = 'tapToOpenPopupMenuKey';
|
||||
const String fastForwardSecondsKey = 'fastForwardSecondsKey';
|
||||
const String rewindSecondsKey = 'rewindSecondsKey';
|
||||
const String playerHeightKey = 'playerHeightKey';
|
||||
const String speedKey = 'speedKey';
|
||||
const String skipSilenceKey = 'skipSilenceKey';
|
||||
|
||||
class KeyValueStorage {
|
||||
final String key;
|
||||
@ -101,9 +103,10 @@ class KeyValueStorage {
|
||||
return prefs.getString(key);
|
||||
}
|
||||
|
||||
saveMenu(List<int> list) async {
|
||||
Future<bool> saveMenu(List<int> list) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setStringList(key, list.map((e) => e.toString()).toList());
|
||||
return await prefs.setStringList(
|
||||
key, list.map((e) => e.toString()).toList());
|
||||
}
|
||||
|
||||
Future<List<int>> getMenu() async {
|
||||
@ -129,8 +132,23 @@ class KeyValueStorage {
|
||||
}
|
||||
|
||||
/// Rreverse is used for compatite bool value save before which set true = 0, false = 1
|
||||
saveBool(boo, {reverse = false}) async {
|
||||
Future<bool> saveBool(boo, {reverse = false}) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
reverse ? prefs.setInt(key, boo ? 0 : 1) : prefs.setInt(key, boo ? 1 : 0);
|
||||
return reverse
|
||||
? prefs.setInt(key, boo ? 0 : 1)
|
||||
: prefs.setInt(key, boo ? 1 : 0);
|
||||
}
|
||||
|
||||
Future<bool> saveDouble(double data) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
return prefs.setDouble(key, data);
|
||||
}
|
||||
|
||||
Future<double> getDoubel({double defaultValue = 0.0}) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
if (prefs.getDouble(key) == null) {
|
||||
await prefs.setDouble(key, defaultValue);
|
||||
}
|
||||
return prefs.getDouble(key);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
var fastForwardSecondsStorage = KeyValueStorage(fastForwardSecondsKey);
|
||||
var rewindSecondsStorage = KeyValueStorage(rewindSecondsKey);
|
||||
var playerHeightStorage = KeyValueStorage(playerHeightKey);
|
||||
var speedStorage = KeyValueStorage(speedKey);
|
||||
var skipSilenceStorage = KeyValueStorage(skipSilenceKey);
|
||||
|
||||
/// Current playing episdoe.
|
||||
EpisodeBrief _episode;
|
||||
@ -137,18 +139,24 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
/// Current speed.
|
||||
double _currentSpeed = 1;
|
||||
|
||||
//Update episode card when setting changed
|
||||
///Update episode card when setting changed
|
||||
bool _episodeState = false;
|
||||
|
||||
/// Player height.
|
||||
PlayerHeight _playerHeight;
|
||||
|
||||
/// Player skip silence.
|
||||
bool _skipSilence;
|
||||
|
||||
// ignore: prefer_final_fields
|
||||
bool _playerRunning = false;
|
||||
|
||||
AudioProcessingState get audioState => _audioState;
|
||||
int get backgroundAudioDuration => _backgroundAudioDuration;
|
||||
int get backgroundAudioPosition => _backgroundAudioPosition;
|
||||
double get seekSliderValue => _seekSliderValue;
|
||||
String get remoteErrorMessage => _remoteErrorMessage;
|
||||
bool get playerRunning => _audioState != AudioProcessingState.none;
|
||||
bool get playerRunning => _playerRunning;
|
||||
bool get buffering => _audioState != AudioProcessingState.ready;
|
||||
int get lastPositin => _lastPostion;
|
||||
Playlist get queue => _queue;
|
||||
@ -166,6 +174,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
int get fastForwardSeconds => _fastForwardSeconds;
|
||||
int get rewindSeconds => _rewindSeconds;
|
||||
PlayerHeight get playerHeight => _playerHeight;
|
||||
bool get skipSilence => _skipSilence;
|
||||
|
||||
set setSwitchValue(double value) {
|
||||
_switchValue = value;
|
||||
@ -183,9 +192,11 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
_savePlayerHeight();
|
||||
}
|
||||
|
||||
Future _getPlayerHeight() async {
|
||||
Future _initAudioData() async {
|
||||
var index = await playerHeightStorage.getInt(defaultValue: 0);
|
||||
_playerHeight = PlayerHeight.values[index];
|
||||
_currentSpeed = await speedStorage.getDoubel(defaultValue: 1.0);
|
||||
_skipSilence = await skipSilenceStorage.getBool(defaultValue: false);
|
||||
}
|
||||
|
||||
Future _savePlayerHeight() async {
|
||||
@ -210,9 +221,9 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
@override
|
||||
void addListener(VoidCallback listener) {
|
||||
super.addListener(listener);
|
||||
_getPlayerHeight();
|
||||
_queueUpdate = false;
|
||||
_getAutoSleepTimer();
|
||||
_initAudioData();
|
||||
// _queueUpdate = false;
|
||||
// _getAutoSleepTimer();
|
||||
AudioService.connect();
|
||||
var running = AudioService.running;
|
||||
if (running) {}
|
||||
@ -257,7 +268,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
_backgroundAudioPosition = 0;
|
||||
_seekSliderValue = 0;
|
||||
_episode = episodeNew;
|
||||
_audioState = AudioProcessingState.connecting;
|
||||
_playerRunning = true;
|
||||
notifyListeners();
|
||||
//await _queue.savePlaylist();
|
||||
_startAudioService(startPosition, episodeNew.enclosureUrl);
|
||||
@ -270,6 +281,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
_startAudioService(int position, String url) async {
|
||||
_stopOnComplete = false;
|
||||
_sleepTimerMode = SleepTimerMode.undefined;
|
||||
_switchValue = 0;
|
||||
|
||||
/// Connect to audio service.
|
||||
if (!AudioService.connected) {
|
||||
@ -319,7 +331,12 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
sleepTimer(defaultTimer);
|
||||
}
|
||||
}
|
||||
|
||||
if (_currentSpeed != 1.0) {
|
||||
await AudioService.customAction('setSpeed', _currentSpeed);
|
||||
}
|
||||
if (_skipSilence) {
|
||||
await AudioService.customAction('setSkipSilence', skipSilence);
|
||||
}
|
||||
await AudioService.play();
|
||||
|
||||
AudioService.currentMediaItemStream
|
||||
@ -343,24 +360,6 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
AudioService.skipToNext();
|
||||
}
|
||||
});
|
||||
|
||||
// queueSubject = BehaviorSubject<List<MediaItem>>();
|
||||
// queueSubject.addStream(
|
||||
// AudioService.queueStream.distinct().where((event) => event != null));
|
||||
//queueSubject.stream.
|
||||
AudioService.customEventStream.distinct().listen((event) async {
|
||||
if (event is String && _episode.title == event) {
|
||||
print(event);
|
||||
_queue.delFromPlaylist(_episode);
|
||||
_lastPostion = 0;
|
||||
notifyListeners();
|
||||
await positionStorage.saveInt(_lastPostion);
|
||||
final history = PlayHistory(_episode.title, _episode.enclosureUrl,
|
||||
backgroundAudioPosition ~/ 1000, seekSliderValue);
|
||||
dbHelper.saveHistory(history);
|
||||
}
|
||||
});
|
||||
|
||||
AudioService.playbackStateStream
|
||||
.distinct()
|
||||
.where((event) => event != null)
|
||||
@ -387,6 +386,23 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
});
|
||||
|
||||
AudioService.customEventStream.distinct().listen((event) async {
|
||||
if (event is String && _episode.title == event) {
|
||||
print(event);
|
||||
_queue.delFromPlaylist(_episode);
|
||||
_lastPostion = 0;
|
||||
notifyListeners();
|
||||
await positionStorage.saveInt(_lastPostion);
|
||||
final history = PlayHistory(_episode.title, _episode.enclosureUrl,
|
||||
backgroundAudioPosition ~/ 1000, seekSliderValue);
|
||||
dbHelper.saveHistory(history);
|
||||
}
|
||||
if (event is Map && event['playerRunning'] == false) {
|
||||
_playerRunning = false;
|
||||
notifyListeners();
|
||||
}
|
||||
});
|
||||
|
||||
//double s = _currentSpeed ?? 1.0;
|
||||
var getPosition = 0;
|
||||
Timer.periodic(Duration(milliseconds: 500), (timer) {
|
||||
@ -431,7 +447,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
_seekSliderValue = 0;
|
||||
_episode = _queue.playlist.first;
|
||||
_queueUpdate = !_queueUpdate;
|
||||
_audioState = AudioProcessingState.connecting;
|
||||
_audioState = AudioProcessingState.none;
|
||||
_playerRunning = true;
|
||||
notifyListeners();
|
||||
_startAudioService(_lastPostion ?? 0, _queue.playlist.first.enclosureUrl);
|
||||
}
|
||||
@ -554,9 +571,18 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set player speed.
|
||||
setSpeed(double speed) async {
|
||||
await AudioService.customAction('setSpeed', speed);
|
||||
_currentSpeed = speed;
|
||||
await speedStorage.saveDouble(_currentSpeed);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setSkipSilence({@required bool skipSilence}) async {
|
||||
await AudioService.customAction('setSkipSilence', skipSilence);
|
||||
_skipSilence = skipSilence;
|
||||
await skipSilenceStorage.saveBool(_skipSilence);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -819,6 +845,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||
_playerStateSubscription.cancel();
|
||||
_eventSubscription.cancel();
|
||||
await _setState(processingState: AudioProcessingState.none);
|
||||
AudioServiceBackground.sendCustomEvent({'playerRunning': false});
|
||||
await super.onStop();
|
||||
}
|
||||
|
||||
@ -857,7 +884,6 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||
@override
|
||||
void onFastForward() async {
|
||||
await _seekRelative(fastForwardInterval);
|
||||
print('test');
|
||||
}
|
||||
|
||||
@override
|
||||
@ -919,9 +945,18 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||
case 'setSpeed':
|
||||
await _audioPlayer.setSpeed(argument);
|
||||
break;
|
||||
case 'setSkipSilence':
|
||||
await _setSkipSilence(argument);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future _setSkipSilence(bool boo) async {
|
||||
await _audioPlayer.setSkipSilence(boo);
|
||||
var duration = await _audioPlayer.durationFuture ?? Duration.zero;
|
||||
AudioServiceBackground.setMediaItem(mediaItem.copyWith(duration: duration));
|
||||
}
|
||||
|
||||
Future<void> _setState({
|
||||
AudioProcessingState processingState,
|
||||
Duration position,
|
||||
|
Loading…
Reference in New Issue
Block a user