Created
September 22, 2022 02:04
-
-
Save tatsuyasusukida/a7915c0ab44fcee5aa2e9785331a5876 to your computer and use it in GitHub Desktop.
Flutter video recording example (recording issues fixed version)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:video_recording/start_screen.dart'; | |
Future<void> main() async { | |
WidgetsFlutterBinding.ensureInitialized(); | |
runApp(MaterialApp( | |
theme: ThemeData.dark(), | |
home: const StartScreen(), | |
)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:video_recording/video_recorder_screen.dart'; | |
class StartScreen extends StatelessWidget { | |
const StartScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: const Text('Start screen')), | |
body: Padding( | |
padding: EdgeInsets.all(10), | |
child: SizedBox( | |
width: double.infinity, | |
child: ElevatedButton( | |
child: const Text('Camera'), | |
onPressed: () { | |
Navigator.of(context).push( | |
MaterialPageRoute( | |
builder: (context) => const VideoRecorderScreen(), | |
), | |
); | |
}, | |
), | |
), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:io'; | |
import 'package:flutter/material.dart'; | |
import 'package:video_player/video_player.dart'; | |
class VideoPlayerScreen extends StatefulWidget { | |
final String videoPath; | |
const VideoPlayerScreen({super.key, required this.videoPath}); | |
@override | |
State<VideoPlayerScreen> createState() => _VideoPlayerScreenState(); | |
} | |
class _VideoPlayerScreenState extends State<VideoPlayerScreen> { | |
late VideoPlayerController _controller; | |
late Future<void> _initializeControllerFuture; | |
@override | |
void initState() { | |
super.initState(); | |
_controller = VideoPlayerController.file(File(widget.videoPath)); | |
_initializeControllerFuture = _controller.initialize(); | |
_controller.setLooping(true); | |
} | |
@override | |
void dispose() { | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: const Text('Video player screen')), | |
body: FutureBuilder( | |
future: _initializeControllerFuture, | |
builder: (context, snapshot) { | |
if (snapshot.connectionState == ConnectionState.done) { | |
return AspectRatio( | |
aspectRatio: _controller.value.aspectRatio, | |
child: VideoPlayer(_controller), | |
); | |
} else { | |
return const Center( | |
child: CircularProgressIndicator(), | |
); | |
} | |
}, | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: () { | |
setState(() { | |
if (_controller.value.isPlaying) { | |
_controller.pause(); | |
} else { | |
_controller.play(); | |
} | |
}); | |
}, | |
child: Icon( | |
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow, | |
), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:camera/camera.dart'; | |
import 'package:flutter/material.dart'; | |
import 'video_player_screen.dart'; | |
class VideoRecorderScreen extends StatefulWidget { | |
const VideoRecorderScreen({ | |
super.key, | |
}); | |
@override | |
State<VideoRecorderScreen> createState() => _VideoRecorderScreenState(); | |
} | |
class _VideoRecorderScreenState extends State<VideoRecorderScreen> { | |
late CameraController _controller; | |
late Future<void> _initializeControllerFuture; | |
bool _isRecording = false; | |
@override | |
void initState() { | |
super.initState(); | |
_initializeControllerFuture = _initCamera(); | |
} | |
Future<void> _initCamera() async { | |
final cameras = await availableCameras(); | |
final firstCamera = cameras.firstWhere((camera) { | |
return camera.lensDirection == CameraLensDirection.front; | |
}); | |
_controller = CameraController( | |
firstCamera, | |
ResolutionPreset.medium, | |
); | |
await _controller.initialize(); | |
} | |
@override | |
void dispose() { | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: const Text('Video recorder screen')), | |
body: FutureBuilder<void>( | |
future: _initializeControllerFuture, | |
builder: (context, snapshot) { | |
if (snapshot.connectionState == ConnectionState.done) { | |
return CameraPreview(_controller); | |
} else { | |
return const Center(child: CircularProgressIndicator()); | |
} | |
}, | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: () async { | |
try { | |
await _initializeControllerFuture; | |
if (!mounted) { | |
return; | |
} | |
if (_isRecording) { | |
final video = await _controller.stopVideoRecording(); | |
await Navigator.of(context).push( | |
MaterialPageRoute( | |
builder: (context) => VideoPlayerScreen( | |
videoPath: video.path, | |
), | |
), | |
); | |
} else { | |
await _controller.prepareForVideoRecording(); | |
await _controller.startVideoRecording(); | |
} | |
setState(() { | |
_isRecording = !_isRecording; | |
}); | |
} catch (e) { | |
print(e); | |
} | |
}, | |
child: Icon(_isRecording ? Icons.stop : Icons.circle), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment