Unify web player controls and add volume control
This commit is contained in:
@@ -42,6 +42,7 @@ class _PlayerPageState extends State<PlayerPage> {
|
||||
bool _isRefreshing = false;
|
||||
bool _isFullscreen = false;
|
||||
bool _controlsVisible = true;
|
||||
double _volume = kIsWeb ? 0.0 : 1.0;
|
||||
int _playerVersion = 0;
|
||||
String _selectedResolution = 'Source';
|
||||
List<String> _availableResolutions = const ['Source'];
|
||||
@@ -63,6 +64,7 @@ class _PlayerPageState extends State<PlayerPage> {
|
||||
_controller = VideoPlayerController.networkUrl(Uri.parse(playbackUrl));
|
||||
try {
|
||||
await _controller!.initialize();
|
||||
await _controller!.setVolume(_volume);
|
||||
_controller!.play();
|
||||
if (mounted) setState(() {});
|
||||
} catch (e) {
|
||||
@@ -254,6 +256,76 @@ class _PlayerPageState extends State<PlayerPage> {
|
||||
_showControls();
|
||||
}
|
||||
|
||||
Future<void> _setVolume(double volume) async {
|
||||
final nextVolume = volume.clamp(0.0, 1.0);
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() => _volume = nextVolume);
|
||||
|
||||
if (!kIsWeb && _controller != null) {
|
||||
await _controller!.setVolume(nextVolume);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openVolumeSheet() async {
|
||||
_showControls();
|
||||
await showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 20, 28),
|
||||
child: StatefulBuilder(
|
||||
builder: (context, setSheetState) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Volume',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
_volume == 0
|
||||
? Icons.volume_off
|
||||
: _volume < 0.5
|
||||
? Icons.volume_down
|
||||
: Icons.volume_up,
|
||||
),
|
||||
Expanded(
|
||||
child: Slider(
|
||||
value: _volume,
|
||||
min: 0,
|
||||
max: 1,
|
||||
divisions: 20,
|
||||
label: '${(_volume * 100).round()}%',
|
||||
onChanged: (value) {
|
||||
setSheetState(() => _volume = value);
|
||||
_setVolume(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 48,
|
||||
child: Text('${(_volume * 100).round()}%'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showControls() {
|
||||
_controlsHideTimer?.cancel();
|
||||
if (mounted) {
|
||||
@@ -439,6 +511,7 @@ class _PlayerPageState extends State<PlayerPage> {
|
||||
? WebStreamPlayer(
|
||||
key: ValueKey('web-player-$_playerVersion'),
|
||||
streamUrl: _currentPlaybackUrl(),
|
||||
volume: _volume,
|
||||
)
|
||||
: _controller != null && _controller!.value.isInitialized
|
||||
? AspectRatio(
|
||||
@@ -550,6 +623,15 @@ class _PlayerPageState extends State<PlayerPage> {
|
||||
label: "Refresh",
|
||||
onPressed: _refreshPlayer,
|
||||
),
|
||||
_buildControlButton(
|
||||
icon: _volume == 0
|
||||
? Icons.volume_off
|
||||
: _volume < 0.5
|
||||
? Icons.volume_down
|
||||
: Icons.volume_up,
|
||||
label: "Volume",
|
||||
onPressed: _openVolumeSheet,
|
||||
),
|
||||
_buildControlButton(
|
||||
icon: _showDanmaku ? Icons.subtitles : Icons.subtitles_off,
|
||||
label: _showDanmaku ? "Danmaku On" : "Danmaku Off",
|
||||
|
||||
Reference in New Issue
Block a user