audio_waveforms icon indicating copy to clipboard operation
audio_waveforms copied to clipboard

ExoPlayer MalformedURLException when playing local files

Open daniel-villamizar-yohana opened this issue 7 months ago • 1 comments

Describe the bug When attempting to play a local audio file using the audio_waveforms package on Android, playback fails with a MalformedURLException: no protocol error. The file path is being stripped of its file:// protocol, causing ExoPlayer to throw the error.

To Reproduce Steps to reproduce the behavior:

Use audio_waveforms to play a local file on Android. Pass a file path (with or without file://) to PlayerController.preparePlayer. Observe that playback fails and the error is logged. Expected behavior Local audio files should play correctly on Android without protocol errors. The file path should be passed to ExoPlayer with the correct protocol (file://) if required.

Smartphone (please complete the following information):

Device: Pixel 4a OS: Android 12 Version: audio_waveforms 1.3.0

Additional context The PlayerController.preparePlayer method currently uses path = Uri.parse(path).path, which strips the file:// protocol from the path. This causes ExoPlayer to throw a MalformedURLException when trying to play local files. Stack trace excerpt:

/ExoPlayerImpl( 6796): Init 79e4d06 [ExoPlayerLib/2.17.1] [emulator64_arm64, sdk_gphone64_arm64, Google, 32] E/ExoPlayerImplInternal( 6796): Playback error E/ExoPlayerImplInternal( 6796): com.google.android.exoplayer2.ExoPlaybackException: Source error E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:641) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:613) E/ExoPlayerImplInternal( 6796): at android.os.Handler.dispatchMessage(Handler.java:102) E/ExoPlayerImplInternal( 6796): at android.os.Looper.loopOnce(Looper.java:201) E/ExoPlayerImplInternal( 6796): at android.os.Looper.loop(Looper.java:288) E/ExoPlayerImplInternal( 6796): at android.os.HandlerThread.run(HandlerThread.java:67) E/ExoPlayerImplInternal( 6796): Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: java.net.MalformedURLException: no protocol: /data/user/0/com.xxx.xxx/cache/temp_audio_2025-05-08T12:15:45.282181.wav E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:365) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:258) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1009) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412) E/ExoPlayerImplInternal( 6796): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/ExoPlayerImplInternal( 6796): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/ExoPlayerImplInternal( 6796): at java.lang.Thread.run(Thread.java:920) E/ExoPlayerImplInternal( 6796): Caused by: java.net.MalformedURLException: no protocol: /data/user/0/com.xxx.xxx/cache/temp_audio_2025-05-08T12:15:45.282181.wav E/ExoPlayerImplInternal( 6796): at java.net.URL.<init>(URL.java:601) E/ExoPlayerImplInternal( 6796): at java.net.URL.<init>(URL.java:498) E/ExoPlayerImplInternal( 6796): at java.net.URL.<init>(URL.java:447) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:507) E/ExoPlayerImplInternal( 6796): at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:359) E/ExoPlayerImplInternal( 6796): ... 7 more

Please advise on the correct way to handle local file paths

@daniel-villamizar-yohana For locally picked files, you can just pass path directly as shown in the example.

  1. Picking the file.
  2. Passing the path.
  3. passing to preparePlayer.

Do let me if this resolves your issue.

ujas-m-simformsolutions avatar May 26 '25 06:05 ujas-m-simformsolutions