voice_audio_visualizer 1.0.0 copy "voice_audio_visualizer: ^1.0.0" to clipboard
voice_audio_visualizer: ^1.0.0 copied to clipboard

A comprehensive Flutter audio package with recording, playback, editing, and waveform visualization. Features customizable widgets, voice message bubbles, and cross-platform support.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Audio Visualizer Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Audio Visualizer'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildSection(
            context,
            'Recording',
            'Record audio with live waveform',
            Icons.mic,
            () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const RecorderDemo()),
            ),
          ),
          _buildSection(
            context,
            'Playback',
            'Play audio with waveform visualization',
            Icons.play_circle,
            () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const PlayerDemo()),
            ),
          ),
          _buildSection(
            context,
            'Voice Messages',
            'Chat-style voice message bubbles',
            Icons.chat_bubble,
            () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const VoiceBubbleDemo()),
            ),
          ),
          _buildSection(
            context,
            'Editor',
            'Edit audio with trim and delete',
            Icons.content_cut,
            () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const EditorDemo()),
            ),
          ),
          _buildSection(
            context,
            'Waveform Styles',
            'Different waveform visualizations',
            Icons.waves,
            () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const WaveformStylesDemo()),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSection(
    BuildContext context,
    String title,
    String subtitle,
    IconData icon,
    VoidCallback onTap,
  ) {
    return Card(
      margin: const EdgeInsets.only(bottom: 12),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: Theme.of(context).colorScheme.primaryContainer,
          child: Icon(icon, color: Theme.of(context).colorScheme.primary),
        ),
        title: Text(title),
        subtitle: Text(subtitle),
        trailing: const Icon(Icons.chevron_right),
        onTap: onTap,
      ),
    );
  }
}

// Recording Demo
class RecorderDemo extends StatefulWidget {
  const RecorderDemo({super.key});

  @override
  State<RecorderDemo> createState() => _RecorderDemoState();
}

class _RecorderDemoState extends State<RecorderDemo> {
  AudioFile? _recordedFile;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Recording Demo')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            AudioRecorderWidget(
              waveformStyle: const WaveformStyle(
                waveColor: Colors.blue,
                type: WaveformType.bars,
              ),
              onRecordingComplete: (file) {
                setState(() => _recordedFile = file);
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Recorded: ${file.formattedDuration}')),
                );
              },
            ),
            if (_recordedFile != null) ...[
              const SizedBox(height: 24),
              const Text('Recorded Audio:', style: TextStyle(fontWeight: FontWeight.bold)),
              const SizedBox(height: 8),
              AudioPlayerWidget(
                filePath: _recordedFile!.path,
                waveformData: _recordedFile!.waveformData,
              ),
            ],
          ],
        ),
      ),
    );
  }
}

// Player Demo
class PlayerDemo extends StatelessWidget {
  const PlayerDemo({super.key});

  @override
  Widget build(BuildContext context) {
    // Using placeholder waveform for demo
    final sampleWaveform = WaveformExtractor.generatePlaceholder(60);

    return Scaffold(
      appBar: AppBar(title: const Text('Player Demo')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            const Text(
              'Audio Player with Waveform',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 16),
            AudioPlayerWidget(
              // Replace with actual audio URL
              url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
              waveformData: sampleWaveform.samples,
              waveformStyle: const WaveformStyle(
                waveColor: Colors.grey,
                playedColor: Colors.blue,
                type: WaveformType.bars,
              ),
              showSpeedControl: true,
            ),
          ],
        ),
      ),
    );
  }
}

// Voice Bubble Demo
class VoiceBubbleDemo extends StatelessWidget {
  const VoiceBubbleDemo({super.key});

  @override
  Widget build(BuildContext context) {
    final sampleWaveform = WaveformExtractor.generatePlaceholder(40);

    return Scaffold(
      appBar: AppBar(title: const Text('Voice Messages')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          const Text('WhatsApp Style', style: TextStyle(fontWeight: FontWeight.bold)),
          const SizedBox(height: 8),
          VoiceMessageBubble(
            url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
            waveformData: sampleWaveform.samples,
            style: VoiceBubbleStyle.whatsApp,
            isSent: true,
            timestamp: DateTime.now(),
          ),
          const SizedBox(height: 24),
          const Text('Telegram Style', style: TextStyle(fontWeight: FontWeight.bold)),
          const SizedBox(height: 8),
          VoiceMessageBubble(
            url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
            waveformData: sampleWaveform.samples,
            style: VoiceBubbleStyle.telegram,
            isSent: false,
            timestamp: DateTime.now().subtract(const Duration(hours: 2)),
          ),
          const SizedBox(height: 24),
          const Text('Custom Style', style: TextStyle(fontWeight: FontWeight.bold)),
          const SizedBox(height: 8),
          VoiceMessageBubble(
            url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
            waveformData: sampleWaveform.samples,
            style: const VoiceBubbleStyle(
              bubbleColor: Color(0xFFE8EAF6),
              iconColor: Color(0xFF3F51B5),
              borderRadius: 20,
            ),
            waveformStyle: const WaveformStyle(
              waveColor: Color(0xFFBDBDBD),
              playedColor: Color(0xFF3F51B5),
              type: WaveformType.rounded,
            ),
            isSent: true,
          ),
        ],
      ),
    );
  }
}

// Editor Demo
class EditorDemo extends StatelessWidget {
  const EditorDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Audio Editor')),
      body: const Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Audio Editor',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 8),
            Text(
              'Drag on the waveform to select a region, then use the controls to trim or delete.',
              style: TextStyle(color: Colors.grey),
            ),
            SizedBox(height: 16),
            // AudioEditorWidget requires a local file path
            // For demo, you would record first then edit
            Center(
              child: Text(
                'Record an audio first, then edit it here.',
                style: TextStyle(fontStyle: FontStyle.italic),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// Waveform Styles Demo
class WaveformStylesDemo extends StatelessWidget {
  const WaveformStylesDemo({super.key});

  @override
  Widget build(BuildContext context) {
    final samples = WaveformExtractor.generatePlaceholder(80).samples;

    return Scaffold(
      appBar: AppBar(title: const Text('Waveform Styles')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildWaveformDemo('Bars (Default)', samples, WaveformType.bars),
          _buildWaveformDemo('Line', samples, WaveformType.line),
          _buildWaveformDemo('Rounded', samples, WaveformType.rounded),
          _buildWaveformDemo('Mirrored', samples, WaveformType.mirrored),
          _buildWaveformDemo('SoundCloud', samples, WaveformType.soundCloud),
        ],
      ),
    );
  }

  Widget _buildWaveformDemo(String title, List<double> samples, WaveformType type) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
        const SizedBox(height: 8),
        Container(
          height: 60,
          decoration: BoxDecoration(
            color: Colors.grey[100],
            borderRadius: BorderRadius.circular(8),
          ),
          child: AudioWaveform(
            samples: samples,
            progress: 0.4,
            style: WaveformStyle(
              waveColor: Colors.grey,
              playedColor: Colors.blue,
              type: type,
            ),
            height: 60,
          ),
        ),
        const SizedBox(height: 24),
      ],
    );
  }
}
4
likes
130
points
14
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A comprehensive Flutter audio package with recording, playback, editing, and waveform visualization. Features customizable widgets, voice message bubbles, and cross-platform support.

Repository (GitHub)
View/report issues

Topics

#audio #waveform #recording #voice-message #audio-player

License

MIT (license)

Dependencies

flutter, just_audio, path, path_provider, permission_handler, record, uuid

More

Packages that depend on voice_audio_visualizer