Flutter录音功能插件record_widget的使用

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

Flutter录音功能插件record_widget的使用

介绍

record_widget 是一个用于录制Flutter小部件渲染或任何实时变化的库。它通过将每一帧保存为PNG图像来实现录制,因为直接录制为视频目前还不支持。如果你需要将这些图像转换为视频,你需要安装FFMPEG来将多个图像文件转换为视频。

示例代码

下面是一个完整的示例Demo,展示了如何使用 record_widget 插件来录制Flutter小部件,并将其导出为视频文件。

安装库

首先,在 pubspec.yaml 文件中添加 record_widget 依赖:

flutter pub add record_widget

导入库

在Dart文件中导入 record_widget 库:

import 'package:record_widget/record_widget.dart';
import "package:path/path.dart" as path;

示例代码

以下是一个完整的示例代码,展示了如何使用 record_widget 插件来录制Flutter小部件,并将其导出为视频文件。

// ignore_for_file: unnecessary_brace_in_string_interps, avoid_print, non_constant_identifier_names

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:record_widget/record_widget.dart';
import "package:path/path.dart" as path;

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Record Widget',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Record Widget'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  RecordWidgetController controller = RecordWidgetController(
    pixelRatio: 1.0,
    directory_folder_render: Directory(path.join(Directory.current.path, "result")),
  );

  bool is_stop = false;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      controller.start();
      Timer.periodic(const Duration(microseconds: 1), task);
    });
  }

  void task(Timer timer) async {
    if (is_stop) {
      return;
    }
    _incrementCounter();
  }

  @override
  Widget build(BuildContext context) {
    return RecordWidgetRealtime(
      controller: controller,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text(
                'You have pushed the button this many times:',
              ),
              Center(
                child: Text(
                  '${_counter}',
                  style: Theme.of(context).textTheme.headlineMedium,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(10),
                child: ElevatedButton(
                  onPressed: () {
                    controller.start();
                  },
                  child: const Text('Start'),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(10),
                child: ElevatedButton(
                  onPressed: () {
                    controller.stop();
                  },
                  child: const Text('Stop'),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(10),
                child: ElevatedButton(
                  onPressed: () async {
                    controller.stop();
                    setState(() {
                      is_stop = true;
                    });

                    Future(() async {
                      bool is_saved = await controller.renderToVideoMp4(
                        outputFile: File(
                          path.join(
                            controller.directory_folder_render.path,
                            "output.mp4",
                          ),
                        ),
                      );

                      print(is_saved);

                      setState(() {
                        is_stop = false;
                      });
                    });
                  },
                  child: const Text('Render To Video'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

说明

  1. 初始化控制器RecordWidgetController 用于控制录制过程。你可以设置 pixelRatio 来调整录制的分辨率,directory_folder_render 用于指定保存图像的目录。
  2. 启动录制:在 initState 中,我们使用 WidgetsBinding.instance.addPostFrameCallback 来确保在小部件首次显示时自动启动录制。
  3. 停止录制:点击“Stop”按钮时,调用 controller.stop() 停止录制。
  4. 渲染为视频:点击“Render To Video”按钮时,调用 controller.renderToVideoMp4 将录制的图像转换为视频文件。这个过程是异步的,因此我们使用 Future 来处理。
  5. UI设计:界面上包含了一个计数器,每次点击“Start”按钮时,计数器会递增。你可以通过点击“Start”和“Stop”按钮来控制录制的开始和结束。

注意事项

  • 录制的内容会被保存为PNG图像文件,存放在 directory_folder_render 指定的目录中。
  • 如果需要将这些图像文件转换为视频文件,你需要安装FFMPEG,并使用以下命令进行转换:
    ffmpeg -f image2 -i %01d.png output.mp4
    

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

1 回复

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


当然,以下是如何在Flutter项目中使用record_widget插件来实现录音功能的示例代码。record_widget是一个方便的Flutter插件,用于处理音频录制。

步骤 1: 添加依赖

首先,在你的pubspec.yaml文件中添加record_widget依赖:

dependencies:
  flutter:
    sdk: flutter
  record_widget: ^x.y.z  # 请使用最新版本号替换x.y.z

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

步骤 2: 导入插件

在你的Dart文件中导入record_widget插件:

import 'package:record_widget/record_widget.dart';

步骤 3: 配置权限

AndroidManifest.xml中添加录音权限:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

步骤 4: 实现录音功能

在你的Flutter组件中,使用RecordWidget来实现录音功能。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:record_widget/record_widget.dart';
import 'package:permission_handler/permission_handler.dart';

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

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

class RecordScreen extends StatefulWidget {
  @override
  _RecordScreenState createState() => _RecordScreenState();
}

class _RecordScreenState extends State<RecordScreen> {
  final RecordController _recordController = RecordController();
  bool _isRecording = false;
  bool _hasPermission = false;

  @override
  void initState() {
    super.initState();
    _requestPermission();
  }

  Future<void> _requestPermission() async {
    var status = await Permission.microphone.status;
    if (!status.isGranted) {
      var result = await Permission.microphone.request();
      if (result.isGranted) {
        setState(() {
          _hasPermission = true;
        });
      }
    } else {
      setState(() {
        _hasPermission = true;
      });
    }
  }

  void _startRecording() {
    if (_isRecording) return;
    _recordController.startRecording();
    setState(() {
      _isRecording = true;
    });
  }

  void _stopRecording() {
    if (!_isRecording) return;
    _recordController.stopRecording().then((file) {
      // Handle the recorded file (e.g., save it, play it, etc.)
      print("Recording saved to: $file");
      setState(() {
        _isRecording = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Record Audio'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (!_hasPermission)
              Text('No permission to record audio.'),
            if (_hasPermission)
              RecordWidget(
                controller: _recordController,
                onStateChanged: (state) {
                  // Handle recording state changes if needed
                },
              ),
            SizedBox(height: 20),
            if (_hasPermission)
              ElevatedButton(
                onPressed: _isRecording ? _stopRecording : _startRecording,
                child: Text(_isRecording ? 'Stop Recording' : 'Start Recording'),
              ),
          ],
        ),
      ),
    );
  }
}

注意事项

  1. 权限处理:在实际应用中,你需要更细致地处理权限请求,比如向用户解释为什么需要这些权限,并在用户拒绝时给出适当的反馈。
  2. UI设计:示例中的UI设计非常简单,你可以根据实际需求进行改进。
  3. 录音文件处理:在_stopRecording方法中,你可以对录音文件进行进一步处理,比如上传到服务器或保存到本地存储。

这个示例展示了如何使用record_widget插件在Flutter中实现基本的录音功能。希望对你有所帮助!

回到顶部