Search code examples
flutteraudio-player

audio_waveforms can't find audio file


I am using audio_waveforms to handle audio messages inside my chat app. I am facing a problem where when I try to call await player.preparePlayer(path: path); to prepare my player where the path is given with the message. I am currently testing with local .wav audio files located in my assets/audio. I added the folder in my pubspec.yaml. I am creating late PlayerController player; in GroupMessage class and then call Future initializePlayer(String path) async { player = PlayerController(); await player.preparePlayer(path: path); }

using a FutureBuilder so that I can wait for the controller to be initialized correctly. But it throws the following error:

E/ExoPlayerImplInternal( 6022): Playback error
E/ExoPlayerImplInternal( 6022):   com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal( 6022):       at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:644)
E/ExoPlayerImplInternal( 6022):       at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:616)
E/ExoPlayerImplInternal( 6022):       at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal( 6022):       at android.os.Looper.loop(Looper.java:223)
E/ExoPlayerImplInternal( 6022):       at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal( 6022):   Caused by: com.google.android.exoplayer2.upstream.FileDataSource$FileDataSourceException: java.io.FileNotFoundException: assets/audio/arabian-psy-vox_138bpm_F.wav: open failed: ENOENT (No such file or directory)

I don't know why it can't see the file, can someone help me


Solution

  • I found a solution & it needs a package named path_provider.

    So, your pubspec.yaml file should look like this:

    flutter:
      uses-material-design: true
      assets:
        - assets/sound.wav
    

    Here's the main.dart file. So, here's a different way in this plugin if your sound file is not in the native folder.

    import "dart:io";
    
    import "package:audio_waveforms/audio_waveforms.dart";
    import "package:flutter/material.dart";
    import "package:flutter/services.dart";
    import "package:path_provider/path_provider.dart";
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MyWidget(),
          debugShowCheckedModeBanner: false,
        );
      }
    }
    
    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      final PlayerController controller = PlayerController();
      String path = "";
    
      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback(
          (Duration timeStamp) async {
            final Directory directory = await getApplicationDocumentsDirectory();
            const String assetName = "sound.wav";
            final File file = File("${directory.path}/$assetName");
            final ByteData byteData = await rootBundle.load("assets/$assetName");
            await file.writeAsBytes(byteData.buffer.asUint8List());
            path = file.path;
            setState(() {});
          },
        );
      }
    
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  AudioFileWaveforms(
                    size: const Size(double.infinity, 100),
                    playerController: controller,
                    playerWaveStyle: const PlayerWaveStyle(
                      liveWaveColor: Colors.blueAccent,
                    ),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      if (controller.playerState.isPlaying) {
                        await controller.stopPlayer();
                      } else {}
                      await controller.preparePlayer(path: path);
                      await controller.startPlayer();
                    },
                    child: const Text("Play"),
                  )
                ],
              ),
            ),
          ),
        );
      }
    }