Reputation: 947
I'm currently using the video_player to analyse the videos with precision. Unfortunately, I can't seem to be able to enhance the precision of the different "position" getter of the VideoPlayer instance. The top is 500ms interval between each refresh. It corresponds to the update of the progress indicator. 500ms to retrieve sports data such s a sprint is way too big.
Would it be possible to have a real time update ? The more precise the better, such as a stream or something.
Below is the code, super simple from their example, I'm using the builtin Stream which only sends an event when completed, and the position getter is the same refresh than the other (500ms)
class AssistantHome extends StatefulWidget {
final UserTest test;
final Player player;
const AssistantHome({Key key, @required this.test, @required this.player})
: super(key: key);
@override
State<AssistantHome> createState() => _AssistantHomeState();
}
class _AssistantHomeState extends State<AssistantHome> {
VideoPlayerController _controller;
int _positionInMs;
Stream<Duration> durationStream;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(widget.test.videoUrl);
durationStream = _controller.position.asStream();
_controller.addListener(() {
setState(() {
_positionInMs = _controller.value.position.inMilliseconds;
});
});
_controller.setLooping(true);
_controller.initialize().then((_) => setState(() {}));
_controller.play();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
children: <Widget>[
Text('${widget.test.uid}'),
Container(
height: 600,
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: SizedBox(
height: 600,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
VideoPlayer(_controller),
_ControlsOverlay(controller: _controller),
VideoProgressIndicator(_controller,
allowScrubbing: true),
],
),
),
),
),
StreamBuilder(builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.connectionState ==
ConnectionState.active ||
snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return const Text('Error');
} else if (snapshot.hasData) {
return Text(snapshot.data.toString(),
style: const TextStyle(
color: Colors.teal, fontSize: 36));
} else {
return const Text('Empty data');
}
} else {
return Text(
'Duration: ${_controller.value.position.inMicroseconds} us');
}
})),
Text("Current position: $_positionInMs ms"),
const Text('Footer'),
],
),
),
],
),
);
}
}
class _ControlsOverlay extends StatelessWidget {
const _ControlsOverlay({Key key, @required this.controller})
: super(key: key);
final VideoPlayerController controller;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
AnimatedSwitcher(
duration: const Duration(milliseconds: 50),
reverseDuration: const Duration(milliseconds: 200),
child: controller.value.isPlaying
? const SizedBox.shrink()
: Container(
color: Colors.black26,
child: const Center(
child: Icon(
Icons.play_arrow,
color: Colors.white,
size: 100.0,
semanticLabel: 'Play',
),
),
),
),
GestureDetector(
onTap: () {
controller.value.isPlaying ? controller.pause() : controller.play();
},
),
],
);
}
}
Upvotes: 2
Views: 1268
Reputation: 1
Try using the smooth_video_progress
package: https://pub.dev/packages/smooth_video_progress!
From https://pub.dev/packages/smooth_video_progress#usage:
Here is how you would build a simple slider for example:
Widget build(BuildContext context) {
SmoothVideoProgress(
controller: controller,
builder: (context, position, duration, child) => Slider(
onChangeStart: (_) => controller.pause(),
onChangeEnd: (_) => controller.play(),
onChanged: (value) =>
controller.seekTo(Duration(milliseconds: value.toInt())),
value: position.inMilliseconds.toDouble(),
min: 0,
max: duration.inMilliseconds.toDouble(),
),
);
}
Upvotes: 0