I'm trying to play an HLS format video in Flutter, where the video is stored in Firebase Storage, and I'm using the Google Transcoder API to generate the HLS video.
1. I create the videos
Content of file_1708297675081_0f606403e29817ac9663.m3u8:
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=412476,AVERAGE-BANDWIDTH=404498,VIDEO-RANGE=SDR,FRAME-RATE=60,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2"
hls.m3u8?alt=media
(I read that a possible issue might be the absence of ?alt=media so I manually added it to the file for testing purposes.)
hls.m3u8:
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXT-X-VERSION:4
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.020,
hls0000000000.ts?alt=media
#EXTINF:1.703,
hls0000000001.ts?alt=media
#EXT-X-ENDLIST
When attempting to play the video in Flutter, I tried both the file_1708297675081_0f606403e29817ac9663.m3u8 and hls.m3u8 files, both unsuccessfully.
For this, I generated a download URL using the Firebase SDK: https://firebasestorage.googleapis.com/v0/b/MYPROJECT.appspot.com/o/users%2Fajd5ZCUGKeMBktnk4W2ruVCG2Uj2%2FZXy2hO4WIwu5V1Qa9Evw%2Foptimized%2Fvideos%2Ffile_1708297675081_0f606403e29817ac9663.m3u8?alt=media&token=TOKEN
"MYPROJECT" and "TOKEN" are properly filled in. When I open the link in a browser, the page loads, but it does not allow the video to play (although I read this is likely a CORS issue, but regardless, it should work in the application.)
When I open link in browser (or just click m3u8 files on console):

In Flutter, I'm using the video_player package. I tried playing an openly accessible m3u8 file, and it was successful, so the Flutter code is fine.
The Flutter error message when I try to play my own file:
I/flutter ( 8209): URL:
https://firebasestorage.googleapis.com/v0/b/---myapp---.appspot.com/o/users%2Fajd5ZCUGKeMBktnk4W2ruVCG2Uj2%2FZXy2hO4WIwu5V1Qa9Evw%2Foptimized%2Fvideos%2Ffile_1708297675081_0f606403e29817ac9663.m3u8?alt=media&token=---token---
I/ExoPlayerImpl( 8209): Init 94f5a88 [ExoPlayerLib/2.18.7] [emu64xa, sdk_gphone64_x86_64, Google, 34] I/Surface ( 8209):
Surface::setFrameRate is deprecated, setFrameRate hint is dropped as
destination is not SurfaceFlinger D/EGL_emulation( 8209):
app_time_stats: avg=25.38ms min=6.67ms max=77.93ms count=36
D/EGL_emulation( 8209): app_time_stats: avg=29.32ms min=11.05ms
>max=56.89ms count=32 D/EGL_emulation( 8209): app_time_stats:
avg=27.87ms min=11.06ms max=43.51ms count=34 D/EGL_emulation( 8209):
>app_time_stats: avg=34.28ms min=12.12ms max=52.86ms count=29
>E/ExoPlayerImplInternal( 8209): Playback error
>E/ExoPlayerImplInternal( 8209):
>com.google.android.exoplayer2.ExoPlaybackException: Source error
>E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:644)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:616)
E/ExoPlayerImplInternal( 8209): at
android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal( 8209): at
android.os.Looper.loopOnce(Looper.java:205) E/ExoPlayerImplInternal(
8209): at android.os.Looper.loop(Looper.java:294)
E/ExoPlayerImplInternal( 8209): at
android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal( 8209): Caused by:
com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException:
Response code: 404 E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:413)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:263)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.DataSourceInputStream.checkOpened(DataSourceInputStream.java:99)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.DataSourceInputStream.open(DataSourceInputStream.java:62)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:174)
E/ExoPlayerImplInternal( 8209): at
com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
E/ExoPlayerImplInternal( 8209): at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
E/ExoPlayerImplInternal( 8209): at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
E/ExoPlayerImplInternal( 8209): at
java.lang.Thread.run(Thread.java:1012) E/flutter ( 8209):
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled
Exception: PlatformException(VideoError, Video player had error
com.google.android.exoplayer2.ExoPlaybackException: Source error,
null, null
)
I also tried to play hls0000000000.ts in browser, it SUCCESSFUL.
But I can't play m3u8 file in browser and flutter app. (But on browser maybe CORS problem and I don't want to change it.)
Rules not problem, because I allowed everything:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read; allow write;
}
}
}
I really don't know where is the problem.. Flutter code good (can play m3u8 videos), maybe security or cors or token or m3u8 file faulty. I just now used first time transcoder API, so maybe m3u8 files also not correct. Thank you for help.

Solved!
I use this instruction: https://medium.com/p/411e4fff68fa
But I missed this important information:
So not just ?alt=media need, need folders (users/..../...ts?alt=media) too! (Every file is in same folder, but for m3u8 file need full addres, I don't thought that.)
Good m3u8 file:
And it's work.