En Flutter, es fácil implementar una función de grabación y visualización de video. Este tutorial nos muestra cómo crear una aplicación que registre y reproduzca video utilizando los paquetes camera y video_player.
Introducción
En este tutorial, crearemos una aplicación Flutter que permita grabar y reproducir video. Los videos garbados pueden ser utilizados, por ejemplo, para su上传 a un servidor remoto.
Primero, crearemos una página para mostrar la entrada de la cámara y grabar un video. Después de grabar el video, abriremos otra página para reproducirlo, permitiendo al usuario visualizar o cerrar el video.
Para comenzar, necesitaremos crear un proyecto Flutter nuevo y agregar las dependencias necesarias al archivo pubspec.yaml. El contenido del archivo debería ser similar al siguiente:
name: flutter_video
description: Flutter Video Flow
publish_to: 'none' # Quita esta línea si planeas publicar en pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
camera: ^0.9.4+3
video_player: ^2.2.6
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^1.0.0
flutter:
uses-material-design: true
También necesitaremos actualizar los archivos específicos de iOS y Android para habilitar el acceso a la cámara y el micrófono.
Configuración para iOS
Agrega el siguiente código al archivo ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>Needed for recording videos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Needed for recording videos.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Configuración para Android
Asegúrate de que el minSdkVersion esté establecido en 21 en el archivo android/app/build.gradle.
Después de agregar las dependencias, ejecuta flutter pub get.
Uso del paquete camera para mostrar la entrada de la cámara
Creamos una nueva clase llamada CameraPage para mostrar la vista de la cámara y el botón de grabación.
import 'package:flutter/material.dart';
import 'package:flutter_video/camera_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: CameraPage(),
);
}
}
La clase CameraPage se implementa de la siguiente manera:
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
class CameraPage extends StatefulWidget {
const CameraPage({Key? key}) : super(key: key);
@override
_CameraPageState createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> {
bool _isLoading = true;
late CameraController _cameraController;
@override
void dispose() {
_cameraController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
_initCamera();
}
Future<void> _initCamera() async {
final cameras = await availableCameras();
final front = cameras.firstWhere(
(camera) => camera.lensDirection == CameraLensDirection.front,
orElse: () => cameras.first,
);
_cameraController = CameraController(front, ResolutionPreset.max);
await _cameraController.initialize();
setState(() => _isLoading = false);
}
@override
Widget build(BuildContext context) {
if (_isLoading) {
return Container(
color: Colors.white,
child: const Center(
child: CircularProgressIndicator(),
),
);
} else {
return Stack(
alignment: Alignment.bottomCenter,
children: [
CameraPreview(_cameraController),
Padding(
padding: const EdgeInsets.all(25),
child: FloatingActionButton(
backgroundColor: Colors.red,
child: Icon(_isRecording ? Icons.stop : Icons.circle),
onPressed: () => _recordVideo(),
),
),
],
);
}
}
bool _isRecording = false;
Future<void> _recordVideo() async {
if (_isRecording) {
final file = await _cameraController.stopVideoRecording();
setState(() => _isRecording = false);
final route = MaterialPageRoute(
fullscreenDialog: true,
builder: (_) => VideoPage(filePath: file.path),
);
Navigator.push(context, route);
} else {
await _cameraController.prepareForVideoRecording();
await _cameraController.startVideoRecording();
setState(() => _isRecording = true);
}
}
}
Reproducción del video grabado
Creamos una nueva clase llamada VideoPage para reproducir el video grabado:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPage extends StatefulWidget {
final String filePath;
const VideoPage({Key? key, required this.filePath}) : super(key: key);
@override
_VideoPageState createState() => _VideoPageState();
}
class _VideoPageState extends State<VideoPage> {
late VideoPlayerController _videoPlayerController;
@override
void dispose() {
_videoPlayerController.dispose();
super.dispose();
}
Future<void> _initVideoPlayer() async {
_videoPlayerController = VideoPlayerController.file(File(widget.filePath));
await _videoPlayerController.initialize();
await _videoPlayerController.setLooping(true);
await _videoPlayerController.play();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Vista previa'),
elevation: 0,
backgroundColor: Colors.black26,
actions: [
IconButton(
icon: const Icon(Icons.check),
onPressed: () {
// Implementación para guardar o compartir el video
},
),
],
),
extendBodyBehindAppBar: true,
body: FutureBuilder(
future: _initVideoPlayer(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return VideoPlayer(_videoPlayerController);
}
},
),
);
}
}
Conclusión
En este tutorial, utilizamos los paquetes camera y video_player para crear una aplciación Flutter que permita grabar y reproducir video. La implementación incluye una vista previa de la cámara, un botón para grabación y una pantalla para reproducir el video grabado.