Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to play .m3u8 file on Android #86

Closed
newdev8 opened this issue Apr 28, 2020 · 14 comments
Closed

Failed to play .m3u8 file on Android #86

newdev8 opened this issue Apr 28, 2020 · 14 comments
Assignees
Labels
bug Something isn't working

Comments

@newdev8
Copy link

newdev8 commented Apr 28, 2020

Describe the bug
I am trying to play a .m3u8 playlist file, in iOS works but on Android, it shows an exception.

Minimal reproduction project
Example project

To Reproduce
Steps to reproduce the behavior:

  1. Make a playlist with one or multiple .m3u8 files.
  2. Run the app.
  3. Hit play.
  4. See error.

Error messages

PlatformException(0, com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor, FlacExtractor) could read the stream).

Expected behavior
The file should play like it does on iOS.

Screenshots
Not applicable.

Smartphone (please complete the following information):

  • Device: Pixel 2 (emulator)
  • OS: Android 10 (API 29)

Flutter SDK version

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, v1.18.0-9.0.pre.14, on Mac OS X 10.15.4 19E287, locale es-ES)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
[✓] Android Studio (version 3.6)
[✓] Connected device (2 available)

• No issues found!

Additional context
The .m3u8 is formed by various .ts files.
Plus, the URL does not end in .m3u8, if that causes any problem.
I am also using the audio_service plugin.

@newdev8 newdev8 added 1 backlog bug Something isn't working labels Apr 28, 2020
@newdev8
Copy link
Author

newdev8 commented Apr 28, 2020

Here's a more detailed error log:

E/ExoPlayerImplInternal( 8879): Source error
E/ExoPlayerImplInternal( 8879):   com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor, FlacExtractor) could read the stream.
E/ExoPlayerImplInternal( 8879):       at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractorHolder.selectExtractor(ProgressiveMediaPeriod.java:1090)
E/ExoPlayerImplInternal( 8879):       at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:969)
E/ExoPlayerImplInternal( 8879):       at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391)
E/ExoPlayerImplInternal( 8879):       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal( 8879):       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal( 8879):       at java.lang.Thread.run(Thread.java:919)
E/AudioPlayer( 8879): TYPE_SOURCE: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor, FlacExtractor) could read the stream.
E/flutter ( 8879): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor, FlacExtractor) could read the stream.

@ryanheise
Copy link
Owner

Hi @lain-ke , as you suspected, I currently use the extension to determine the file type which would cause the problem.

ExoPlayer currently doesn't have any built-in mechanism to detect the stream type, and there is an open issue discussing adding this feature: google/ExoPlayer#3165

The ExoPlayer example app also uses the extension to detect the file type, but it at least points at what a solution might look like, which is to "sniff" the first few bytes of content to determine the type. If there is an example to base this solution on, that will be helpful.

Otherwise, in the meantime you will need to depend on the extension. If you have no control over the server, there is a workaround which is to create a local http server using Dart libraries and serve the file at a localhost URL with the correct extension that returns a 301 that points to the remote server.

The other alternative is to provide a low-level API similar to ExoPlayer where you have to choose the media source type before you pass in the URL, but I would rather not have the API go in that direction. Automatic detection of the stream type would be preferred.

@newdev8
Copy link
Author

newdev8 commented Apr 29, 2020

My URL basically contains the path (not ending in the extension) and then some params apply (?token=sñldhcioygosgduyasdv & more), so if as my last param I add &extension=.m3u8, the server wouldn't even read it but ExoPlayer would recognize it and play it, right?

@newdev8
Copy link
Author

newdev8 commented Apr 29, 2020

Okay, I've tried it and it doesn't work, I don't know if it's because it's a param or because my server redirects to the file.

Does ExoPlayer support redirects?

@ryanheise
Copy link
Owner

Your idea of adding the extension in the query string is quite clever and it's only unfortunate that the code only considers the path part of the URL. It got me thinking that maybe a fragment could be used for this purpose as a sort of workaround, but even in this case, I would need to add some code to recognise the fragment.

ExoPlayer does support redirects, which is why my previous suggestion will probably work, but maybe it'll be better if I just add some code to recognise the fragment as a temporary hack.

So for example, https://somewhere.com/somestream?whatever#.m3u8 .

I believe fragments are not sent in http requests, so this should be safer.

@newdev8
Copy link
Author

newdev8 commented Apr 29, 2020

What I've done is make the server send the url in JSON format, among with other data.
The server can output .m3u8 or .mp3 files depending on the case, is there any way to tell ExoPlayer what the extension is?

I mean, the JSON output returns (for example)

{"url": "https://...", "extension": "m3u8"}

or

{"url": "https://...", "extension": "mp3"}

So we already know the extension before passing it to ExoPlayer.

If there isn't any way, I'll wait for you to implement your above solution.

@ryanheise
Copy link
Owner

It's possible to do that with ExoPlayer (by choosing the media source class) but you don't have access to that at the Dart level, you only have access to the just_audio API, and the goal is to hide all of that so that you can just pass in a URL and the type is detected automatically.

I'll try to implement the temporary hack for you.

@newdev8
Copy link
Author

newdev8 commented Apr 29, 2020

Thanks!!

@ryanheise
Copy link
Owner

I've committed the work around to git master. Would you be able to test it before I include it in the next release?

@newdev8
Copy link
Author

newdev8 commented Apr 29, 2020

Sure!
But I don't really know how to manage GitHub and Flutter plugins... I'll need you to teach me how 😅

@ryanheise
Copy link
Owner

You can temporarily set your project to use the git master version of the plugin by changing your pubspec to:

  audio_service:
    git:
      url: https://github.com/ryanheise/audio_service.git

@newdev8
Copy link
Author

newdev8 commented Apr 30, 2020

Hey thanks a lot for the fix!
It works totally fine!

@newdev8 newdev8 closed this as completed Apr 30, 2020
@ryanheise
Copy link
Owner

Awesome, thanks for testing.

@github-actions
Copy link

github-actions bot commented Nov 8, 2021

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with just_audio.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants