Flutter屏幕录制插件screen_record_plus的使用

Flutter屏幕录制插件screen_record_plus的使用

简介

screen_recorder 包获取灵感,并修改其机制以解决现有的一些不足。

特性

  • ✅ 录制屏幕并导出为mp4格式。

演示

应用演示

存储位置

示例代码

以下是使用 screen_record_plus 插件的完整示例代码:

import 'dart:io';

import 'package:ffmpeg_kit_flutter/ffmpeg_kit_config.dart';
import 'package:flutter/material.dart';
import 'package:screen_record_plus/screen_record_plus.dart';

import 'animated_screen.dart';
import 'sample_animation.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

// 定义录制状态枚举
enum RecordStatus { none, recording, stop, exporting }

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  RecordStatus status = RecordStatus.none;

  // 初始化ScreenRecorderController
  ScreenRecorderController controller = ScreenRecorderController(
    binding: WidgetsFlutterBinding.ensureInitialized(),
    skipFramesBetweenCaptures: 0,
    pixelRatio: 3,
  );

  // 检查是否可以导出
  bool get canExport => controller.exporter.hasFrames;
  double percentExport = 0;

  // 设置录制时长
  Duration duration = const Duration(seconds: 3);

  File? testFile;

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 显示录制区域
              ScreenRecorder(
                height: MediaQuery.of(context).size.height - 300,
                width: MediaQuery.of(context).size.width,
                controller: controller,
                child: const UnconstrainedBox(
                  child: SizedBox(
                    height: 300,
                    width: 300,
                    child: SampleAnimation(),
                  ),
                ),
              ),
              // 如果当前状态为none,显示开始录制按钮
              if (status == RecordStatus.none)
                ElevatedButton(
                  onPressed: () async {
                    await controller.start();
                    setState(() {
                      status = RecordStatus.recording;
                    });
                  },
                  child: const Text('开始录制'),
                ),
              // 如果当前状态为recording,显示停止录制按钮
              if (status == RecordStatus.recording)
                ElevatedButton(
                  onPressed: () async {
                    controller.stop();
                    setState(() {
                      status = RecordStatus.stop;
                    });
                  },
                  child: const Text('停止录制'),
                ),
              // 如果当前状态为stop,显示导出视频按钮
              if (status == RecordStatus.stop)
                ElevatedButton(
                  onPressed: () async {
                    File? file = await controller.exporter.exportVideo(onProgress: (value) {
                      print(value);
                    });
                    await showDialog(
                      context: context,
                      builder: (context) {
                        return AnimatedScreen(
                          file: file!,
                        );
                      },
                    );
                    setState(() {
                      status = RecordStatus.none;
                    });
                  },
                  child: const Text('导出视频'),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter屏幕录制插件screen_record_plus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter屏幕录制插件screen_record_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用screen_record_plus插件进行屏幕录制的代码示例。

首先,确保你已经在pubspec.yaml文件中添加了screen_record_plus依赖:

dependencies:
  flutter:
    sdk: flutter
  screen_record_plus: ^最新版本号 # 请替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用screen_record_plus插件进行屏幕录制。

1. 导入包

在你的Dart文件中导入screen_record_plus包:

import 'package:screen_record_plus/screen_record_plus.dart';
import 'package:flutter/material.dart';

2. 请求权限

在Android和iOS上,屏幕录制需要相应的权限。你可以在应用启动时请求这些权限。以下是一个简单的权限请求示例:

Future<void> requestPermissions() async {
  bool hasPermission = await ScreenRecordPlus.requestPermissions();
  if (!hasPermission) {
    // 处理权限被拒绝的情况
    throw Exception("Screen record permission denied");
  }
}

3. 开始和停止录制

你可以使用ScreenRecordPlus提供的startstop方法来开始和停止屏幕录制。以下是一个简单的示例,展示了如何在按钮点击时开始和停止录制:

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ScreenRecordPlus? _screenRecordPlus;
  bool _isRecording = false;

  @override
  void initState() {
    super.initState();
    _screenRecordPlus = ScreenRecordPlus();
    requestPermissions().then((_) {
      // 权限请求成功后,可以执行其他初始化操作
    }).catchError((error) {
      // 处理权限请求错误
      print(error);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screen Record Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              if (!_isRecording) {
                // 开始录制
                String? filePath = await _screenRecordPlus!.start(
                  outputPath: "/sdcard/screen_record.mp4", // 指定输出路径(Android)
                  // iOS上不需要指定输出路径,录制文件将保存在应用的临时目录中
                );
                print("Recording started. File path: $filePath");
                setState(() {
                  _isRecording = true;
                });
              } else {
                // 停止录制
                String? filePath = await _screenRecordPlus!.stop();
                print("Recording stopped. File path: $filePath");
                setState(() {
                  _isRecording = false;
                });
              }
            },
            child: Text(_isRecording ? 'Stop Recording' : 'Start Recording'),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _screenRecordPlus?.dispose();
    super.dispose();
  }
}

注意事项

  1. 权限处理:在实际应用中,你应该更细致地处理权限请求的结果,比如向用户解释为什么需要这个权限,并在权限被拒绝时提供重新请求的机制。
  2. 路径处理:在Android上,你需要确保指定的输出路径是可写的。在iOS上,你通常不需要指定输出路径,因为录制文件将自动保存在应用的临时目录中。
  3. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,比如处理屏幕录制过程中可能出现的异常。

这个示例展示了如何使用screen_record_plus插件进行基本的屏幕录制操作。根据你的具体需求,你可能需要进一步自定义和扩展这个示例。

回到顶部