I am using the camera 0.9.4+5 package.
I think the Camera Preview's size and aspect ratio of the package has been changed.
Please let me know how to set the Camera Preview to full screen without stretch.
Thank you.
For now the only solution in my mind is to make the package local and removed it from yaml file and then make the aspect ratio according to your will :)
Place your CameraPreview inside of an AspectRatio inside of a SizedBox with you screen dimensions.
Code below:
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import '../../main.dart';
// I defined cameras in main
class FullScreenCamera extends StatefulWidget {
const FullScreenCamera({Key? key}) : super(key: key);
#override
_FullScreenCameraState createState() => _FullScreenCameraState();
}
class _FullScreenCameraState extends State<FullScreenCamera>
with WidgetsBindingObserver {
late CameraController controller;
late Future<void> _initializeControllerFuture;
double? _screenWidth;
double? _screenHeight;
#override
void initState() {
super.initState();
controller = CameraController(cameras[0], ResolutionPreset.ultraHigh);
controller.setFlashMode(FlashMode.auto);
_initializeControllerFuture = controller.initialize();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
_screenWidth = MediaQuery.of(context).size.width;
_screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Stack(
children: [
SizedBox(
width: _screenWidth,
height: _screenHeight,
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
),
),
],
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
);
}
}
Edit:
I didn't realize, but the code is creating stretching as seen below on an iphone 13 pro with a 19.5:9 aspect ratio... As Christopher Perry pointed out, the camera view aspect ratio appears stuck at 16:9 and just fills out the screen resulting in stretching.
Stretched in full screen:
Normal:
Related
I have been trying to get the flutter camera plugin to work for almost a week now but I couldn't.
Every time the camera is not initialized no matter what workaround I do.
Can any one help please.
class CameraPage extends StatefulWidget {
const CameraPage({Key? key,}) : super(key: key); #override
State<CameraPage> createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> {
List<CameraDescription>? cameras;
CameraDescription? camera;
CameraController? cameraController;
CameraDescription? firstCamera() {
camera = cameras![1];
return camera;
}
Future getAvailableCameras() async {
cameras = await availableCameras();
camera = firstCamera();
}
Future setDefaultCamera() async {
cameraController = CameraController(
Provider.of<CameraProvider>(context).camer!, ResolutionPreset.medium);
cameraController?.initialize();
return cameraController;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: setDefaultCamera(),
builder: ((context, snapshot) {
if (snapshot.hasData) {
return Container(
width: 450,
color: Colors.red,
height: 450,
child: CameraPreview(cameraController!));
} else {
return const Center(child: CircularProgressIndicator());}})),);}}
To anyone facing the same problem and want more control than using image_picker. I found a solution to my problem by following the example in the this showcase.
https://dev.to/aouahib/build-a-flutter-gallery-to-display-all-the-photos-and-videos-in-your-phone-pb6
I hope someone will find it useful.
I want to use a rive animation like this one
https://rive.app/community/1514-2958-flower-composition-tutorial/
I notice that this artboard contains a somes NestedArtboard this nested artboard are not loaded by my app, I would like to know why this happen?
This is my code:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rive/rive.dart';
class RiveBackground extends StatefulWidget {
const RiveBackground({Key? key}) : super(key: key);
#override
State<RiveBackground> createState() => _RiveBackgroundState();
}
class _RiveBackgroundState extends State<RiveBackground> {
// Declarations necessary to rive
final riveFileName = 'assets/rive/last.riv';
Artboard? globalArtboard;
// Animation controller
late RiveAnimationController _animationController;
// Loads a Rive file
Future<void> _loadRiveFile() async {
final bytes = await rootBundle.load(riveFileName);
RiveFile rFile = RiveFile.import(bytes);
final artboard = rFile.artboardByName('Motion');
print(globalArtboard);
globalArtboard = artboard!
..addController(
_animationController = SimpleAnimation('Animation 1'),
);
setState(() {});
}
#override
void initState() {
WidgetsBinding.instance!.addPostFrameCallback((_) => _loadRiveFile());
super.initState();
}
#override
Widget build(BuildContext context) {
print('Building');
return Scaffold(
body: globalArtboard != null
? Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Rive(
fit: BoxFit.cover,
artboard: globalArtboard!,
),
)
: const Center(child: Text('empty')),
);
}
}
Expected result
My result
Not sure if you found a solution for this already, but according to this response in this Github issue,
to get the nested artboard to show through, you should instance the Artboard when you set it up with the Rive widget, so your setup would go from:
Rive(artboard: riveFile.artboardByName("artboard"));
to
Rive(artboard: riveFile.artboardByName("artboard")!.instance());
more detail in the link. I hope this helps!
I'm trying to show a video inside a container, videos could exceed container's aspect ratio, so the they need to be cropped.
With images it is simple as that:
Image.network(someUrl, fit: BoxFit.cover)
but how to do it with VideoPlayer?
my current code looks like this:
Stack(
children: [
Container(
width: double.infinity,
height: double.infinity,
child: ShowcaseVideoPlayer(someUrl)
),
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {},
),
),
],);
class ShowcaseVideoPlayer extends StatefulWidget {
final String url;
ShowcaseVideoPlayer(this.url);
#override
_ShowcaseVideoPlayerState createState() => _ShowcaseVideoPlayerState();
}
class _ShowcaseVideoPlayerState extends State<ShowcaseVideoPlayer> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
_controller = VideoPlayerController.network(widget.url);
_initializeVideoPlayerFuture = _controller.initialize();
_controller.setVolume(0);
super.initState();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
_controller.play();
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the VideoPlayer.
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(),
);
}
},
);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
}
I need a stack as I will have to show other things over the video. I tried without the stack and the player maintains the aspect ratio of the video, basically letter-boxing it. With the stack, the video stratches, losing the original aspect ratio:
to be clear, what I want is this:
EDIT: I tried random things on it and managed to achieve something, I removed the Container and wrapped the VideoPlayer like this:
Stack(
children: [
OverflowBox(
child: Wrap(
children: [
ShowcaseVideoPlayer(someUrl)
],
),
)]);
now the the video is actually cropped, but not centered (I see the upper part of the video instead of the central one). Wrapping Wrap in a Center and setting alignment: Alignment.center on OverfowBox have no effect. Any idea?
I am trying to create a background video splash screen for my app.
Currently, I am achieving a blank screen by running this code.
void main() => runApp(WalkThrough());
class WalkThrough extends StatefulWidget {
#override
_WalkThroughState createState() => _WalkThroughState();
}
class _WalkThroughState extends State<WalkThrough> {
VideoPlayerController _controller;
#override
void initState() {
super.initState();
// Pointing the video controller to our local asset.
_controller = VideoPlayerController.asset('assets/video.mp4')
..initialize().then((_) {
// Once the video has been loaded we play the video and set looping to true.
_controller.play();
_controller.setLooping(true);
_controller.setVolume(0.0);
_controller.play();
// Ensure the first frame is shown after the video is initialized.
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
I suspect the problem may be here and have based my research off this Full screen video background in Flutter on Login as I am trying to achieve a similar result.
SizedBox.expand(
child: FittedBox(
// If your background video doesn't look right, try changing the BoxFit property.
// BoxFit.fill created the look I was going for.
fit: BoxFit.fill,
child: SizedBox(
width: _controller.value.size?.width ?? 0,
height: _controller.value.size?.height ?? 0,
child: VideoPlayer(_controller),
),
),
),
I think the video player package has an issue to show video in the Ios simulator. I had the same issue and search for it and find out this issue in Github. until now this issue is open. I tested the video player on a real device and there were no problems.
Use this video player video_player plugin
& Save your mp4 file in assets/videos location
Try the below code
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
import 'HomePage.dart';
class SplashPage extends StatefulWidget {
SplashPage({Key key}) : super(key: key);
#override
State<StatefulWidget> createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
VideoPlayerController _controller;
bool _visible = false;
#override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
_controller = VideoPlayerController.asset("assets/video/splash_video.mp4");
_controller.initialize().then((_) {
_controller.setLooping(true);
Timer(Duration(milliseconds: 100), () {
setState(() {
_controller.play();
_visible = true;
});
});
});
Future.delayed(Duration(seconds: 4), () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => HomePage(param_homepage: 'Welcome Home')),
(e) => false);
});
}
#override
void dispose() {
super.dispose();
if (_controller != null) {
_controller.dispose();
_controller = null;
}
}
_getVideoBackground() {
return AnimatedOpacity(
opacity: _visible ? 1.0 : 0.0,
duration: Duration(milliseconds: 1000),
child: VideoPlayer(_controller),
);
}
_getBackgroundColor() {
return Container(color: Colors.transparent //.withAlpha(120),
);
}
_getContent() {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Stack(
children: <Widget>[
_getVideoBackground(),
],
),
),
);
}
}
I'm trying to position some text over a video.
The video is currently taking as much space as possible while retaining it's original aspect ratio. Ideally I'd like it to keep doing this as I want the video to resize to fit the browser window.
I'm assuming I need to get get the height/width of the video dynamically..
If anyone knows how to make a video play automatically that would be great as well - I'm using the video_player package.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
drawer: ResponsiveLayout.isSmallScreen(context) ? NavDrawer() : null,
body: Container(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
NavBar(),
Body(),
Footer(),
],
),
),
),
);
}
}
class Body extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ResponsiveLayout(
largeScreen: LargeScreen(),
mediumScreen: LargeScreen(),
smallScreen: LargeScreen(),
);
}
}
class LargeScreen extends StatefulWidget {
#override
_LargeScreenState createState() => _LargeScreenState();
}
class _LargeScreenState extends State<LargeScreen> {
VideoPlayerController _videoPlayerController;
Future<void> _initializeVideoPlayerFuture;
#override
void initState() {
_videoPlayerController = VideoPlayerController.asset(
'assets/videos/video.mp4',
);
_initializeVideoPlayerFuture = _videoPlayerController.initialize();
super.initState();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Column(
children: <Widget>[
FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the VideoPlayer.
return AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_videoPlayerController),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return Center(child: CircularProgressIndicator());
}
},
),
],
),
);
}
#override
void dispose() {
super.dispose();
_videoPlayerController.dispose();
}
}
you can wrap your Widgets in stack widget and use positioning to position your text
AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: Stack(children:<Widget>[
VideoPlayer(_videoPlayerController),
Positioned(bottom:10,left:10,
child:Text("my text here))
])
)
update
If anyone knows how to make a video play automatically that would be great as well - I'm using the video_player package.
you can set the state of your video using your controller
_videoPlayerController.value.isPlaying
I want the video to resize to fit the browser window.
you can wrap your video in a SizedBox.expand which Creates a box that will become as large as its parent allows.
sized box constructors