1
0
mirror of https://github.com/stonega/tsacdop synced 2025-01-23 04:12:12 +01:00

Skip silence feature.

This commit is contained in:
stonegate 2020-08-01 15:31:18 +08:00
parent aa1c4843d3
commit 7a48df7f05
3 changed files with 128 additions and 41 deletions

View File

@ -262,6 +262,30 @@ class LastPosition extends StatelessWidget {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ 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>( FutureBuilder<PlayHistory>(
future: getPosition(episode), future: getPosition(episode),
builder: (context, snapshot) { builder: (context, snapshot) {
@ -287,15 +311,24 @@ class LastPosition extends StatelessWidget {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius:
BorderRadius.circular(100.0), BorderRadius.circular(100.0),
side: side: BorderSide(
BorderSide(color: Colors.green[700])), color: context.accentColor)),
highlightedBorderColor: Colors.green[700], highlightedBorderColor: Colors.green[700],
onPressed: () => audio.seekTo( onPressed: () => audio.seekTo(
(snapshot.data.seconds * 1000).toInt()), (snapshot.data.seconds * 1000).toInt()),
child: Row( child: Row(
children: [ children: [
Text(s.timeLastPlayed( SizedBox(
snapshot.data.seconds.toTime)), 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, width: 40,
child: Transform.rotate( child: Transform.rotate(
angle: math.pi * 0.7, angle: math.pi * 0.7,
child: Icon(Icons.brightness_2, size: 18))) child: Icon(Icons.brightness_2,
size: 18, color: context.accentColor)))
: Center(), : Center(),
) )
], ],
@ -1181,11 +1215,10 @@ class _ControlPanelState extends State<ControlPanel>
}, },
), ),
), ),
Container( SizedBox(
height: 80.0, height: 80.0,
padding: EdgeInsets.only(left: 60, right: 60),
alignment: Alignment.center,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Expanded( Expanded(
@ -1193,6 +1226,7 @@ class _ControlPanelState extends State<ControlPanel>
selector: (_, audio) => audio.episode.title, selector: (_, audio) => audio.episode.title,
builder: (_, title, __) { builder: (_, title, __) {
return Container( return Container(
padding: EdgeInsets.only(left: 60, right: 60),
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, size) { builder: (context, size) {
var span = TextSpan( var span = TextSpan(
@ -1312,7 +1346,7 @@ class _ControlPanelState extends State<ControlPanel>
width: 100, width: 100,
child: Text( child: Text(
data.item1.feedTitle, data.item1.feedTitle,
maxLines: 1, maxLines: 2,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
), ),
), ),

View File

@ -34,6 +34,8 @@ const String tapToOpenPopupMenuKey = 'tapToOpenPopupMenuKey';
const String fastForwardSecondsKey = 'fastForwardSecondsKey'; const String fastForwardSecondsKey = 'fastForwardSecondsKey';
const String rewindSecondsKey = 'rewindSecondsKey'; const String rewindSecondsKey = 'rewindSecondsKey';
const String playerHeightKey = 'playerHeightKey'; const String playerHeightKey = 'playerHeightKey';
const String speedKey = 'speedKey';
const String skipSilenceKey = 'skipSilenceKey';
class KeyValueStorage { class KeyValueStorage {
final String key; final String key;
@ -101,9 +103,10 @@ class KeyValueStorage {
return prefs.getString(key); return prefs.getString(key);
} }
saveMenu(List<int> list) async { Future<bool> saveMenu(List<int> list) async {
var prefs = await SharedPreferences.getInstance(); 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 { 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 /// 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(); 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);
} }
} }

View File

@ -64,6 +64,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
var fastForwardSecondsStorage = KeyValueStorage(fastForwardSecondsKey); var fastForwardSecondsStorage = KeyValueStorage(fastForwardSecondsKey);
var rewindSecondsStorage = KeyValueStorage(rewindSecondsKey); var rewindSecondsStorage = KeyValueStorage(rewindSecondsKey);
var playerHeightStorage = KeyValueStorage(playerHeightKey); var playerHeightStorage = KeyValueStorage(playerHeightKey);
var speedStorage = KeyValueStorage(speedKey);
var skipSilenceStorage = KeyValueStorage(skipSilenceKey);
/// Current playing episdoe. /// Current playing episdoe.
EpisodeBrief _episode; EpisodeBrief _episode;
@ -137,18 +139,24 @@ class AudioPlayerNotifier extends ChangeNotifier {
/// Current speed. /// Current speed.
double _currentSpeed = 1; double _currentSpeed = 1;
//Update episode card when setting changed ///Update episode card when setting changed
bool _episodeState = false; bool _episodeState = false;
/// Player height. /// Player height.
PlayerHeight _playerHeight; PlayerHeight _playerHeight;
/// Player skip silence.
bool _skipSilence;
// ignore: prefer_final_fields
bool _playerRunning = false;
AudioProcessingState get audioState => _audioState; AudioProcessingState get audioState => _audioState;
int get backgroundAudioDuration => _backgroundAudioDuration; int get backgroundAudioDuration => _backgroundAudioDuration;
int get backgroundAudioPosition => _backgroundAudioPosition; int get backgroundAudioPosition => _backgroundAudioPosition;
double get seekSliderValue => _seekSliderValue; double get seekSliderValue => _seekSliderValue;
String get remoteErrorMessage => _remoteErrorMessage; String get remoteErrorMessage => _remoteErrorMessage;
bool get playerRunning => _audioState != AudioProcessingState.none; bool get playerRunning => _playerRunning;
bool get buffering => _audioState != AudioProcessingState.ready; bool get buffering => _audioState != AudioProcessingState.ready;
int get lastPositin => _lastPostion; int get lastPositin => _lastPostion;
Playlist get queue => _queue; Playlist get queue => _queue;
@ -166,6 +174,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
int get fastForwardSeconds => _fastForwardSeconds; int get fastForwardSeconds => _fastForwardSeconds;
int get rewindSeconds => _rewindSeconds; int get rewindSeconds => _rewindSeconds;
PlayerHeight get playerHeight => _playerHeight; PlayerHeight get playerHeight => _playerHeight;
bool get skipSilence => _skipSilence;
set setSwitchValue(double value) { set setSwitchValue(double value) {
_switchValue = value; _switchValue = value;
@ -183,9 +192,11 @@ class AudioPlayerNotifier extends ChangeNotifier {
_savePlayerHeight(); _savePlayerHeight();
} }
Future _getPlayerHeight() async { Future _initAudioData() async {
var index = await playerHeightStorage.getInt(defaultValue: 0); var index = await playerHeightStorage.getInt(defaultValue: 0);
_playerHeight = PlayerHeight.values[index]; _playerHeight = PlayerHeight.values[index];
_currentSpeed = await speedStorage.getDoubel(defaultValue: 1.0);
_skipSilence = await skipSilenceStorage.getBool(defaultValue: false);
} }
Future _savePlayerHeight() async { Future _savePlayerHeight() async {
@ -210,9 +221,9 @@ class AudioPlayerNotifier extends ChangeNotifier {
@override @override
void addListener(VoidCallback listener) { void addListener(VoidCallback listener) {
super.addListener(listener); super.addListener(listener);
_getPlayerHeight(); _initAudioData();
_queueUpdate = false; // _queueUpdate = false;
_getAutoSleepTimer(); // _getAutoSleepTimer();
AudioService.connect(); AudioService.connect();
var running = AudioService.running; var running = AudioService.running;
if (running) {} if (running) {}
@ -257,7 +268,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
_backgroundAudioPosition = 0; _backgroundAudioPosition = 0;
_seekSliderValue = 0; _seekSliderValue = 0;
_episode = episodeNew; _episode = episodeNew;
_audioState = AudioProcessingState.connecting; _playerRunning = true;
notifyListeners(); notifyListeners();
//await _queue.savePlaylist(); //await _queue.savePlaylist();
_startAudioService(startPosition, episodeNew.enclosureUrl); _startAudioService(startPosition, episodeNew.enclosureUrl);
@ -270,6 +281,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
_startAudioService(int position, String url) async { _startAudioService(int position, String url) async {
_stopOnComplete = false; _stopOnComplete = false;
_sleepTimerMode = SleepTimerMode.undefined; _sleepTimerMode = SleepTimerMode.undefined;
_switchValue = 0;
/// Connect to audio service. /// Connect to audio service.
if (!AudioService.connected) { if (!AudioService.connected) {
@ -319,7 +331,12 @@ class AudioPlayerNotifier extends ChangeNotifier {
sleepTimer(defaultTimer); sleepTimer(defaultTimer);
} }
} }
if (_currentSpeed != 1.0) {
await AudioService.customAction('setSpeed', _currentSpeed);
}
if (_skipSilence) {
await AudioService.customAction('setSkipSilence', skipSilence);
}
await AudioService.play(); await AudioService.play();
AudioService.currentMediaItemStream AudioService.currentMediaItemStream
@ -343,24 +360,6 @@ class AudioPlayerNotifier extends ChangeNotifier {
AudioService.skipToNext(); 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 AudioService.playbackStateStream
.distinct() .distinct()
.where((event) => event != null) .where((event) => event != null)
@ -387,6 +386,23 @@ class AudioPlayerNotifier extends ChangeNotifier {
notifyListeners(); 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; //double s = _currentSpeed ?? 1.0;
var getPosition = 0; var getPosition = 0;
Timer.periodic(Duration(milliseconds: 500), (timer) { Timer.periodic(Duration(milliseconds: 500), (timer) {
@ -431,7 +447,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
_seekSliderValue = 0; _seekSliderValue = 0;
_episode = _queue.playlist.first; _episode = _queue.playlist.first;
_queueUpdate = !_queueUpdate; _queueUpdate = !_queueUpdate;
_audioState = AudioProcessingState.connecting; _audioState = AudioProcessingState.none;
_playerRunning = true;
notifyListeners(); notifyListeners();
_startAudioService(_lastPostion ?? 0, _queue.playlist.first.enclosureUrl); _startAudioService(_lastPostion ?? 0, _queue.playlist.first.enclosureUrl);
} }
@ -554,9 +571,18 @@ class AudioPlayerNotifier extends ChangeNotifier {
} }
} }
/// Set player speed.
setSpeed(double speed) async { setSpeed(double speed) async {
await AudioService.customAction('setSpeed', speed); await AudioService.customAction('setSpeed', speed);
_currentSpeed = 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(); notifyListeners();
} }
@ -819,6 +845,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
_playerStateSubscription.cancel(); _playerStateSubscription.cancel();
_eventSubscription.cancel(); _eventSubscription.cancel();
await _setState(processingState: AudioProcessingState.none); await _setState(processingState: AudioProcessingState.none);
AudioServiceBackground.sendCustomEvent({'playerRunning': false});
await super.onStop(); await super.onStop();
} }
@ -857,7 +884,6 @@ class AudioPlayerTask extends BackgroundAudioTask {
@override @override
void onFastForward() async { void onFastForward() async {
await _seekRelative(fastForwardInterval); await _seekRelative(fastForwardInterval);
print('test');
} }
@override @override
@ -919,9 +945,18 @@ class AudioPlayerTask extends BackgroundAudioTask {
case 'setSpeed': case 'setSpeed':
await _audioPlayer.setSpeed(argument); await _audioPlayer.setSpeed(argument);
break; 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({ Future<void> _setState({
AudioProcessingState processingState, AudioProcessingState processingState,
Duration position, Duration position,