パッケージ、リポジトリ、アプリカテゴリを検索

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
  • 録画中の視覚フィードバック
  • 低遅延オーディオ処理
  • 内蔵再生コントロール

適している対象

  • チャットアプリを開発する開発者
  • 音声対応ツールの開発者
  • 音声入力付きの教育アプリ
  • オーディオ録音プロトタイプ
  • 直感的なオーディオUIを必要とするアプリ

注意事項

  • すべてのプラットフォームでマイク権限が必要です
  • 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 件

ソースリポジトリ

このパッケージを使用しているプロジェクト