viewer: video overlay muted/speed indicators

This commit is contained in:
Thibault Deckers 2022-03-18 11:38:49 +09:00
parent ac21238ab4
commit 318ee1385e
3 changed files with 51 additions and 4 deletions

View file

@ -2,12 +2,14 @@ import 'dart:async';
import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/format.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/theme/themes.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/common/fx/borders.dart';
import 'package:aves/widgets/viewer/video/controller.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class VideoProgressBar extends StatefulWidget {
final AvesVideoController? controller;
@ -114,10 +116,16 @@ class _VideoProgressBarState extends State<VideoProgressBar> {
}),
),
),
Text(
// fake text below to match the height of the text above and center the whole thing
'',
style: textStyle,
Row(
children: [
_buildSpeedIndicator(),
_buildMuteIndicator(),
Text(
// fake text below to match the height of the text above and center the whole thing
'',
style: textStyle,
),
],
),
],
),
@ -128,6 +136,38 @@ class _VideoProgressBarState extends State<VideoProgressBar> {
);
}
Widget _buildSpeedIndicator() => StreamBuilder<double>(
stream: controller?.speedStream ?? Stream.value(1.0),
builder: (context, snapshot) {
final speed = controller?.speed ?? 1.0;
return speed != 1
? Padding(
padding: const EdgeInsetsDirectional.only(end: 8),
child: Text('x$speed'),
)
: const SizedBox();
},
);
Widget _buildMuteIndicator() => StreamBuilder<double>(
stream: controller?.volumeStream ?? Stream.value(1.0),
builder: (context, snapshot) {
final isMuted = controller?.isMuted ?? false;
return isMuted
? Padding(
padding: const EdgeInsetsDirectional.only(end: 8),
child: Selector<MediaQueryData, double>(
selector: (context, mq) => mq.textScaleFactor,
builder: (context, textScaleFactor, child) => Icon(
AIcons.mute,
size: 16 * textScaleFactor,
),
),
)
: const SizedBox();
},
);
void _seekFromTap(Offset globalPosition) async {
if (controller == null) return;
final keyContext = _progressBarKey.currentContext!;

View file

@ -94,6 +94,8 @@ abstract class AvesVideoController {
Stream<double> get volumeStream;
Stream<double> get speedStream;
bool get isReady;
bool get isPlaying => status == VideoStatus.playing;

View file

@ -18,6 +18,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
final StreamController<FijkValue> _valueStreamController = StreamController.broadcast();
final StreamController<String?> _timedTextStreamController = StreamController.broadcast();
final StreamController<double> _volumeStreamController = StreamController.broadcast();
final StreamController<double> _speedStreamController = StreamController.broadcast();
final AChangeNotifier _completedNotifier = AChangeNotifier();
Offset _macroBlockCrop = Offset.zero;
final List<StreamSummary> _streams = [];
@ -333,6 +334,9 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
@override
Stream<double> get volumeStream => _volumeStreamController.stream;
@override
Stream<double> get speedStream => _speedStreamController.stream;
@override
bool get isReady => _instance.isPlayable();
@ -372,6 +376,7 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
if (speed <= 0 || _speed == speed) return;
final optionChange = _needSoundTouch(speed) != _needSoundTouch(_speed);
_speed = speed;
_speedStreamController.add(_speed);
if (optionChange) {
_init(startMillis: currentPosition);