Grabación y reproducción de video en Flutter

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.

Etiquetas: Flutter Grabación de video Reproducción de video cámara

Publicado el 8-25 00:04