Flutter屏幕录制插件screen_recorder的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter屏幕录制插件screen_recorder的使用

pub.dev Sponsoring likes popularity pub points


🚧 注意:此插件仍处于高度实验性阶段,API可能会发生变化。

screen_recorder 是一个用于创建Flutter小部件录制的插件。这些录制可以导出为GIF格式。它是一个纯Flutter/Dart实现,不依赖于任何原生或平台代码,因此可以在所有支持的平台上运行。

然而,请注意,GIF编码需要大量时间,在Web上尤其明显,几乎不可行。

🚀 快速开始

安装

首先,在你的pubspec.yaml文件中添加screen_recorder

dependencies:
  flutter:
    sdk: flutter
  screen_recorder: ^latest_version # 使用pub.dev上的最新版本

然后,在终端中运行flutter packages get

示例代码

下面是一个完整的示例demo,展示了如何使用screen_recorder进行屏幕录制并导出为GIF或帧。

import 'dart:typed_data';

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

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

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

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

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

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _recording = false;
  bool _exporting = false;
  ScreenRecorderController controller = ScreenRecorderController();
  bool get canExport => controller.exporter.hasFrames;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              if (_exporting)
                const Center(child: CircularProgressIndicator())
              else ...[
                ScreenRecorder(
                  height: 500,
                  width: 500,
                  controller: controller,
                  child: Container(
                    color: Colors.red,
                    child: const Center(
                      child: Text('Record Me!', style: TextStyle(fontSize: 24)),
                    ),
                  ),
                ),
                if (!_recording && !_exporting)
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ElevatedButton(
                      onPressed: () {
                        controller.start();
                        setState(() {
                          _recording = true;
                        });
                      },
                      child: const Text('Start'),
                    ),
                  ),
                if (_recording && !_exporting)
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ElevatedButton(
                      onPressed: () {
                        controller.stop();
                        setState(() {
                          _recording = false;
                        });
                      },
                      child: const Text('Stop'),
                    ),
                  ),
                if (canExport && !_exporting)
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ElevatedButton(
                      onPressed: () async {
                        setState(() {
                          _exporting = true;
                        });
                        var gif = await controller.exporter.exportGif();
                        if (gif == null) {
                          throw Exception();
                        }
                        setState(() => _exporting = false);
                        showDialog(
                          context: context as dynamic,
                          builder: (context) {
                            return AlertDialog(
                              content: Image.memory(Uint8List.fromList(gif)),
                            );
                          },
                        );
                      },
                      child: const Text('Export as GIF'),
                    ),
                  ),
                if (canExport && !_exporting)
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ElevatedButton(
                      onPressed: () {
                        setState(() {
                          controller.exporter.clear();
                        });
                      },
                      child: const Text('Clear recorded data'),
                    ),
                  )
              ]
            ],
          ),
        ),
      ),
    );
  }
}

在这个例子中,我们创建了一个简单的应用界面,其中包含一个可录制的小部件。用户可以通过点击按钮来启动和停止录制,并将录制的内容导出为GIF。

⚠️ 已知问题和限制

  • 平台视图在截图中是不可见的(如webviewGoogle Maps)。有关详细信息,请参阅此问题此问题
  • Web仅支持Flutter的CanvasKit渲染器,更多信息请参阅Flutter Web Renderer文档
  • 该包目前不支持音频录制,也不会在未来支持,除非在纯Dart/Flutter环境中成为可能。
  • 该包目前不支持视频导出,也不会在未来支持,除非在纯Dart/Flutter环境中成为可能。

转换GIF为视频

为了将GIF转换为视频,您可以尝试以下库之一。请注意,兼容性未经过测试。

Library Stats
ffmpeg_kit_flutter likes popularity pub points
flutter_video_compress likes popularity pub points
video_editor likes popularity pub points
video_trimmer likes popularity pub points
video_compress likes popularity pub points

关于作者

GitHub followers Twitter Follow

贡献者

希望这个指南对你有帮助!如果你有任何问题或建议,请随时提问。


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

1 回复

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


当然,以下是如何在Flutter项目中使用screen_recorder插件进行屏幕录制的代码示例。请注意,此示例假设您已经有一个Flutter项目,并且已经正确配置了screen_recorder插件。

首先,确保在pubspec.yaml文件中添加screen_recorder依赖项:

dependencies:
  flutter:
    sdk: flutter
  screen_recorder: ^x.y.z  # 请替换为最新版本号

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

接下来,您需要在您的Flutter项目中实现屏幕录制功能。以下是一个简单的示例,展示了如何使用screen_recorder插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ScreenRecorderExample(),
    );
  }
}

class ScreenRecorderExample extends StatefulWidget {
  @override
  _ScreenRecorderExampleState createState() => _ScreenRecorderExampleState();
}

class _ScreenRecorderExampleState extends State<ScreenRecorderExample> {
  late ScreenRecorderController _controller;
  bool _isRecording = false;

  @override
  void initState() {
    super.initState();
    _controller = ScreenRecorderController(
      // 可选:设置视频录制参数,例如比特率、帧率等
      videoBitrate: 5000000,
      frameRate: 30,
    );
    _controller.initialize().then((value) {
      if (!mounted) return;
      // 初始化完成后,可以在这里做一些UI更新
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Screen Recorder Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                if (_isRecording) {
                  await _controller.stopRecording();
                  _isRecording = false;
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Recording stopped.')),
                  );
                } else {
                  await _controller.startRecording('output_video.mp4');
                  _isRecording = true;
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Recording started.')),
                  );
                }
              },
              child: Text(_isRecording ? 'Stop Recording' : 'Start Recording'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮,用于开始和停止屏幕录制。以下是关键步骤:

  1. 初始化ScreenRecorderController:在initState方法中,我们初始化了ScreenRecorderController并设置了视频录制参数(可选)。

  2. 开始和停止录制:在按钮的onPressed回调中,我们检查当前是否正在录制,如果是,则停止录制;如果不是,则开始录制。录制文件的名称在startRecording方法中指定。

  3. UI更新:我们使用ScaffoldMessenger.of(context).showSnackBar来显示录制开始或停止的提示信息。

  4. 资源释放:在dispose方法中,我们释放了ScreenRecorderController资源。

请注意,由于screen_recorder插件可能依赖于特定的平台API,因此在实际使用中,您可能需要在iOS和Android项目中进行额外的配置。此外,录制屏幕可能需要用户权限,因此请确保在应用中请求并处理这些权限。

希望这个示例对您有所帮助!如果您有任何其他问题,请随时提问。

回到顶部