I am working on a flutter project to play video from file or network. I use chewie package to play videos. But while testing in iphone 13 emulator and some of the full screen mobile phone i cant press the full screen and mute button of video player.The controls are overflowed.
And also while playing in full screen the video is not stretched. There are some black spaces in left and right side of the video.
The image of both is attached and my video player code is as follows
callChewie(_videoPlayerController) async {
bool startPlayer = false;
// _videoPlayerController.initialize();
_videoPlayerController.addListener(() {
// print(_videoPlayerController.value.isInitialized);
if (!startPlayer) {
if (!_videoPlayerController.value.isPlaying) {
startPlayer = true;
_videoPlayerController.play();
}
}
});
chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
aspectRatio: 16 / 9,
autoPlay: true,
looping: false,
errorBuilder: (context, errorMessage) {
print('error occured $errorMessage');
Future.delayed(Duration(seconds: 10), () {
AwesomeDialog(
context: context,
dialogType: DialogType.ERROR,
dialogBackgroundColor: Colors.white,
borderSide: BorderSide(color: COLORS['PRIMARY_COLOR'], width: 2),
width: 400,
buttonsBorderRadius: BorderRadius.all(Radius.circular(2)),
headerAnimationLoop: false,
animType: AnimType.BOTTOMSLIDE,
title: 'Something went wrong.\nTry Again!',
btnOkColor: COLORS['PRIMARY_COLOR'],
showCloseIcon: true,
btnOkOnPress: () {
Navigator.pop(context);
},
)..show();
});
return Center(
child: CircularProgressIndicator(
color: Colors.red,
));
},
showControls: true,
allowFullScreen: !kIsWeb ? true : false,
fullScreenByDefault: false,
customControls: CupertinoControls(
backgroundColor: Colors.black,
iconColor: COLORS['PRIMARY_COLOR'],
));
chewieController.addListener(() {
if (chewieController.isFullScreen) {
print('full screen enabled');
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
} else {
print('fullscreen disabled');
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
});
}
playMovie(file) async {
if (mounted) {
setState(() {
_videoPlayerController = null;
});
}
_videoPlayerController = VideoPlayerController.file(file);
await callChewie(_videoPlayerController);
Navigator.of(context).push(
PageRouteBuilder(
opaque: true,
settings: RouteSettings(),
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return WillPopScope(
onWillPop: () {
if (_videoPlayerController.value.isPlaying) {
_videoPlayerController?.pause();
_videoPlayerController?.dispose();
}
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return new Future.value(true);
},
child: Scaffold(
backgroundColor: Colors.black,
resizeToAvoidBottomInset: false,
body: Stack(children: [
MouseRegion(
onEnter: (event) {
setState(() {
isInfoVisible = true;
});
},
child: Dismissible(
key: const Key('key'),
direction: DismissDirection.horizontal,
onDismissed: (_) {
Navigator.of(context).pop();
_videoPlayerController?.dispose();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
},
child: OrientationBuilder(
builder: (context, orientation) {
isPortrait = orientation == Orientation.portrait;
return Center(
child: Stack(
//This will help to expand video in Horizontal mode till last pixel of screen
fit: isPortrait
? StackFit.loose
: StackFit.expand,
children: [
SubTitleWrapper(
videoPlayerController:
_videoPlayerController,
subtitleController: subtitleController,
videoChild: Chewie(
controller: chewieController,
),
),
/*Chewie(
controller: chewieController,
),*/
],
),
);
},
))),
])),
);
},
),
);
}
and I call the playMovie() function on button press.
onPressed: () {
playMovie(file[index]);
},
And also while playing in full screen the video is not stretched. There are some black spaces in left and right side of the video.
Related
I applied will pop scope on that screen it didn't work me its YouTube video player screen. I define all the routes in main.dart is that problem will pop scope is not working Let me know where I am going wrong
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stocker/models/YouTubeStateModel.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
class VideoPlayer extends StatefulWidget {
const VideoPlayer({
Key? key,
required this.videoID,
required this.data,
}) : super(key: key);
static const routeName = '/videoPlayer';
final YouTubeState data;
final String videoID;
#override
State<VideoPlayer> createState() => _VideoPlayerState();
}
class _VideoPlayerState extends State<VideoPlayer> {
late YoutubePlayerController _controller;
#override
void initState() {
super.initState();
_controller = YoutubePlayerController(
initialVideoId: widget.videoID,
flags: const YoutubePlayerFlags(
autoPlay: true,
mute: false,
),
);
Future.delayed(
const Duration(milliseconds: 300),
).then((value) {
_controller.toggleFullScreenMode();
_controller.setSize(Size(1.sw, 1.sh));
});
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
_controller.setSize(
width > height
? Size(1.sw - ScreenUtil().statusBarHeight, 1.sh)
: Size(1.sw, 1.sh - ScreenUtil().statusBarHeight),
);
return WillPopScope(
onWillPop: () async {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
Navigator.of(context).pop();
return false;
},
child: Stack(
children: [
YoutubePlayerBuilder(
player: YoutubePlayer(
bottomActions: [
const SizedBox(width: 14.0),
CurrentPosition(),
const SizedBox(width: 8.0),
ProgressBar(
isExpanded: true,
// colors: widget,
),
RemainingDuration(),
const PlaybackSpeedButton(),
],
// aspectRatio: width > height
// ? (width - ScreenUtil().statusBarHeight) / height
// : (width) / (height - ScreenUtil().statusBarHeight),
aspectRatio: width > height
? height / (width - ScreenUtil().statusBarHeight)
: (height - ScreenUtil().statusBarHeight) / (width),
controller: _controller,
width: size.width,
),
builder: (context, player) {
return Scaffold(
backgroundColor: Colors.black,
body: Padding(
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight),
child: SizedBox(
height: 1.sh - ScreenUtil().statusBarHeight,
width: 1.sw,
child: Stack(
children: [
Center(child: player),
// Positioned(
// bottom: 100,
// right: 100,
// child: GestureDetector(
// onTap: Navigator.of(context).pop,
// child: SvgPicture.asset(
// 'assets/svg/back_arrow.svg',
// color: Colors.white,
// width: 24.h,
// height: 24.h,
// ),
// ),
// ),
],
),
),
),
);
},
),
Positioned(
left: 5.w,
top: 30.h,
child: GestureDetector(
onTap: () {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
Navigator.of(context).pop();
},
child: SvgPicture.asset(
'assets/svg/back_arrow.svg',
color: Colors.white,
width: 16.w,
height: 16.w,
),
),
)
],
),
);
}
}
I applied Will pop scope on the main stack and inside the builder Scaffold as well but at both of the places it didn't work let me know how can I tackle this problem .
/* ::::::::::::::::::::::: OnWillPop show dialog :::::::::::::::::::::::*/
WillPopScope(
onWillPop: () {
return openDialog();
},)
openDialog() {
Get.dialog(
AlertDialog(
title: const Text('Are Yor Sure?'),
content: const Text('Do you want to exit this App'),
actions: [
TextButton(
onPressed: () => Get.back(),
child: const Text("No"),
),
TextButton(
onPressed: () {
if (Platform.isAndroid) {
SystemNavigator.pop(); // or
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(builder: (context) => HomePage()),
// (route) => false);
print("android>>>>");
} else if (Platform.isIOS) {
exit(0);
}
},
child: const Text("Yes"),
),
],
),
);
}
2nd way
onWillPop: () async {
final shouldPop = await showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Do you want to go back?'),
actionsAlignment: MainAxisAlignment.spaceBetween,
actions: [
TextButton(
onPressed: () {
Navigator.pop(context, true);
},
child: const Text('Yes'),
),
TextButton(
onPressed: () {
Navigator.pop(context, false);
},
child: const Text('No'),
),
],
);
},
);
return shouldPop!;
},
Hello friends my problem is that I want perform task there small icon on menu bar mic icon when user click on Mic it show dialog box and when they speak text word appear on dialog box when user finished up there speech it's goes to next screen I have done all thing but problem is that when user finishing there speech i unable to go on next sacreen this only issue any expert can help here is picture below what i actually i want
Here is when user speech
When they complete their speech go next sacreen
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
import 'package:speech_to_text/speech_to_text.dart';
import 'package:avatar_glow/avatar_glow.dart';
class Booknames extends StatefulWidget {
const Booknames({Key? key}) : super(key: key);
#override
_BooknamesState createState() => _BooknamesState();
}
class _BooknamesState extends State<Booknames> {
stt.SpeechToText speechToText = stt.SpeechToText();
bool islistening = false;
late String text = 'Example:Gensis chapter verse 5';
bool complete=false;
#override
void initState() {
// TODO: implement initState
super.initState();
_initSpeech();
}
/// This has to happen only once per app
void _initSpeech() async {
speechToText.initialize();
}
final GlobalKey _dialogKey = GlobalKey();
_showDialog() async {
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return StatefulBuilder(
key: _dialogKey,
builder: (context, setState) {
return Container(
child: Dialog(
child: Padding(
padding: EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
AvatarGlow(
glowColor: Colors.blue,
endRadius: 80,
duration: Duration( milliseconds: 2500),
repeat: true,
showTwoGlows: true,
repeatPauseDuration: Duration( milliseconds: 150),
child: Material(
elevation: 5,
shape: CircleBorder(),
child: CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.mic, color: Colors.blue, size: 40,),
radius: 40,
),
),
),
Text(text),
SizedBox(height: 10),
TextButton(
onPressed: () => Navigator.pop(context, false), // passing false
child: Text('Cancel Voice'),
),
],
),
),
),
);
},
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
new IconButton(
icon: new Icon(islistening ? Icons.mic : Icons.mic_none),
highlightColor: Colors.pink,
onPressed: () {
setState(() {
_listen();
_showDialog();
});
},
),
],
elevation: 0,
title: Text('The Bible Multiversion', style: TextStyle(
fontSize: 20
),),
centerTitle: true,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView.separated(
shrinkWrap: true,
itemCount: 1,
separatorBuilder: (BuildContext context, int index) =>
Divider(height: 1),
itemBuilder: (context, index) {
return Column(
children: [
],
);
},
),
),
],
),
);
}
void _listen() async {
if (!islistening) {
bool available = await speechToText.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'),
);
if (available) {
setState(() {
islistening = true;
});
speechToText.listen(
onResult: (result) =>
setState(() {
text = result.recognizedWords;
if (_dialogKey.currentState != null && _dialogKey.currentState!.mounted) {
_dialogKey.currentState!.setState(() {
text =result.recognizedWords;
});
}
})
);
}
} else {
setState(() => islistening = false
);
speechToText.stop();
}
}
}
I am working on a video playing app. Where i play video using chewie package. To show subtitles is user subtitle wrapper package. The subtitle is showing properly in protrait mode when switched to full screen its not showing. Does anyone have a solution for this. my code is as below:
SafeArea(
child: Scaffold(
backgroundColor: Colors.black,
resizeToAvoidBottomInset: false,
body: Stack(children: [
MouseRegion(
onEnter: (event) {
setState(() {
isInfoVisible = true;
});
},
child: Dismissible(
key: const Key('key'),
direction: DismissDirection.horizontal,
onDismissed: (_) {
Navigator.of(context).pop();
_videoPlayerController?.dispose();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
},
child: OrientationBuilder(
builder: (context, orientation) {
isPortrait =
orientation == Orientation.portrait;
return Center(
child: Stack(
fit: isPortrait
? StackFit.loose
: StackFit.expand,
children: [
SubTitleWrapper(
videoPlayerController:
_videoPlayerController,
subtitleController: subtitleController,
videoChild: Chewie(
controller: chewieController,
),
),
/*Chewie(
controller: chewieController,
),*/
],
),
);
},
))),
])),
),
chewie controller as below:
chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
aspectRatio: 16 / 9,
autoPlay: true,
looping: false,
errorBuilder: (context, errorMessage) {
print('error occured $errorMessage');
},
showControls: true,
allowFullScreen: !kIsWeb ? true : false,
fullScreenByDefault: false,
customControls: CupertinoControls(
backgroundColor: Colors.black,
iconColor: COLORS['PRIMARY_COLOR'],
));
anyone please help with this or another any solution to show subtitle from a link in chewie package.
I have a Flutter project with Bottom Navigation Bar. There are 2 tabs in the Bottom Navigation Bar. One page is webview and the other is flutter page. I add these two pages to my home page with include. I want to manage the navigation in the webview when the back button is pressed while the inside webview is on the page.
Home Page Code:
Future<bool> _onBackPressed() {
return (showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Sure?'),
content:
new Text('???'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'),
),
],
),
)) ??
false;
}
#override
Widget build(BuildContext context) {
List<Widget> pageList = [
MainHomePage(
text: widget.text,
),
WatchPage()
];
return WillPopScope(
onWillPop: _onBackPressed,
child: Scaffold(
//backgroundColor: Colors.transparent,
body: Container(
child: pageList[_activePage],
),
bottomNavigationBar: CurvedNavigationBar(
animationCurve: Curves.easeInOut,
animationDuration: Duration(milliseconds: 600),
color: Color(0xff1f5269),
backgroundColor: Colors.transparent,
onTap: (index) {
setState(() {
_activePage = index;
});
},
items: <Widget>[
Icon(
Icons.home,
color: Colors.white,
),
Icon(
Icons.tv,
color: Colors.white,
),
],
),
),
);
}
WebView Page:
WebViewController controller;
final Completer<WebViewController> _controller =
Completer<WebViewController>();
Future<void> _onWillPop(BuildContext context) async {
print("onwillpop");
if (await controller.canGoBack()) {
controller.goBack();
return Future.value(true);
} else {
//exit(0);
return Future.value(false);
}
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _onWillPop(context),
child: Scaffold(
appBar: AppBar(
toolbarHeight: 10,
flexibleSpace: Container(
color: Color(0xff1f5269),
),
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: widget.text,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController c) {
_controller.future.then((value) => controller = value);
_controller.complete(c);
},
onProgress: (int progress) {
//print("Webview is loading(progress: $progress&)");
},
onPageStarted: (String url) {
if (url == "https://app.testt.com/Login/Cikis") {
Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(builder: (context) => new LoginPage()));
}
},
onPageFinished: (String url) {
if (url == "https://app.testt.com/Login" ) {
Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(builder: (context) => new LoginPage()));
}
},
gestureNavigationEnabled: true,
);
}),
),
);
}
I am new to flutter and I am using hero widget to make animation for floating button.
I have bottom navigation and I have to open page with tab navigator. But hero animation is not working.
I use every possible solution but still hero animation not working for page route.
Here is my code snippet.
FloatingActionButton(
onPressed: () {
_selectTab(TabItem.Floating);
},
child: Icon(Icons.add),
heroTag: "tag",
),
This is click for fab button to open new page
void _selectTab(TabItem tabItem) {
if (tabItem == currentTab) {
// pop to first route
_navigatorKeys[tabItem].currentState.popUntil((route) => route.isFirst);
} else {
setState(() => currentTab = tabItem);
}
}
In navigator
#override
Widget build(BuildContext context) {
var routeBuilders = _routeBuilders(context);
return Navigator(
observers: [
HeroController(),
],
key: widget.navigatorKey,
initialRoute: TabNavigatorRoutes.root,
onGenerateRoute: (routeSettings) {
return PageRouteBuilder(
transitionDuration: Duration(seconds: 1),
pageBuilder: (_, __, ___) =>
routeBuilders[routeSettings.name](context));
});
}
Route
if (widget.tabItem == TabItem.Floating) {
return ActFloatingScreen(
title: 'Floating Tab',
onPush: (materialIndex) =>
_push(context, materialIndex: materialIndex),
);
}
push
void _push(BuildContext context, {int materialIndex: 500}) {
var routeBuilders = _routeBuilders(context, materialIndex: materialIndex);
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 1),
pageBuilder: (_, __, ___) =>
routeBuilders[TabNavigatorRoutes.detail](context)));
}
and finally my desired class which I want to open with hero animation
return Scaffold(
backgroundColor: Colors.white,
body: Hero(
tag: "tag",
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Container(
color: Colors.green,
height: 200,
),
PositionedDirectional(
start: 0,
end: 0,
top: 150,
child: Center(
child: Icon(
Icons.add,
size: 100,
)),
),
],
),
),
);