import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:camera/camera.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shoutout_studio/views/camera/profile_screen.dart';
import 'package:video_player/video_player.dart';
class CameraScreen extends StatefulWidget {
@override
_CameraScreenState createState() => _CameraScreenState();
}
bool isRecording = false;
class _CameraScreenState extends State<CameraScreen>
with WidgetsBindingObserver {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
CameraController controller;
List cameras;
int selectedCameraIdx;
XFile videoFile;
XFile imageFile;
VideoPlayerController videoController;
VoidCallback videoPlayerListener;
bool enableAudio = true;
@override
void initState() {
super.initState();
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
selectedCameraIdx = 0;
});
_initCameraController(cameras[selectedCameraIdx]).then((void v) {});
} else {
print('NO Camera Available');
}
}).catchError((err) {
print('Error: $err.code\nError Message: $err.message');
});
}
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = CameraController(cameraDescription, ResolutionPreset.high);
controller.addListener(() {
if (mounted) {
setState(() {});
}
if (controller.value.hasError) {
print('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on CameraException catch (e) {
_showCameraException(e);
}
if (mounted) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
child: _cameraPreviewWidget(),
),
Container(
height: MediaQuery.of(context).size.height * 0.27,
color: Colors.black.withOpacity(0.58),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(
top: size.height * 0.015,
right: size.width * 0.05,
left: size.width * 0.05,
),
child: Row(
children: [
Column(
children: [
SizedBox(
height: size.height * 0.01,
),
GestureDetector(
onTap: () {
Navigator.of(context).pop();
controller.dispose();
},
child: Image(
height: size.height * 0.03,
image: AssetImage('assets/icons/back_arrow.png'),
),
),
],
),
SizedBox(
width: size.width * 0.05,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: size.height * 0.02,
),
Text(
'Identity Verification Script',
textAlign: TextAlign.center,
style: GoogleFonts.quicksand(
fontSize: size.width * 0.048,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
SizedBox(
height: size.height * 0.01,
),
Container(
height: 3,
width: size.width * 0.2,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xffFD0C92),
Color(0xf0FD0C92),
Colors.yellow[200],
]),
),
)
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'Hi',
textAlign: TextAlign.center,
style: GoogleFonts.quicksand(
color: Colors.white,
fontSize: size.width * 0.04,
),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.height * 0.52,
left: MediaQuery.of(context).size.width * 0.84,
),
child: _cameraTogglesRowWidget(),
),
Padding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.height * 0.8,
),
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.58),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60.0),
topRight: Radius.circular(60.0),
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Replay',
style: GoogleFonts.quicksand(
color: Colors.white,
),
),
GestureDetector(
child: Container(
height: size.height * 0.08,
width: size.width * 0.13,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/replay.png',
),
fit: BoxFit.fill,
),
),
),
onTap: () {
//_startVideoPlayer();
},
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: _captureControlRowWidget(context),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Upload',
style: GoogleFonts.quicksand(
color: Colors.white,
),
),
GestureDetector(
child: Container(
height: size.height * 0.08,
width: size.width * 0.13,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/upload.png',
),
fit: BoxFit.fill,
),
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePicture(),
),
);
controller.dispose();
},
),
],
),
),
],
),
),
),
),
SizedBox(height: 20.0)
],
),
);
}
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
);
}
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
Widget _captureControlRowWidget(context) {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Record',
style: GoogleFonts.quicksand(
color: Colors.white,
),
),
GestureDetector(
child: CircleAvatar(
backgroundColor: Colors.white,
radius: 30,
child: Icon(
isRecording ? Icons.pause : Icons.fiber_manual_record_rounded,
color: Colors.red,
size: 35,
),
),
onTap: () => isRecording
? onStopButtonPressed()
: onVideoRecordButtonPressed(),
),
],
),
),
);
}
Widget _cameraTogglesRowWidget() {
if (cameras == null || cameras.isEmpty) {
return Spacer();
}
return Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: GestureDetector(
onTap: () => _onSwitchCamera(),
child: Container(
height: 25,
width: 25,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/reverse.png',
),
fit: BoxFit.fill,
),
),
),
),
),
);
}
void _onSwitchCamera() {
selectedCameraIdx =
selectedCameraIdx < cameras.length - 1 ? selectedCameraIdx + 1 : 0;
CameraDescription selectedCamera = cameras[selectedCameraIdx];
_initCameraController(selectedCamera);
}
void onVideoRecordButtonPressed() {
isRecording = true;
startVideoRecording().then((_) {
if (mounted) setState(() {});
});
}
void onStopButtonPressed() {
isRecording = false;
stopVideoRecording().then((file) {
if (mounted) setState(() {});
if (file != null) {
showInSnackBar('Video recorded to ${file.path}');
videoFile = file;
}
}, onError: (e) {
print(e);
});
}
Future<void> startVideoRecording() async {
if (!controller.value.isInitialized) {
showInSnackBar('Error: select a camera first.');
return;
}
if (controller.value.isRecordingVideo) {
// A recording is already started, do nothing.
return;
}
try {
await controller.startVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return;
}
}
Future<XFile> stopVideoRecording() async {
if (!controller.value.isRecordingVideo) {
return null;
}
try {
return controller.stopVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
}
Future<void> _startVideoPlayer() async {
final VideoPlayerController vController =
VideoPlayerController.file(File(videoFile.path));
videoPlayerListener = () {
if (videoController != null && videoController.value.size != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) setState(() {});
videoController.removeListener(videoPlayerListener);
}
};
vController.addListener(videoPlayerListener);
await vController.setLooping(false);
await vController.initialize();
await videoController?.dispose();
if (mounted) {
setState(() {
imageFile = null;
videoController = vController;
});
}
await vController.play();
}
void showInSnackBar(String message) {
// ignore: deprecated_member_use
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
}
void _showCameraException(CameraException e) {
String errorText = 'Error: ${e.code}\nError Message: ${e.description}';
print(errorText);
print('Error: ${e.code}\n${e.description}');
}
}
I am creating a camera recording page and this is what I have done so for but I am getting this error but I don't know how to solve this. I thought that It was due to the camera preview widget but I had searched for this exception and find this link incorrect use of parent data widget. expanded widgets must be placed inside flex widgets