搜尋套件、儲存庫與 APP 分類

waveform_recorder 封面
套件詳情v2.0.0

waveform_recorder

一個用於實時波形視覺化錄音的 Flutter 套件,非常適合聊天應用中的語音訊息和音頻錄製功能。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
1.7萬
喜歡數
53
Pub 分數
160

安裝套件

flutter pub add waveform_recorder

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

一個 Flutter 套件,可實現音訊錄製並即時顯示波形圖,專為需要語音訊息或音訊輸入功能的應用程式設計。它支援 Android、iOS、Web、macOS、Windows 和 Linux 多個平台,提供在錄製過程中具備視覺反饋的流暢使用者體驗。該套件可無縫整合到聊天或通訊應用中,讓使用者在說話時看到自己的語音波形。基於效能與跨平台一致性而建構,它以最少的設定簡化了音訊錄製功能的實作。

適用情境

  • 聊天應用中的語音訊息
  • 音頻筆記
  • 即時語音反饋
  • 播客錄製介面
  • 基於語音的互動遊戲
  • 即時音訊串流預覽

主要特色

  • 即時波形可視化
  • 跨平台支援
  • 簡單的 API 用於記錄
  • 錄製期間的視覺反饋
  • 低延遲音頻處理
  • 內建播放控制

適合對象

  • 開發聊天應用的開發者
  • 語音功能工具的創作者
  • 具有音訊輸入的教育應用程式
  • 音頻錄製原型
  • 需要直覺音訊使用者介面的應用程式

使用建議

  • 所有平台都需要麥克風權限
  • Web 支援可能有瀏覽器限制
  • 大型錄音可能會影響記憶體使用
  • 效能會在低階裝置上有所差異
  • 波形外觀的自訂選項有限
  • 依賴於底層平台的音訊API

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

The waveform_recorder package provides a widget to show a waveform as an audio stream is being recorded in the style of recent AI chat packages.

Screenshot of waveform_recorder in
action

Setup

For this package to work, you'll need to set up the underlying record package according to the setup and permission instructions.

Usage

The main entry point for this package is the WaveformRecorder widget, which requires an instance of the WaveformRecorderController to start/stop recording. Here's an example of using the recorder to record audio and then allowing the user to play it back:

import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:waveform_recorder/waveform_recorder.dart';

void main() => runApp(const MyApp());

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _textController = TextEditingController();
  final _waveController = WaveformRecorderController();

  @override
  void dispose() {
    _textController.dispose();
    _waveController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: const Text('WaveForm Example')),
          body: ListenableBuilder(
            listenable: _waveController,
            builder: (context, _) => Column(
              children: [
                Expanded(
                  child: Center(
                    child: OutlinedButton(
                      onPressed: !_waveController.isRecording &&
                              _waveController.file != null
                          ? _playRecording
                          : null,
                      child: const Text('Play'),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Row(
                    children: [
                      Expanded(
                        child: DecoratedBox(
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                            borderRadius: BorderRadius.circular(8),
                          ),
                          child: _waveController.isRecording
                              ? WaveformRecorder(
                                  height: 48,
                                  controller: _waveController,
                                  onRecordingStopped: _onRecordingStopped,
                                )
                              : TextField(
                                  controller: _textController,
                                  maxLines: 1,
                                  decoration: const InputDecoration(
                                    border: InputBorder.none,
                                    contentPadding: EdgeInsets.symmetric(
                                      horizontal: 8,
                                    ),
                                  ),
                                ),
                        ),
                      ),
                      const Gap(8),
                      IconButton(
                        icon: Icon(
                          _waveController.isRecording ? Icons.stop : Icons.mic,
                        ),
                        onPressed: _toggleRecording,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      );

  Future<void> _toggleRecording() => switch (_waveController.isRecording) {
        true => _waveController.stopRecording(),
        false => _waveController.startRecording(),
      };

  Future<void> _onRecordingStopped() async {
    final file = _waveController.file;
    if (file == null) return;

    _textController.text = ''
        '${file.name}: '
        '${_waveController.length.inMilliseconds / 1000} seconds';

    debugPrint('XFile properties:');
    debugPrint('  path: ${file.path}');
    debugPrint('  name: ${file.name}');
    debugPrint('  mimeType: ${file.mimeType}');
  }

  Future<void> _playRecording() async {
    final file = _waveController.file;
    if (file == null) return;
    final source = kIsWeb ? UrlSource(file.path) : DeviceFileSource(file.path);
    await AudioPlayer().play(source);
  }
}
Usage Considerations

For all platforms except the web, the output of a record operation is a file on your hard drive; it's your app's responsibility to remove this temp file when it's done with it. When executing on the web, the file (an instance of the XFile type from the cross_file package) of the recorded audio will contain a path to a blob URL but otherwise, it will be a file in the file system. You can get the path to that file from WaveformRecorderController.file.path, e.g.

  Future<void> _deleteRecording() async {
    final file = _waveController.file;
    if (file == null) return;
    if (!kIsWeb) await File(file.path).delete();
  }

Feedback

Your feedback via issues or PRs is welcome!

所屬分類

依賴

依賴清單 6 項

原始碼儲存庫

使用此套件的專案