Closed krida2000 closed 11 months ago
I think the black background is the default in most video players?
Does doing a flutter upgrade help? Since it will use the latest media_kit release
Does the video fill get passed to the media_kit video widget? If yes I will try to make it based of a custom theme (no promises) since I have been busy for a while
@zezo357
Dear author,
The issue of a black screen is indeed a significant problem. Currently, I am unable to use this well-functioning player simply due to one reason—the application has a white color scheme, and the black preloading screen ruins the overall experience. It is unknown how to resolve this.
Ideally, it would be great to have a parameter for customizing the background color of the placeholder. This is crucial for applications that require a seamless transition between video playback and the UI. Without such customization, it seems impossible to use this player code in a serious business setting.
I kindly request you to add the ability to customize the color.
Thank you in advance!
Thank you for explaining, your case I will try to provide a way to customize it, when I do I will let you know here
@zezo357 Dear author of the player, please take a look at the following code example. Currently, I am using this wrapper... It effectively solves several issues:
In the attachment, I am simply showing you this code example to demonstrate real use cases and the challenges faced when using the player.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_meedu_videoplayer/meedu_player.dart';
class UVideoPlayer extends StatefulWidget {
final String? source;
final double? width;
final double? height;
const UVideoPlayer({
Key? key,
required this.source,
this.width,
this.height,
}) : super(key: key);
@override
_UVideoPlayerState createState() => _UVideoPlayerState();
}
class _UVideoPlayerState extends State<UVideoPlayer> with SingleTickerProviderStateMixin {
final _meeduPlayerController = MeeduPlayerController(
controlsStyle: ControlsStyle.custom,
autoHideControls: false,
controlsEnabled: false,
enabledControls: EnabledControls(
desktopDoubleTapToFullScreen: false,
desktopTapToPlayAndPause: false,
enterKeyOpensFullScreen: false,
escapeKeyCloseFullScreen: false,
numPadDecimalKeyToggleFit: false,
onLongPressSpeedUp: false,
seekArrows: false,
seekSwipes: false,
spaceKeyTogglePlay: false,
volumeArrows: false,
volumeSwipes: false,
),
);
late AnimationController _animationController;
late Animation<double> _opacityAnimation;
@override
void initState() {
super.initState();
Future.microtask(updateSource);
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
);
_opacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
Timer(Duration(seconds: 1), () {
_animationController.forward();
});
}
void updateSource() async {
if (_meeduPlayerController.playerStatus.playing) {
await _meeduPlayerController.pause();
}
if (widget.source != null) {
if (widget.source!.startsWith('https://') || widget.source!.startsWith('http://')) {
await _meeduPlayerController.setDataSource(
DataSource(
type: DataSourceType.network,
source: widget.source!,
),
autoplay: true,
looping: true,
);
} else {
var file = File(widget.source!);
await _meeduPlayerController.setDataSource(
DataSource(
type: DataSourceType.file,
file: file,
),
autoplay: true,
looping: true,
);
}
}
await _meeduPlayerController.setVolume(90);
}
@override
void dispose() {
_meeduPlayerController.dispose();
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
late double width;
late double height;
if (widget.width == null || widget.height == null) {
width = 256;
height = 144;
} else {
width = widget.width!;
height = widget.height!;
}
return Container(
margin: EdgeInsets.all(0),
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
width: width,
height: height,
child: AnimatedBuilder(
animation: _opacityAnimation,
builder: (BuildContext context, Widget? child) {
return Opacity(
opacity: _opacityAnimation.value,
child: child,
);
},
child: widget.source != null
? AspectRatio(
aspectRatio: 16 / 9,
child: MeeduVideoPlayer(
controller: _meeduPlayerController,
),
)
: Container(),
),
),
),
);
}
}
@zezo357 Dear author of the player, please take a look at the following code example. Currently, I am using this wrapper... It effectively solves several issues:
- Black screen
- Convenient source handling, whether the file is retrieved from the web or locally (I really don't want to know the details)
- Default dimensions, but not the dimensions of the placeholder...
In the attachment, I am simply showing you this code example to demonstrate real use cases and the challenges faced when using the player.
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_meedu_videoplayer/meedu_player.dart'; class UVideoPlayer extends StatefulWidget { final String? source; final double? width; final double? height; const UVideoPlayer({ Key? key, required this.source, this.width, this.height, }) : super(key: key); @override _UVideoPlayerState createState() => _UVideoPlayerState(); } class _UVideoPlayerState extends State<UVideoPlayer> with SingleTickerProviderStateMixin { final _meeduPlayerController = MeeduPlayerController( controlsStyle: ControlsStyle.custom, autoHideControls: false, controlsEnabled: false, enabledControls: EnabledControls( desktopDoubleTapToFullScreen: false, desktopTapToPlayAndPause: false, enterKeyOpensFullScreen: false, escapeKeyCloseFullScreen: false, numPadDecimalKeyToggleFit: false, onLongPressSpeedUp: false, seekArrows: false, seekSwipes: false, spaceKeyTogglePlay: false, volumeArrows: false, volumeSwipes: false, ), ); late AnimationController _animationController; late Animation<double> _opacityAnimation; @override void initState() { super.initState(); Future.microtask(updateSource); _animationController = AnimationController( vsync: this, duration: Duration(milliseconds: 1000), ); _opacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_animationController); Timer(Duration(seconds: 1), () { _animationController.forward(); }); } void updateSource() async { if (_meeduPlayerController.playerStatus.playing) { await _meeduPlayerController.pause(); } if (widget.source != null) { if (widget.source!.startsWith('https://') || widget.source!.startsWith('http://')) { await _meeduPlayerController.setDataSource( DataSource( type: DataSourceType.network, source: widget.source!, ), autoplay: true, looping: true, ); } else { var file = File(widget.source!); await _meeduPlayerController.setDataSource( DataSource( type: DataSourceType.file, file: file, ), autoplay: true, looping: true, ); } } await _meeduPlayerController.setVolume(90); } @override void dispose() { _meeduPlayerController.dispose(); _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { late double width; late double height; if (widget.width == null || widget.height == null) { width = 256; height = 144; } else { width = widget.width!; height = widget.height!; } return Container( margin: EdgeInsets.all(0), child: Align( alignment: Alignment.topCenter, child: SizedBox( width: width, height: height, child: AnimatedBuilder( animation: _opacityAnimation, builder: (BuildContext context, Widget? child) { return Opacity( opacity: _opacityAnimation.value, child: child, ); }, child: widget.source != null ? AspectRatio( aspectRatio: 16 / 9, child: MeeduVideoPlayer( controller: _meeduPlayerController, ), ) : Container(), ), ), ), ); } }
The black should still be visible when using windows or desktop in general due to media_kit I think
@zezo357 Under Linux, the player functions correctly, but a 1-second timeout is unacceptable for me. Checking Android now ... But anyway, we need to have option "all controls are disabled" just for dumb promo video, also, unified source will be great option IMO. But black screen is the real problem anyway.
@zezo357 Under Linux, the player functions correctly, but a 1-second timeout is unacceptable for me. Checking Android now ... But anyway, we need to have option "all controls are disabled" just for dumb promo video, also, unified source will be great option IMO. But black screen is the real problem anyway.
The unified source can be handled like how you handled it, the separation makes it easier for debugging, for most people,
Also can you explain the 1 second time out, you mentioned?
For the black background, I can check it next weekend, since I am working full time. Sorry if that takes some time
@zezo357 The animation with a 1-second delay after startup removes or hides the black screen, followed by a transparency animation. But... However, it is not suitable to have an empty white placeholder displayed for more than 1 second.
p.s. timeline is OK :) Thanks!
@zezo357 The animation with a 1-second delay after startup removes or hides the black screen, followed by a transparency animation. But... However, it is not suitable to have an empty white placeholder displayed for more than 1 second.
p.s. timeline is OK :) Thanks!
Thank you ❤️
check new release and example
@amaxcz @krida2000 hope it works well in your case
also for disabling controls you can set controlsEnabled to false , which will not put the ui controls and none of the touch/taps ones
@zezo357 works! finally! big thanks!
I have a black rectangle before the video initialized. I think it is because
media_kit Video.fill
is not set and by default it's black. There is any way to set this paramether?Video
https://github.com/zezo357/flutter_meedu_videoplayer/assets/71345244/ac340d0e-5051-4b43-840f-77553bcce017