Update just audio to latest version

This commit is contained in:
stonega 2021-09-05 14:57:02 +08:00
parent f14f0f819c
commit 8a128dc6ad
4 changed files with 120 additions and 51 deletions

View File

@ -457,18 +457,10 @@ class _PlaylistWidgetState extends State<PlaylistWidget> {
children: <Widget>[ children: <Widget>[
Padding( Padding(
padding: EdgeInsets.all(10.0), padding: EdgeInsets.all(10.0),
child: ClipRRect( child: CircleAvatar(
borderRadius: radius: 15,
BorderRadius.all(Radius.circular(15.0)), backgroundImage:
child: SizedBox( episodes[index].avatarImage),
height: 30.0,
width: 30.0,
child: Image(
image: episodes[index].avatarImage)
// Image.file(File(
// "${episodes[index].imagePath}"))
),
),
), ),
Expanded( Expanded(
child: Align( child: Align(
@ -522,9 +514,9 @@ class _PlaylistWidgetState extends State<PlaylistWidget> {
borderRadius: BorderRadius.all(Radius.circular(15)), borderRadius: BorderRadius.all(Radius.circular(15)),
onTap: () { onTap: () {
audio.playNext(); audio.playNext();
miniPlaylistKey.currentState.removeItem( // miniPlaylistKey.currentState.removeItem(
0, (context, animation) => Container()); // 0, (context, animation) => Container());
miniPlaylistKey.currentState.insertItem(0); // miniPlaylistKey.currentState.insertItem(0);
}, },
child: SizedBox( child: SizedBox(
height: 30, height: 30,

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:line_icons/line_icons.dart'; import 'package:line_icons/line_icons.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -408,7 +410,9 @@ class __TopPodcastListState extends State<_TopPodcastList> {
@override @override
void initState() { void initState() {
_page = 1; _page = 1;
_searchFuture = _getTopPodcasts(genre: widget.genre, page: _page); try {
_searchFuture = _getTopPodcasts(genre: widget.genre, page: _page);
} catch (e) {}
super.initState(); super.initState();
} }

View File

@ -187,16 +187,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
final cacheMax = final cacheMax =
await cacheStorage.getInt(defaultValue: (1024 * 1024 * 200).toInt()); await cacheStorage.getInt(defaultValue: (1024 * 1024 * 200).toInt());
_audioHandler = await AudioService.init( _audioHandler = await AudioService.init(
builder: () => CustomAudioHandler(cacheMax), builder: () => CustomAudioHandler(cacheMax), config: _config);
config: AudioServiceConfig(
androidNotificationChannelName: 'Tsacdop',
androidNotificationIcon: 'drawable/ic_notification',
androidEnableQueue: true,
androidStopForegroundOnPause: true,
preloadArtwork: false,
fastForwardInterval: Duration(seconds: _fastForwardSeconds),
rewindInterval: Duration(seconds: _rewindSeconds)),
);
super.addListener(listener); super.addListener(listener);
} }
@ -208,6 +199,17 @@ class AudioPlayerNotifier extends ChangeNotifier {
super.dispose(); super.dispose();
} }
/// Audio service config
AudioServiceConfig get _config => AudioServiceConfig(
androidNotificationChannelName: 'Tsacdop',
androidNotificationIcon: 'drawable/ic_notification',
androidEnableQueue: true,
androidStopForegroundOnPause: true,
preloadArtwork: false,
fastForwardInterval: Duration(seconds: _fastForwardSeconds),
rewindInterval: Duration(seconds: _rewindSeconds),
);
/// Audio playing state. /// Audio playing state.
AudioProcessingState get audioState => _audioState; AudioProcessingState get audioState => _audioState;
int get backgroundAudioDuration => _backgroundAudioDuration; int get backgroundAudioDuration => _backgroundAudioDuration;
@ -367,8 +369,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
notifyListeners(); notifyListeners();
if (playlist.isNotEmpty) { if (playlist.isNotEmpty) {
if (playerRunning) { if (playerRunning) {
_audioHandler _audioHandler.customAction('setIsQueue', {'isQueue': playlist.isQueue});
.customAction('setIsQueue', {'isQueue': playlist.name == 'Queue'});
_audioHandler.customAction('changeQueue', { _audioHandler.customAction('changeQueue', {
'queue': [for (var e in p.episodes) e.toMediaItem()] 'queue': [for (var e in p.episodes) e.toMediaItem()]
}); });
@ -394,7 +395,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
} else { } else {
episodeNew = await _dbHelper.getRssItemWithUrl(episode.enclosureUrl); episodeNew = await _dbHelper.getRssItemWithUrl(episode.enclosureUrl);
} }
//TODO load episode from last position when player running // @TODO load episode from last position when player running
if (playerRunning) { if (playerRunning) {
if (_playFromSearchList.contains(_episode)) { if (_playFromSearchList.contains(_episode)) {
_queue.delFromPlaylist(_episode); _queue.delFromPlaylist(_episode);
@ -405,7 +406,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
} }
_queue.addToPlayListAt(episodeNew, 0); _queue.addToPlayListAt(episodeNew, 0);
await updatePlaylist(_queue, updateEpisodes: !fromSearch); await updatePlaylist(_queue, updateEpisodes: !fromSearch);
if (!_playlist.isQueue) { if (_playlist.isQueue) {
_audioHandler.customAction('setIsQueue', {'isQueue': true}); _audioHandler.customAction('setIsQueue', {'isQueue': true});
_audioHandler.customAction('changeQueue', { _audioHandler.customAction('changeQueue', {
'queue': [for (var e in _queue.episodes) e.toMediaItem()] 'queue': [for (var e in _queue.episodes) e.toMediaItem()]
@ -470,6 +471,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
await _audioHandler await _audioHandler
.addQueueItems([playlist.episodes[index].toMediaItem()]); .addQueueItems([playlist.episodes[index].toMediaItem()]);
} }
await _audioHandler.play();
//Check auto sleep timer setting //Check auto sleep timer setting
await _getAutoSleepTimer(); await _getAutoSleepTimer();
if (_autoSleepTimer) { if (_autoSleepTimer) {
@ -489,6 +492,10 @@ class AudioPlayerNotifier extends ChangeNotifier {
} }
} }
/// Set if playlist is queue.
await _audioHandler
.customAction('setIsQueue', {'isQueue': playlist.isQueue});
/// Set player speed. /// Set player speed.
if (_currentSpeed != 1.0) { if (_currentSpeed != 1.0) {
await _audioHandler.customAction('setSpeed', {'speed': _currentSpeed}); await _audioHandler.customAction('setSpeed', {'speed': _currentSpeed});
@ -559,9 +566,12 @@ class AudioPlayerNotifier extends ChangeNotifier {
_customEventSubscription = _customEventSubscription =
_audioHandler.customEvent.distinct().listen((event) async { _audioHandler.customEvent.distinct().listen((event) async {
if (event is Map && event['removePlayed'] != null) { if (event is Map && event['removePlayed'] != null) {
log(event.toString());
log(_queue.episodes.first.title);
if (_playlist.isQueue && if (_playlist.isQueue &&
_queue.isNotEmpty && _queue.isNotEmpty &&
_queue.episodes.first.title == event['removePlayed']) { _queue.episodes.first.title == event['removePlayed']) {
log(event['removePlayed']);
_queue.delFromPlaylist(_episode); _queue.delFromPlaylist(_episode);
updatePlaylist(_queue, updateEpisodes: false); updatePlaylist(_queue, updateEpisodes: false);
} }
@ -605,7 +615,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
}); });
} }
/// Queue management. /// Queue management
Future<void> addToPlaylist(EpisodeBrief episode) async { Future<void> addToPlaylist(EpisodeBrief episode) async {
var episodeNew = await _dbHelper.getRssItemWithUrl(episode.enclosureUrl); var episodeNew = await _dbHelper.getRssItemWithUrl(episode.enclosureUrl);
if (episodeNew.isNew == 1) { if (episodeNew.isNew == 1) {
@ -837,6 +847,10 @@ class AudioPlayerNotifier extends ChangeNotifier {
Future<void> playNext() async { Future<void> playNext() async {
_remoteErrorMessage = null; _remoteErrorMessage = null;
if (_playlist.isQueue && _queue.isNotEmpty) {
_queue.delFromPlaylist(_episode);
updatePlaylist(_queue, updateEpisodes: false);
}
await _audioHandler.skipToNext(); await _audioHandler.skipToNext();
notifyListeners(); notifyListeners();
} }
@ -972,6 +986,13 @@ class CustomAudioHandler extends BaseAudioHandler
int _layoutIndex; int _layoutIndex;
bool _stopAtEnd = false; bool _stopAtEnd = false;
bool _isQueue = false; bool _isQueue = false;
bool _autoSkip = true;
ConcatenatingAudioSource _playlist = ConcatenatingAudioSource(
useLazyPreparation: true,
shuffleOrder: DefaultShuffleOrder(),
children: [],
);
bool get hasNext => queue.value.length > 0; bool get hasNext => queue.value.length > 0;
MediaItem get currentMediaItem => mediaItem.value; MediaItem get currentMediaItem => mediaItem.value;
@ -984,13 +1005,13 @@ class CustomAudioHandler extends BaseAudioHandler
_handleInterruption(); _handleInterruption();
_player.currentIndexStream.listen( _player.currentIndexStream.listen(
(index) { (index) {
log(index.toString()); if (queue.value.isNotEmpty && index < queue.value.length) {
if (queue.value.isNotEmpty) {
mediaItem.add(queue.value[index]); mediaItem.add(queue.value[index]);
} }
if (_isQueue && index == 1) { if (_isQueue && _autoSkip) {
customEvent.add({'removePlayed': queue.value.first.title}); customEvent.add({'removePlayed': queue.value.first.title});
} }
_autoSkip = true;
}, },
); );
_player.playbackEventStream.listen((event) async { _player.playbackEventStream.listen((event) async {
@ -1024,25 +1045,26 @@ class CustomAudioHandler extends BaseAudioHandler
customEvent.add({'position': event}); customEvent.add({'position': event});
}); });
_player.sequenceStream.listen((event) {
log(event.toString());
});
_player.durationStream.listen((event) { _player.durationStream.listen((event) {
mediaItem.add(mediaItem.value.copyWith(duration: _player.duration)); mediaItem.add(mediaItem.value.copyWith(duration: _player.duration));
}); });
} }
@override
Future<void> addQueueItems(List<MediaItem> items) async { Future<void> addQueueItems(List<MediaItem> items) async {
super.addQueueItems(items); queue.add(items);
await _player.setAudioSource( _setAudioSource(items);
ConcatenatingAudioSource( _player.setAudioSource(_playlist);
useLazyPreparation: true, }
shuffleOrder: DefaultShuffleOrder(),
children: [ void _setAudioSource(List<MediaItem> items) {
for (var item in items) _playlist.insertAll(
ClippingAudioSource( 0,
start: Duration(seconds: item.extras['skipSecondsStart']), [for (var item in items) _itemToSource(item)],
// end: Duration(seconds: item.extras['skipSecondsEnd']),
child: AudioSource.uri(Uri.parse(item.id))),
],
),
); );
} }
@ -1102,11 +1124,13 @@ class CustomAudioHandler extends BaseAudioHandler
} }
} }
@override
Future<void> skipToNext() async { Future<void> skipToNext() async {
if (queue.value.length == 0 || _stopAtEnd) { if (queue.value.length == 0 || _stopAtEnd) {
await Future.delayed(Duration(milliseconds: 200)); await Future.delayed(Duration(milliseconds: 200));
await stop(); await stop();
} else { } else {
_autoSkip = false;
await super.skipToNext(); await super.skipToNext();
_player.seekToNext(); _player.seekToNext();
if (_isQueue && queue.value.isNotEmpty) { if (_isQueue && queue.value.isNotEmpty) {
@ -1115,10 +1139,12 @@ class CustomAudioHandler extends BaseAudioHandler
} }
} }
@override
Future<void> play() async { Future<void> play() async {
if (playing == null) { if (playing == null) {
log('playing');
await super.play(); await super.play();
_player.play(); await _player.play();
} else { } else {
super.play(); super.play();
await _player.play(); await _player.play();
@ -1126,15 +1152,24 @@ class CustomAudioHandler extends BaseAudioHandler
} }
} }
@override
Future<void> addQueueItem(MediaItem item) async {
_addQueueItemAt(item, queue.value.length);
}
@override
Future<void> removeQueueItemAt(int index) async { Future<void> removeQueueItemAt(int index) async {
queue.add(queue.value..removeAt(index)); queue.add(queue.value..removeAt(index));
_playlist.removeAt(index);
super.removeQueueItemAt(index); super.removeQueueItemAt(index);
} }
@override
Future<void> pause() async { Future<void> pause() async {
await _player.pause(); await _player.pause();
} }
@override
Future<void> seek(Duration position) async { Future<void> seek(Duration position) async {
await _player.seek(position); await _player.seek(position);
super.seek(position); super.seek(position);
@ -1186,6 +1221,7 @@ class CustomAudioHandler extends BaseAudioHandler
} }
Future<void> _addQueueItemAt(MediaItem item, int index) async { Future<void> _addQueueItemAt(MediaItem item, int index) async {
log(index.toString() + ': ' + item.toString());
if (index == 0 && _isQueue) { if (index == 0 && _isQueue) {
queue.add(queue.value..removeWhere((i) => i.id == item.id)); queue.add(queue.value..removeWhere((i) => i.id == item.id));
queue.add(queue.value..insert(index, item)); queue.add(queue.value..insert(index, item));
@ -1193,10 +1229,12 @@ class CustomAudioHandler extends BaseAudioHandler
} else { } else {
queue.add(queue.value..insert(index, item)); queue.add(queue.value..insert(index, item));
} }
_playlist.insert(index, _itemToSource(item));
} }
Future<dynamic> customAction(funtion, [argument]) async { @override
switch (funtion) { Future<dynamic> customAction(function, [argument]) async {
switch (function) {
case 'stopAtEnd': case 'stopAtEnd':
_stopAtEnd = true; _stopAtEnd = true;
break; break;
@ -1204,6 +1242,7 @@ class CustomAudioHandler extends BaseAudioHandler
_stopAtEnd = false; _stopAtEnd = false;
break; break;
case 'setSpeed': case 'setSpeed':
log('Argument' + argument['speed'].toString());
await _player.setSpeed(argument['speed']); await _player.setSpeed(argument['speed']);
break; break;
case 'setSkipSilence': case 'setSkipSilence':
@ -1213,6 +1252,7 @@ class CustomAudioHandler extends BaseAudioHandler
await _setBoostVolume(argument['boostVolume'], argument['gain']); await _setBoostVolume(argument['boostVolume'], argument['gain']);
break; break;
case 'setIsQueue': case 'setIsQueue':
log('Argument' + argument['isQueue'].toString());
_isQueue = argument['isQueue']; _isQueue = argument['isQueue'];
break; break;
case 'changeQueue': case 'changeQueue':
@ -1223,6 +1263,9 @@ class CustomAudioHandler extends BaseAudioHandler
break; break;
case 'addQueueItemAt': case 'addQueueItemAt':
await _addQueueItemAt(argument['mediaItem'], argument['index']); await _addQueueItemAt(argument['mediaItem'], argument['index']);
break;
default:
super.customAction(function, argument);
} }
} }
@ -1281,4 +1324,11 @@ class CustomAudioHandler extends BaseAudioHandler
break; break;
} }
} }
static AudioSource _itemToSource(MediaItem item) {
return ClippingAudioSource(
start: Duration(seconds: item.extras['skipSecondsStart']),
// end: Duration(seconds: item.extras['skipSecondsEnd']),
child: AudioSource.uri(Uri.parse(item.id)));
}
} }

View File

@ -19,9 +19,32 @@ class CustomCacheManager extends CacheManager with ImageCacheManager {
try { try {
file = await super file = await super
.downloadFile(url, key: key, authHeaders: authHeaders, force: force); .downloadFile(url, key: key, authHeaders: authHeaders, force: force);
} catch (e) {} } catch (e) {
rethrow;
}
return file; return file;
} }
@override
Stream<FileResponse> getImageFile(
String url, {
String key,
Map<String, String> headers,
bool withProgress = false,
int maxHeight,
int maxWidth,
}) async* {
try {
super.getImageFile(url,
key: key,
headers: headers,
withProgress: withProgress,
maxHeight: maxHeight,
maxWidth: maxWidth);
} catch (e) {
}
}
CustomCacheManager._() : super(Config(key)); CustomCacheManager._() : super(Config(key));
} }