audio_waveforms Flutter Package

repository·main·Indexed 43 days ago

https://github.com/simformsolutionspvtltd/audio_waveforms

A Flutter package for generating and visualizing audio waveforms during real-time recording or from existing audio files. It features RecorderController for capturing audio with customizable encoders, PlayerController for playback with seeking, and specialized widgets like AudioWaveforms and AudioFileWaveforms for UI visualization. Supports Android, iOS, and macOS with customizable styling via WaveStyle and PlayerWaveStyle.

Tokens
16K
Snippets
48
Records
62
Agent score
55%

What's inside audio_waveforms

  1. Overview of audio_waveforms features

    main

    The audio_waveforms package provides a comprehensive suite for audio visualization and manipulation in Flutter. Key capabilities include:

    • Recording: Capture audio with customizable encoder settings.
    • Real-time Visualization: View waveforms as audio is being recorded.
    • Playback: Play back audio files accompanied by waveform visualization.
    • Gesture Controls: Users can scroll through waveforms or seek to specific time positions using gestures.
    • Customization: Extensive styling options for colors, gradients, and general appearance.
    • Waveform Extraction: Ability to extract and save waveform data to optimize performance.
  2. How the key components work together

    main

    The package is built around several core controllers and widgets:

    • RecorderController: Manages audio recording operations and provides real-time waveform data for recording.
    • PlayerController: Manages audio playback operations and provides waveform data for playback.
    • WaveformExtractionController: A specialized controller to extract waveform data from audio files without needing a player dependency.
    • AudioWaveforms: The widget used to display waveforms during an active recording session.
    • AudioFileWaveforms: The widget used to display waveforms for playing back existing audio files.
    • WaveStyle & PlayerWaveStyle: Configuration objects used to customize the visual appearance (colors, thickness, etc.) of recording and playback waveforms respectively.
  3. Use WaveformExtractionController for standalone extraction

    main

    The WaveformExtractionController allows you to extract waveform data without needing a PlayerController. This is ideal for generating visualizations for lists or thumbnails where playback is not immediately required.

    Sampling Strategies

    When calling extractWaveformData, you must provide exactly one of the following:

    1. noOfSamples: A fixed integer for the total number of data points.
    2. noOfSamplesPerSecond: A dynamic calculation where total samples = noOfSamplesPerSecond * audioDurationInSeconds.

    If neither is provided, it defaults to noOfSamples: 100.

    final waveformExtraction = WaveformExtractionController();
    
    // Option 1: Fixed Sample Count
    final waveformData = await waveformExtraction.extractWaveformData(
      path: '/path/to/audio.mp3',
      noOfSamples: 200,
    );
    
    // Option 2: Samples Per Second (Dynamic)
    final waveformData = await waveformExtraction.extractWaveformData(
      path: '/path/to/audio.mp3',
      noOfSamplesPerSecond: 10,
    );
  4. Choose between FitWidth and Long waveform types

    main

    The waveformType property in AudioFileWaveforms determines how the audio is visualized:

    1. WaveformType.fitWidth: The entire audio waveform is scaled to fit exactly within the widget's width. This is ideal for seeing the whole track at once. Supports tap and drag seeking.
    2. WaveformType.long: Waveforms extend beyond the widget bounds. The completed part appears on the left and the remaining part on the right. This is better for long audio files. Supports drag seeking with a middle seek line.
    // Fit entire audio into widget width
    AudioFileWaveforms(
      controller: playerController,
      size: Size(300, 80),
      waveformType: WaveformType.fitWidth,
    )
    
    // Waveform extends beyond widget bounds
    AudioFileWaveforms(
      controller: playerController,
      size: Size(300, 80),
      waveformType: WaveformType.long,
    )
  5. Play audio using PlayerController

    main

    To play audio with waveform visualization, use the PlayerController.

    1. Initialize: Create an instance of PlayerController.
    2. Prepare: Call preparePlayer() with the file path. Set shouldExtractWaveform: true to generate the waveform.
    3. Configure Granularity: You can control waveform density using either noOfSamples (fixed count) or noOfSamplesPerSecond (dynamic). Do not use both.
    4. Start: Call startPlayer(). You can use FinishMode.loop to loop the audio.
    5. Display: Use the AudioFileWaveforms widget with the controller.
    6. Cleanup: Call dispose() when finished.
    final playerController = PlayerController();
    
    // Prepare with fixed sample count
    await playerController.preparePlayer(
      path: 'path/to/audio.mp3',
      shouldExtractWaveform: true,
      noOfSamples: 200,
    );
    
    // Start playing
    await playerController.startPlayer();
    
    // Display waveforms
    AudioFileWaveforms(
      controller: playerController,
      size: Size(300, 50),
    )
    
    // Stop and cleanup
    await playerController.stopPlayer();
    playerController.dispose();
  6. Cache waveform data for performance

    main

    Extracting waveforms is a heavy operation. To improve performance, extract the waveform once and save the List<double> to local storage. On subsequent loads, check your cache first before calling extractWaveformData.

    // 1. Extract and save
    final waveformData = await waveformExtraction.extractWaveformData(
      path: audioPath,
      noOfSamples: 100,
    );
    await saveToLocalStorage(audioPath, waveformData);
    
    // 2. Retrieve and use
    final cachedData = await loadFromLocalStorage(audioPath);
    if (cachedData != null) {
      AudioFileWaveforms(
        controller: playerController,
        size: Size(300, 80),
        waveformData: cachedData,
      );
    } else {
      // Fallback to extraction
      final data = await waveformExtraction.extractWaveformData(path: audioPath);
      await saveToLocalStorage(audioPath, data);
    }
  7. Configure Android, iOS, and macOS for audio_waveforms

    main

    The package requires specific platform configurations for microphone access and minimum SDK versions.

    Android

    1. Update android/app/build.gradle to set minSdkVersion 23 or higher.
    2. Add the following permission to AndroidManifest.xml:
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    iOS

    1. Add a microphone usage description to ios/Runner/Info.plist:
    <key>NSMicrophoneUsageDescription</key>
    <string>This app requires microphone access to record audio.</string>
    1. Set the minimum iOS version to 13.0 in your Podfile:
    platform :ios, '13.0'

    macOS

    1. Add a microphone usage description to macos/Runner/Info.plist:
    <key>NSMicrophoneUsageDescription</key>
    <string>This app requires microphone access to record audio.</string>
    1. Set the minimum macOS version to 10.14 in your macos/Podfile:
    platform :osx, '10.14'
  8. Record audio using RecorderController

    main

    To record audio, use the RecorderController. You must check for permissions before starting.

    1. Initialize: Create an instance of RecorderController.
    2. Permissions: Call checkPermission() and verify hasPermission.
    3. Record: Call record(). You can optionally provide a custom path.
    4. Pause/Stop: Use pause() to temporarily stop or stop() to finish recording and retrieve the file path.
    5. Display: Use the AudioWaveforms widget with the controller to show real-time waveforms.
    6. Cleanup: Always call dispose() on the controller when the widget is destroyed.
    import 'package:audio_waveforms/audio_waveforms.dart';
    
    // 1. Create controller
    final recorderController = RecorderController();
    
    // 2. Check permissions
    await recorderController.checkPermission();
    
    if (recorderController.hasPermission) {
      // 3. Start recording
      await recorderController.record();
    }
    
    // 4. Display waveforms
    AudioWaveforms(
      controller: recorderController,
      size: Size(300, 50),
    )
    
    // 5. Stop recording
    String? path = await recorderController.stop();
    
    // 6. Dispose
    recorderController.dispose();
  9. Migrate to version 2.0.0: WaveformExtractionController

    main

    In version 2.0.0, WaveformExtractionController was decoupled from PlayerController. You can now use it as a standalone controller or access it via a PlayerController instance.

    // Option 1: Use standalone controller
    final waveformExtraction = WaveformExtractionController();
    await waveformExtraction.extractWaveformData(path: audioPath);
    
    // Option 2: Access through PlayerController
    final playerController = PlayerController();
    await playerController.waveformExtraction.extractWaveformData(path: audioPath);
  10. Customize the iOS launch screen assets

    main

    To change the image displayed during the app's launch on iOS, you can either replace the existing image files directly in the example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode for a more visual approach.

    Using Xcode:

    1. Open the iOS project workspace using the command: open ios/Runner.xcworkspace.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired image assets into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace