### Install Plugin Dependency - Flutter pubspec.yaml Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Adds the audio_waveforms plugin to a Flutter project. After adding, delete the app from the device, run flutter clean and flutter pub get to apply changes. Replace with the plugin’s current version. ```yaml dependencies: audio_waveforms: ``` -------------------------------- ### Quick Start - Record Audio with Waveforms (Flutter) Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Demonstrates initializing RecorderController, checking permissions, starting/pausing/stopping recording, and rendering waveforms with the AudioWaveforms widget. The widget must be disposed when no longer needed. ```dart String? recordedFilePath; final RecorderController recorderController = RecorderController(); @override void initState() { super.initState(); recorderController.checkPermission(); } @override void dispose() { recorderController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ ElevatedButton( onPressed: () { if (recorderController.hasPermission) { recorderController.record(); // By default saves file with datetime as name. } }, child: Text('Record'), ), ElevatedButton( onPressed: () { recorderController.pause(); }, child: Text('Record'), ), ElevatedButton( onPressed: () async { if (recorderController.isRecording) { recordedFilePath = await recorderController.stop(); } }, child: Text('Stop'), ), AudioWaveforms( controller: recorderController, size: Size(300, 50), ), ], ); } ``` -------------------------------- ### Play Audio with PlayerController and AudioFileWaveforms Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md A quick example showing how to use `PlayerController` to prepare, play, pause, and stop audio files, and display waveforms using the `AudioFileWaveforms` widget. Includes necessary lifecycle methods for controller management. ```dart final PlayerController playerController = PlayerController(); @override void initState() { super.initState(); playerController.preparePlayer(path: '../myFile.mp3'); } @override void dispose() { playerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ ElevatedButton( onPressed: () { playerController.startPlayer(); }, child: Text('play'), ), ElevatedButton( onPressed: () { playerController.pausePlayer(); }, child: Text('pause'), ), ElevatedButton( onPressed: () { playerController.stopPlayer(); }, child: Text('Stop'), ), AudioFileWaveforms( controller: playerController, size: Size(300, 50), ), ], ); } ``` -------------------------------- ### Audio player controls in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Basic player controls including start, volume, playback rate, and seeking. All methods operate on the playerController instance. ```dart playerController.startPlayer(); ``` ```dart playerController.setVolume(1.0); ``` ```dart playerController.setRate(1.0); ``` ```dart playerController.seekTo(5000); ``` -------------------------------- ### Record to Custom Path (Flutter) Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Shows how to specify a custom file path when starting recording. Ensure the directory exists and the file extension matches the encoder/output format. ```dart recorderController.record(path: '../myFile.m4a'); ``` -------------------------------- ### Recording Audio with Live Waveforms in Flutter (Dart) Source: https://context7.com/simformsolutionspvtltd/audio_waveforms/llms.txt This snippet demonstrates using RecorderController to start, pause, and stop audio recording while displaying a real-time waveform visualization. It requires the audio_waveforms package and microphone permissions. Inputs include recording path and settings like sample rate and encoders; outputs the saved audio file path. Limitations include platform-specific encoder support and the need to handle permissions manually. ```Dart import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:flutter/material.dart'; class RecorderExample extends StatefulWidget { @override _RecorderExampleState createState() => _RecorderExampleState(); } class _RecorderExampleState extends State { final RecorderController recorderController = RecorderController(); String? recordedFilePath; @override void initState() { super.initState(); // Check microphone permission on initialization recorderController.checkPermission(); } @override void dispose() { recorderController.dispose(); super.dispose(); } Future _startRecording() async { if (recorderController.hasPermission) { // Start recording with custom path and settings await recorderController.record( path: '/path/to/audio.m4a', recorderSettings: const RecorderSettings( iosEncoderSetting: IosEncoderSetting( iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, ), androidEncoderSettings: AndroidEncoderSettings( androidEncoder: AndroidEncoder.aacLc, androidOutputFormat: AndroidOutputFormat.mpeg4, ), sampleRate: 44100, bitRate: 128000, ), ); } } Future _stopRecording() async { if (recorderController.isRecording) { recordedFilePath = await recorderController.stop(); print('Audio saved at: $recordedFilePath'); } } @override Widget build(BuildContext context) { return Column( children: [ AudioWaveforms( controller: recorderController, size: Size(300, 80), waveStyle: WaveStyle( waveColor: Colors.blue, showMiddleLine: true, middleLineColor: Colors.red, spacing: 8.0, waveThickness: 3.0, showDurationLabel: true, durationStyle: TextStyle(color: Colors.white, fontSize: 14), ), enableGesture: true, shouldCalculateScrolledPosition: true, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: _startRecording, child: Text('Record'), ), ElevatedButton( onPressed: () => recorderController.pause(), child: Text('Pause'), ), ElevatedButton( onPressed: _stopRecording, child: Text('Stop'), ), ], ), ], ); } } ``` -------------------------------- ### Styling Waveforms with Gradients (Dart) Source: https://context7.com/simformsolutionspvtltd/audio_waveforms/llms.txt This snippet shows how to configure both RecorderController and PlayerController in Flutter to display audio waveforms with custom styling such as colors, gradients, and line thickness. It imports audio_waveforms and uses ui.Gradient for linear gradient backgrounds. The code assumes a Flutter project with the audio_waveforms package installed and provides a sample UI layout without audio processing logic. ```dart import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:flutter/material.dart'; import 'dart:ui' as ui; class StyledWaveformExample extends StatelessWidget { final RecorderController recorderController = RecorderController(); final PlayerController playerController = PlayerController(); @override Widget build(BuildContext context) { return Column( children: [ // Recorder waveform with gradient AudioWaveforms( controller: recorderController, size: Size(300, 100), waveStyle: WaveStyle( waveColor: Colors.blue, showTop: true, showBottom: true, showMiddleLine: true, middleLineColor: Colors.red, middleLineThickness: 3.0, waveThickness: 5.0, spacing: 10.0, waveCap: StrokeCap.round, scaleFactor: 30.0, extendWaveform: true, showDurationLabel: true, showHourInDuration: false, durationStyle: TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold, ), durationLinesColor: Colors.white, durationLinesHeight: 20.0, labelSpacing: 16.0, durationTextPadding: 10.0, gradient: ui.Gradient.linear( Offset(0, 50), Offset(300, 50), [Colors.blue, Colors.purple, Colors.pink], ), ), ), // Player waveform with dual gradients AudioFileWaveforms( controller: playerController, size: Size(350, 80), waveformType: WaveformType.long, playerWaveStyle: PlayerWaveStyle( fixedWaveColor: Colors.white30, liveWaveColor: Colors.blueAccent, showTop: true, showBottom: true, spacing: 6.0, waveThickness: 4.0, waveCap: StrokeCap.round, showSeekLine: true, seekLineColor: Colors.yellow, seekLineThickness: 3.0, scaleFactor: 120.0, scrollScale: 1.3, fixedWaveGradient: ui.Gradient.linear( Offset(0, 0), Offset(350, 0), [Colors.grey.shade700, Colors.grey.shade500], ), liveWaveGradient: ui.Gradient.linear( Offset(0, 0), Offset(350, 0), [Colors.cyan, Colors.blue, Colors.indigo], ), ), ), ], ); } } ``` -------------------------------- ### Monitor Recording Events with Dart Source: https://context7.com/simformsolutionspvtltd/audio_waveforms/llms.txt This Dart code snippet demonstrates how to set up event listeners for real-time monitoring of audio recording states and duration using the `RecorderController`. It covers listening to current duration, recorder state changes, recording completion, and raw audio chunks. It also shows how to access controller properties and control the recording lifecycle, including starting, pausing, resuming, and stopping. ```dart import 'package:audio_waveforms/audio_waveforms.dart'; import 'dart:typed_data'; class RecordingEventsExample { final RecorderController recorderController = RecorderController(); void setupEventListeners() { // Listen to current duration updates (every 50ms) recorderController.onCurrentDuration.listen((duration) { final minutes = duration.inMinutes; final seconds = duration.inSeconds % 60; print('Recording duration: $minutes:${seconds.toString().padLeft(2, '0')}'); }); // Listen to recorder state changes recorderController.onRecorderStateChanged.listen((state) { switch (state) { case RecorderState.initialized: print('Recorder initialized and ready'); break; case RecorderState.recording: print('Recording in progress'); break; case RecorderState.paused: print('Recording paused'); break; case RecorderState.stopped: print('Recording stopped'); break; } }); // Listen to recording completion recorderController.onRecordingEnded.listen((duration) { print('Recording ended. Total duration: ${duration.inSeconds}s'); }); // Listen to audio chunks (raw audio bytes) recorderController.onAudioChunks.listen((Uint8List bytes) { print('Received audio chunk: ${bytes.length} bytes'); // Process raw audio data if needed }); // Access current state and properties print('Has microphone permission: ${recorderController.hasPermission}'); print('Is recording: ${recorderController.isRecording}'); print('Recorder state: ${recorderController.recorderState}'); print('Elapsed duration: ${recorderController.elapsedDuration}'); print('Recorded duration: ${recorderController.recordedDuration}'); print('Wave data: ${recorderController.waveData}'); // Get scrolled position (requires shouldCalculateScrolledPosition: true) recorderController.currentScrolledDuration.addListener(() { final scrolledMs = recorderController.currentScrolledDuration.value; print('Scrolled to position: ${scrolledMs}ms'); }); } Future controlRecording() async { // Start recording await recorderController.record(path: '/path/to/recording.m4a'); // Pause recording await recorderController.pause(); // Resume recording (call record again) await recorderController.record(); // Stop and get file path final filePath = await recorderController.stop(); print('Saved to: $filePath'); // Reset waveforms without stopping recorderController.reset(); // Refresh waveforms to initial position recorderController.refresh(); } } ``` -------------------------------- ### Control Audio Recording with RecorderController Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Functions to manage the audio recording process using the `recorderController`. Includes methods to start, pause, stop, reset, refresh, and dispose of the recorder. The `stop` method has a parameter to control waveform clearing. ```dart recorderController.record(); // If a path isn't provided, by default, the current date and time are set as the file name; m4a is used as the file extension. recorderController.pause(); // Pauses the recording. recorderController.stop(false); // Stops the current recording. recorderController.reset(); // Clears waveforms and duration legends from the AudioWaveforms widget. recorderController.refresh(); // Move back waveforms to original position if they have ever been scrolled. recorderController.dispose(); // Dispose the controller and recorder if haven't already stopped. ``` -------------------------------- ### Get audio duration in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Retrieves either the maximum duration or current playback position of the audio file in milliseconds. ```dart final fileLengthInDuration = await playerController.getDuration(DurationType.max); final currentDuration = await playerController.getDuration(DurationType.current); ``` -------------------------------- ### Listen to Recorder Events and Get Scrolled Duration Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Provides event streams from `recorderController` to monitor recording progress and state. Includes streams for current duration, recorder state changes, and recording end. Also details how to access the `currentScrolledDuration` for waveform scrolling. ```dart recorderController.onCurrentDuration.listen((duration){}); // Provides currently recorded duration of audio every 50 milliseconds. recorderController.onRecorderStateChanged.listen((state){}); // Provides current state of recorder. recorderController.onRecordingEnded.listen((duration){}); // Provided duration of the audio file after recording is ended. recorderController.currentScrolledDuration; // A ValueNotifier which provides current position of scrolled waveform with respect to middle line. ``` -------------------------------- ### Prepare player with waveform extraction in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Initializes player with waveform extraction enabled. Stores waveform data for consistent visualization across widget rebuilds. ```dart playerController.preparePlayer(shouldExtractWaveform: true); ``` -------------------------------- ### Configure Android minSdkVersion - android/app/build.gradle Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Sets the minimum Android SDK version to 23 to ensure recording APIs are available. Update the minSdkVersion line in android/app/build.gradle. ```gradle minSdkVersion 23 ``` -------------------------------- ### Customize AudioWaveforms Widget Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Demonstrates how to initialize and customize the `AudioWaveforms` widget. Key parameters include `size`, `shouldCalculateScrolledPosition`, `enableGesture`, and `waveStyle` for visual appearance and interactivity. ```dart AudioWaveforms( size: Size(MediaQuery.of(context).size.width, 200.0), // The size of your waveform widget. shouldCalculateScrolledPosition: true, // recorderController.currentScrolledDuration will notify only when this is enabled. enableGesture: true, // Enable/disable scrolling of the waveforms. waveStyle: WaveStyle(), // Customize how waveforms looks. ); ``` -------------------------------- ### Set iOS Deployment Target - ios/Podfile Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Sets the iOS platform to 13.0 or higher in the Podfile to satisfy the plugin’s minimum iOS version requirement. ```ruby platform :ios, '13.0' ``` -------------------------------- ### Load audio from assets in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Loads an audio file from app assets into memory and prepares the player. Requires file system access and asset bundle. ```dart File file = File('${appDirectory.path}/audio.mp3'); final audioFile = await rootBundle.load('assets/audio.mp3'); await file.writeAsBytes(audioFile.buffer.asUint8List()); playerController.preparePlayer(path: file.path); ``` -------------------------------- ### Set Encoders and Output Format (Flutter) Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Demonstrates configuring platform-specific encoders and output formats via RecorderSettings. Use IosEncoderSetting and AndroidEncoderSettings to pick supported codecs. Ensure file extension, sample rate, and bit rate are compatible with the chosen encoders and with MediaRecorder (Android) and AVAudioRecorder (iOS). ```dart recorderController.record( recorderSettings: const RecorderSettings( iosEncoderSetting: IosEncoderSetting( iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, ), androidEncoderSettings: AndroidEncoderSettings( androidEncoder: AndroidEncoder.aac, androidOutputFormat: AndroidOutputFormat.mpeg4, ), ), ); ``` -------------------------------- ### Configure iOS Microphone Usage - ios/Runner/Info.plist Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Declares microphone usage for iOS by adding the NSMicrophoneUsageDescription key to ios/Runner/Info.plist. Provide a user-facing description explaining why microphone access is needed. ```xml NSMicrophoneUsageDescription Add your own description. ``` -------------------------------- ### Control Player Behavior and Seeking in Dart Source: https://context7.com/simformsolutionspvtltd/audio_waveforms/llms.txt This code showcases advanced player controls including volume adjustment, playback rate, seeking, and finish modes. It requires the audio_waveforms package and a prepared player instance. Inputs are audio path and control parameters; outputs are updated player states and event notifications. Limitations include predefined update frequencies and dependency on platform audio support. ```dart import 'package:audio_waveforms/audio_waveforms.dart'; class AdvancedPlayerControls { final PlayerController playerController = PlayerController(); Future setupAdvancedControls() async { // Prepare the player await playerController.preparePlayer( path: '/path/to/audio.mp3', shouldExtractWaveform: true, ); // Set volume (0.0 to 1.0) await playerController.setVolume(0.8); // Set playback rate (0.5 = half speed, 2.0 = double speed) await playerController.setRate(1.5); // Set finish mode to control behavior when audio completes await playerController.setFinishMode( finishMode: FinishMode.loop, // Options: loop, pause, stop ); // Set update frequency for smoother animations playerController.updateFrequency = UpdateFrequency.high; // 50ms updates // Get duration information final maxDuration = await playerController.getDuration(DurationType.max); final currentDuration = await playerController.getDuration(DurationType.current); print('Total duration: ${maxDuration}ms, Current: ${currentDuration}ms'); // Seek to specific position (in milliseconds) await playerController.seekTo(30000); // Seek to 30 seconds // Listen to completion events playerController.onCompletion.listen((_) { print('Playback completed'); }); } Future controlMultiplePlayers() async { // Stop all players at once await playerController.stopAllPlayers(); // Pause all players at once await playerController.pauseAllPlayers(); // Release resources for this player await playerController.release(); } } ``` -------------------------------- ### Access RecorderController Properties Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Exposes properties of the `recorderController` to retrieve waveform data, durations, and recording status. Includes `waveData`, `elapsedDuration`, `recordedDuration`, `hasPermission`, `isRecording`, and `recorderState`. ```dart recorderController.waveData; // The waveform data is in the form of normalized peak power for iOS and normalized peak amplitude for Android. The values are between 0.0 and 1.0. recorderController.elapsedDuration; // Recorded duration of the file. recorderController.recordedDuration; // Duration of recorded audio file when recording has been stopped. Until recording has been stopped, this duration will be zero (Duration.zero). Also, once a new recording is started, this duration will be reset to zero. recorderController.hasPermission; // If we have microphone permission or not. recorderController.isRecording; // If the recorder is currently recording. recorderController.recorderState; // Current state of the recorder. ``` -------------------------------- ### Grant Android Recording Permission - AndroidManifest.xml Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Adds the RECORD_AUDIO permission to AndroidManifest.xml so the app can access the microphone. ```xml ``` -------------------------------- ### Dart: Play Audio with Synchronized Waveform Display Source: https://context7.com/simformsolutionspvtltd/audio_waveforms/llms.txt Prepares and plays an audio file while displaying its waveform. It handles loading audio from assets, extracting waveform data based on screen width, and provides UI controls for play, pause, and stop. Dependencies include `audio_waveforms` and `flutter`. ```dart import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:io'; class PlayerExample extends StatefulWidget { @override _PlayerExampleState createState() => _PlayerExampleState(); } class _PlayerExampleState extends State { final PlayerController playerController = PlayerController(); bool isPlayerReady = false; @override void initState() { super.initState(); _preparePlayer(); } Future _preparePlayer() async { // For loading from assets final appDirectory = Directory.systemTemp; final file = File('${appDirectory.path}/audio.mp3'); final audioFile = await rootBundle.load('assets/audio.mp3'); await file.writeAsBytes(audioFile.buffer.asUint8List()); // Calculate number of samples based on screen width final style = PlayerWaveStyle(spacing: 5.0); final screenWidth = MediaQuery.of(context).size.width; final samples = style.getSamplesForWidth(screenWidth); // Prepare player with waveform extraction await playerController.preparePlayer( path: file.path, shouldExtractWaveform: true, noOfSamples: samples, volume: 1.0, ); // Listen to player state changes playerController.onPlayerStateChanged.listen((state) { print('Player state: $state'); }); // Listen to duration changes playerController.onCurrentDurationChanged.listen((duration) { print('Current duration: ${duration}ms'); }); setState(() => isPlayerReady = true); } @override void dispose() { playerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (!isPlayerReady) { return Center(child: CircularProgressIndicator()); } return Column( children: [ AudioFileWaveforms( controller: playerController, size: Size(MediaQuery.of(context).size.width - 40, 100), waveformType: WaveformType.fitWidth, enableSeekGesture: true, playerWaveStyle: PlayerWaveStyle( fixedWaveColor: Colors.grey, liveWaveColor: Colors.blueAccent, spacing: 5.0, waveThickness: 3.0, showSeekLine: true, seekLineColor: Colors.white, seekLineThickness: 2.0, scaleFactor: 100.0, scrollScale: 1.2, ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( icon: Icon(Icons.play_arrow), onPressed: () async { await playerController.startPlayer(); }, ), IconButton( icon: Icon(Icons.pause), onPressed: () async { await playerController.pausePlayer(); }, ), IconButton( icon: Icon(Icons.stop), onPressed: () async { await playerController.stopPlayer(); }, ), ], ), ], ); } } ``` -------------------------------- ### Configure Waveform Types in Flutter Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Sets different waveform display modes - fitWidth fills specified width while long allows waveforms to extend beyond bounds. fitWidth enables tap and drag seeking while long only supports drag gestures. Requires sample calculation for optimal width fitting. ```dart AudioFileWaveforms( waveformType: WaveformType.fitWidth, ); ``` ```dart final style = PlayerWaveStyle(...); final samples = style.getSamplesForWidth(screenWidth / 2); await playerController.preparePlayer(noOfSamples: samples); ``` ```dart AudioFileWaveforms( waveformType: WaveformType.long, ); ``` -------------------------------- ### Waveform extraction in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Extracts waveform data separately from player initialization. Returns list of doubles for visualization and allows progress monitoring. ```dart final waveformData = await playerController.waveformExtraction.extractWaveformData(path: '../audioFile.mp3'); AudioFileWaveforms( ... waveformData: waveformData, ); ``` ```dart playerController.waveformExtraction.extractWaveformData(path: '../audioFile.mp3'); playerController.waveformExtraction.stopWaveformExtraction(); ``` -------------------------------- ### Manage Audio Player Resources in Flutter Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Controls native player resource management and multiple player instances. release() frees native player resources, stopAllPlayers() stops all players from any instance, pauseAllPlayers() pauses all players, and dispose() cleans up controller resources. ```dart playerController.release(); ``` ```dart playerController.stopAllPlayers(); ``` ```dart playerController.pauseAllPlayers(); ``` ```dart playerController.dispose(); ``` -------------------------------- ### Customize Audio Waveforms Widget in Flutter Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Configures waveform appearance and display behavior. continuousWaveform controls progressive vs complete display, while PlayerWaveStyle customizes visual elements including color, thickness, gradients, and completed/remaining portions. ```dart AudioFileWaveforms( continuousWaveform: true, playerWaveStyle: PlayerWaveStlye(), ); ``` -------------------------------- ### Extract Waveform Data Without Player Controller Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Enables waveform data extraction independent of audio playback using WaveformExtractionController. Supports path-based extraction with progress monitoring and extraction cancellation. Returns waveform data for custom visualization implementations. ```dart final waveformExtraction = WaveformExtractionController(); final waveformData = await waveformExtraction.extractWaveformData(path: '../audioFile.mp3'); AudioFileWaveforms( ... waveformData: waveformData, ); ``` ```dart waveformExtraction.extractWaveformData(path: '../audioFile.mp3'); /// When you want to stop extraction in between call waveformExtraction.stopWaveformExtraction(); ``` ```dart waveformExtraction.onCurrentExtractedWaveformData.listen((data) {}); // Provides latest data while extracting the waveforms. waveformExtraction.onExtractionProgress.listen((progress) {}); // Provides progress of the waveform extractions. ``` -------------------------------- ### Player event listeners in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Subscribes to various player events including state changes, playback position, waveform extraction progress, and completion. ```dart playerController.onPlayerStateChanged.listen((state) {}); playerController.onCurrentDurationChanged.listen((duration) {}); playerController.waveformExtraction.onCurrentExtractedWaveformData.listen((data) {}); playerController.waveformExtraction.onExtractionProgress.listen((progress) {}); playerController.onCompletion.listen((_){}); ``` -------------------------------- ### Extract and Cache Waveform Data in Dart Source: https://context7.com/simformsolutionspvtltd/audio_waveforms/llms.txt This code extracts waveform data from an audio file and caches it using SharedPreferences to avoid redundant computations. It depends on the audio_waveforms package for extraction, Dart's convert library for JSON, and shared_preferences for storage. Inputs include an audio file path and a cache key; outputs are a list of doubles for waveform samples. Limitation: Fixed to 200 samples and assumes audio file exists. ```dart import 'package:audio_waveforms/audio_waveforms.dart'; import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; class WaveformCacheExample { final WaveformExtractionController waveformExtraction = WaveformExtractionController(); Future> extractAndCache(String audioPath, String cacheKey) async { // Check if waveform data is already cached final prefs = await SharedPreferences.getInstance(); final cachedData = prefs.getString(cacheKey); if (cachedData != null) { // Return cached waveform data final List decoded = jsonDecode(cachedData); return decoded.map((e) => e as double).toList(); } // Listen to extraction progress waveformExtraction.onExtractionProgress.listen((progress) { print('Extraction progress: ${(progress * 100).toStringAsFixed(1)}%'); }); // Listen to extracted waveform data updates waveformExtraction.onCurrentExtractedWaveformData.listen((data) { print('Current extracted samples: ${data.length}'); }); // Extract waveform data final waveformData = await waveformExtraction.extractWaveformData( path: audioPath, noOfSamples: 200, ); // Cache the extracted data await prefs.setString(cacheKey, jsonEncode(waveformData)); return waveformData; } Future stopExtraction() async { // Stop extraction if needed await waveformExtraction.stopWaveformExtraction(); } } // Using cached waveform data with AudioFileWaveforms class CachedWaveformPlayer extends StatefulWidget { final String audioPath; const CachedWaveformPlayer({required this.audioPath}); @override _CachedWaveformPlayerState createState() => _CachedWaveformPlayerState(); } class _CachedWaveformPlayerState extends State { final PlayerController playerController = PlayerController(); List waveformData = []; bool isLoading = true; @override void initState() { super.initState(); _loadWaveformData(); } Future _loadWaveformData() async { final extractor = WaveformCacheExample(); waveformData = await extractor.extractAndCache( widget.audioPath, 'waveform_${widget.audioPath.hashCode}', ); // Prepare player without extracting waveforms again await playerController.preparePlayer( path: widget.audioPath, shouldExtractWaveform: false, ); setState(() => isLoading = false); } @override Widget build(BuildContext context) { if (isLoading) { return Center(child: CircularProgressIndicator()); } return AudioFileWaveforms( controller: playerController, size: Size(300, 80), waveformData: waveformData, playerWaveStyle: PlayerWaveStyle( fixedWaveColor: Colors.white54, liveWaveColor: Colors.white, spacing: 5, ), ); } @override void dispose() { playerController.dispose(); super.dispose(); } } ``` -------------------------------- ### Configure Waveform Scaling in Flutter Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Adjusts waveform data visualization scaling. scaleFactor amplifies small waveform values to desired height while scrollScale provides visual feedback during scrolling. Essential for proper waveform display visibility. ```dart PlayerWaveStyle( scaleFactor: 100, scrollScale: 1.2, ); ``` -------------------------------- ### Set player finish mode in Dart Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Configures player behavior when audio finishes. Options include loop, pause, and stop modes which control resource management. ```dart playerController.setFinishMode(finishMode: FinishMode.stop); ``` -------------------------------- ### Adjust Waveform Drawing Frequency (Flutter) Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Controls how often new waveform points are drawn during recording by updating RecorderController.updateFrequency. Lower durations yield smoother but more resource-intensive waveforms. ```dart recorderController.updateFrequency = const Duration(milliseconds: 100); ``` -------------------------------- ### Override iOS Audio Session (Flutter) Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Shows how to prevent the plugin from overriding the existing audio session on iOS by setting overrideAudioSession to false. Use this when you manage your own session and want to avoid interference. ```dart recorderController.overrideAudioSession = false; ``` -------------------------------- ### Control Waveform Animation Smoothness in Flutter Source: https://github.com/simformsolutionspvtltd/audio_waveforms/blob/main/README.md Adjusts update frequency for smooth waveform animations during audio seeking. High frequency updates every 50ms for smooth animation while low updates every 200ms which may cause lag. Choose based on device performance requirements. ```dart playerController.updateFrequency = UpdateFrequency.high; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.