Giter VIP home page Giter VIP logo

just_audio's People

Contributors

agersant avatar akindone avatar bdlukaa avatar camerash avatar canxin121 avatar cedvdb avatar creativecreatorormaybenot avatar danielwinkler avatar ewertonls avatar goviral-ma avatar hsangtini avatar idy avatar jei avatar josephcrowell avatar kmod-midori avatar lkho avatar mathisfouques avatar minhqdao avatar nt4f04und avatar nuc134r avatar pante avatar ryanheise avatar snaeji avatar snipd-mikel avatar srawlins avatar stonega avatar subhash279 avatar tarekbazine avatar timilehinjegede avatar zekfad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

just_audio's Issues

Feature Request: Support more audio file formats

Since the migration to exoplayer I think supporting all the various audio file formats should be done.
Currently in my testing I discovered that .flac files do not play.
I had been only testing using .mp3 this whole time.
Hope support for all audio formats can be added in future updates.

Position can be greater than duration

The end position fired by "getPositionStream()" exceeds the duration returned by the setUrl/setFile calls.

I/flutter (22305): position: 229886, duration: 229877

It's a very small discrepancy, but it's enough to break the UI code which does not expect a progress value to exceed the maximum value.

The problem is caused by firing position events every 200ms, which means that the last fire is almost guaranteed to be after the recording finished.

It appears that if you finish "// TODO: emit periodically only in playing state.", it may resolve this issue with plenty of other benefits.

This may also be related to #21

NB: As a side-note, you may want to rename .getPositionStream() into positionStream to make it consistent with playbackStateStream.

Release Tags

Thanks for the project.
Could you please tag your releases on github so that it is possibly to watch the repository for new releases to keep up-to-date with development without having to watch all issues?

PlatformException on setUrl method call

When i call setUrl method, i have "PlatformException (PlatformException(Error: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference"

My player class:
`import 'package:just_audio/just_audio.dart';

class RadioAudioPlayer {
AudioPlayer player;
static final RadioAudioPlayer _instance = RadioAudioPlayer._internal();

factory RadioAudioPlayer() {
return _instance;
}

RadioAudioPlayer._internal();

initialize(){
player = AudioPlayer();
}

playFromUrl(url)async{
await player?.setUrl(url);
player?.play();
}

stop() async {
await player?.stop();
}

}`

Example needs to be updated to use AndroidX

The example android app needs to be updated to use AndroidX or it will not compile.

File: gradle.properties
Add the following:

android.useAndroidX=true
android.enableJetifier=true

Full gradle.properties file:

org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

Thanks.

Keep getting these logs on real device

D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/2983 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/3205 (fetch/transfer)
D/CCodecBuffers(21656): [c2.android.aac.decoder#112:1D-Input.Impl[N]] codec released a buffer owned by client (index 3)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/3428 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/3652 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/3875 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/4101 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/4324 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/4542 (fetch/transfer)
D/BufferPoolAccessor(21656): bufferpool2 0x700114da20 : 6(49152 size) total buffers - 5(40960 size) used buffers - 1/7 (recycle/alloc) - 10/4764 (fetch/transfer)

These logs keep getting printed out when testing on my real device (Redmi Note 3). Please do disable these logs.

Unhandled Exception: NoSuchMethodError: The getter 'state' was called on null.

In both iOs and Android, the following line throws an exception:

Unhandled Exception: NoSuchMethodError: The getter 'state' was called on null.

 /// The current [AudioPlaybackState].
  AudioPlaybackState get playbackState => _audioPlaybackEvent.state;

I took a quick look at the code, but I don't see an obvious reason why _audioPlaybackEvent is null at any point. In either case, the plugin should handle this situation, if it's a valid option, e.g.:

AudioPlaybackState get playbackState => _audioPlaybackEvent?.state;

Buffered audio size

Is it possible to retrieve the amount buffered so far of the song to display on the song progress bar, like u see in the image I have put, is it possible?
Screenshot_20200209-175627

Disable these logs

V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 5
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXEmptyBufferDone 1
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXFillBufferDone 5 time 104489 us, flags = 0x00000000
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 6
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXEmptyBufferDone 2
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXFillBufferDone 6 time 130612 us, flags = 0x00000000
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 7
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXEmptyBufferDone 3
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXFillBufferDone 7 time 156734 us, flags = 0x00000000
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 8
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 5
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXEmptyBufferDone 4
V/ACodec  (23197): [OMX.google.mp3.decoder] onOMXFillBufferDone 8 time 182857 us, flags = 0x00000000
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 6
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 7
V/ACodec  (23197): [OMX.google.mp3.decoder] calling fillBuffer 8

These logs keep getting printed out to console when playing audio. Please do disable these logs.

[Feature Request] Auto get duration of mediaitem.

Auto get duration from audio file is really needed, the seek bar would not show if mediaItem dont have duration data right now. looks like exoplayer have method to get the duration, but I need to learn java first /sad.

Thanks for great work.

Player occasionally starts looping the same bit after seeking

I am running issue where after seeking using the seek method, the player occasionally gets into a state where it continues looping the same part (of roughly half a second). This behavior remains even after pausing and resuming the stream.

I was not able to replicate this issue with the audio in the example application, but it does seem to occur when I replace the audio in the example with something different, for example this (.m4a, MPEG-4 AAC).

Seeking seems to work fine the first 4-5 times, but any more and it usually gets stuck again.

This is on Android 10, both on an emulator as well as a physical device.
No errors appear to be thrown.

Cancel Loading or connecting audio

How possible is it to cancel a loading audio i.e an audio in "AudioPlaybackState.connecting" state as neither dispose or stop work on it as shown on the usage tips in the IDE. So if the audio is still connecting and the user cancels, how can I Stop the loading of this file as right now, it continues loading and plays thereafter.

"Source error" on older devices

What is the minimum version of Android and iOS for this plugin ?
It is working just fine on an Android 7.1.1, but when I test on an Android 5.1.1, it outputs these errors :

I/art     (10305): Rejecting re-init on previously-failed class java.lang.Class<com.google.android.exoplayer2.video.MediaCodecVideoRenderer$OnFrameRenderedListenerV23>
I/art     (10305): Rejecting re-init on previously-failed class java.lang.Class<com.google.android.exoplayer2.video.MediaCodecVideoRenderer$OnFrameRenderedListenerV23>
I/art     (10305): Rejecting re-init on previously-failed class java.lang.Class<com.google.android.exoplayer2.video.MediaCodecVideoRenderer$OnFrameRenderedListenerV23>
I/art     (10305): Rejecting re-init on previously-failed class java.lang.Class<com.google.android.exoplayer2.video.MediaCodecVideoRenderer$OnFrameRenderedListenerV23>
I/art     (10305): Rejecting re-init on previously-failed class java.lang.Class<com.google.android.exoplayer2.video.MediaCodecVideoRenderer$OnFrameRenderedListenerV23>
I/Choreographer(10305): looper Looper (ChoreographerOwner:Handler, tid 606) {37441f61} hasChoreographer
I/ExoPlayerImpl(10305): Init 2f971a86 [ExoPlayerLib/2.11.1] [L5251, RAINBOW JAM 4G, WIKO, 22]
E/ExoPlayerImplInternal(10305): Source error.

It didn't work either on iOS 9.3.6.

Edit : My bad, I didn't have the WiFi turned on.

Playback speed control

A way to change the playback speed would be great.
This is a much requested feature in my app.

AVPlayerItemStatusFailed on iOS

I am using the existing example but update the audio source to Flutter asset file. I have included the asset in pubspec.yaml
Device: iPhone 11 Pro Max Simulator
Flutter: v1.12.13+hotfix.7-stable

To add assets to your application, add an assets section, like this:

assets:
- assets/audio/sound.mp3

@OverRide
void initState() {
super.initState();
_player = AudioPlayer();
_player.setAsset('assets/audio/sound.mp3');
}

The printed log is following. Noted that 'AVPlayerItemStatusFailed' is NSLog message.

Performing hot restart...
Restarted application in 1,233ms.
AVPlayerItemStatusFailed

Exceptions when transitioning between playback states

The comments in the plugin say: "It is legal to invoke this method only from the following states:"

Is this a target platform limitation? All platforms or only one/some?

In either case, the plugin can handle some of these transitions more gracefully. For example, if .stop() is called when a state is AudioPlaybackState.buffering, a plugin can chain "pause" and "stop" calls (for both or one of the platforms where this is an issue), instead of throwing an exception.

@ryanheise I would love to hear your thoughts on that before implementing this logic in my own code. My concern is that the farther away we go from the platform calls, the higher the probability of unpredictable behavior (e.g. stop() called from the app code when a status was AudioPlaybackState.playing, but by the time it reached the platform the status temporarily changed to AudioPlaybackState.buffering, resulting in a failed stop()).

Confusing AudioPlayerState vs AudioPlaybackState

Developer ergonomics
As I was switching to use this library, I found myself losing track of PlayerState (i.e playerState, playerStateStream) and PlaybackState (i.e playbackStateStream). I couldn't remember which was the enum and which was the class, and had to keep on checking.

I suggest that the core issue is that state is a generic word (as in the phrase, "maintaining app state"), and differentiating is relying on the words "player" and "playback", both of which aren't so strongly associated with the data their representing.

I suggest that the API and docs be updated to use "Status" for the enum, and "Details" for the object.

My reasoning:

  • Status implies a short, generic description. For example, a short whatsapp status. "At the park", or "Driving home". This fits with the enum - "loading", "playing", "stopped", etc.
  • Details implies... details, which are specific to the unique activity which is going on now. TImes, speeds, positions - all the contents of the current AudioPlayerState (As I'm writing this, I have to keep on checking which is which ๐Ÿ˜… )

That would give us, perhaps
playerDetailsStream, playbackStatus, playbackStatusStream, etc.

Further, I suggest that the split between "player" and "playback" is additionall information which has to be interpreted by the developer, while not adding that much additional clarity. Perhaps the "prefix" should be a standard "audio", giving
audioDetailsStream, audioStatus, audioStatusStream, and class AudioDetails and enum AudioStatus.

This is my personal opinion, and this is more of a discussion issue (at this point at least).

If you agree, this is something I could try my hands at making a PR for, although it may be a few days until I can get around to it.

Bug: Logcat exception output

java.lang.IllegalStateException
android.media.MediaExtractor.getSampleTime(Native Method)
com.ryanheise.just_audio.AudioPlayer$PlayThread.run(AudioPlayer.java:458)

Happens when stopping, seeking or playing audio sometimes. The PlayThread is the main cause of this issue.

Address event lag through platform channels

Note to self: there is a slight lag between the time an event is broadcast from the platform side and the time it is received on the flutter side, which may create surprises for flutter-side state processing. For example, after await setUrl(...) completes on the flutter side, the state transition to stopped may lag slightly, and for a brief moment querying player.playbackState may still report connecting.

At some point, this code should be improved so that events are categorised into flutter-side initiated events which should update on the flutter side immediately, and asynchronous events which originate on the platform side, such as when buffering is detected, and for which the lag is not a problem.

Catching CodecExceptions from ExoPlayer

Currently, when I feed the plugin a url to an online audio file in opus format, ExoPlayer throws the following exception:

Exception

E/ExoPlayerImplInternal(10334): Renderer error: index=1, type=audio, format=Format(1, null, null, audio/opus, null, -1, en, [-1, -1, -1.0], [2, 48000]), rendererSupport=YES
E/ExoPlayerImplInternal(10334): com.google.android.exoplayer2.ExoPlaybackException: android.media.MediaCodec$CodecException: Error 0x80000000
E/ExoPlayerImplInternal(10334): 	at com.google.android.exoplayer2.BaseRenderer.createRendererException(BaseRenderer.java:359)
E/ExoPlayerImplInternal(10334): 	at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:723)
E/ExoPlayerImplInternal(10334): 	at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:599)
E/ExoPlayerImplInternal(10334): 	at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:329)
E/ExoPlayerImplInternal(10334): 	at android.os.Handler.dispatchMessage(Handler.java:103)
E/ExoPlayerImplInternal(10334): 	at android.os.Looper.loop(Looper.java:214)
E/ExoPlayerImplInternal(10334): 	at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal(10334): Caused by: android.media.MediaCodec$CodecException: Error 0x80000000
E/ExoPlayerImplInternal(10334): 	at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
E/ExoPlayerImplInternal(10334): 	at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2823)
E/ExoPlayerImplInternal(10334): 	at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1504)
E/ExoPlayerImplInternal(10334): 	at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:709)
E/ExoPlayerImplInternal(10334): 	... 5 more

Surrounding logs here

I guess this has more something to do with ExoPlayer than just_audio, but the problem I am having is that I seem to have no way of catching this exception.

Is there any way I can handle these cases?

Add AudioPlaybackState.COMPLETED and onPlayerCompletion stream listener

The audioplayers plugin had features such as onPlayerCompletion stream listener which would get data when the audio file fully completed playback i.e the entire audio file length was played.
I am migrating from this code setup, so having these streams is necessary.

Not only did audioplayers plugin have AudioPlaybackState.COMPLETED but also the audioplayer plugin had it which you are using in audio_service.

Migration from these existing plugins to this just_audio plugin is slightly more difficult due to this.

[Android] EventSink is null when use in conjunction with audio_service

  • just_audio version: 0.1.3
  • Crash log:
java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.EventChannel$EventSink.success(java.lang.Object)' on a null object reference
E/AndroidRuntime(20897): 	at com.ryanheise.just_audio.AudioPlayer.broadcastPlaybackEvent(AudioPlayer.java:229)
E/AndroidRuntime(20897): 	at com.ryanheise.just_audio.AudioPlayer.access$300(AudioPlayer.java:32)
E/AndroidRuntime(20897): 	at com.ryanheise.just_audio.AudioPlayer$1.run(AudioPlayer.java:65)
E/AndroidRuntime(20897): 	at android.os.Handler.handleCallback(Handler.java:883)
E/AndroidRuntime(20897): 	at android.os.Handler.dispatchMessage(Handler.java:100)
E/AndroidRuntime(20897): 	at android.os.Looper.loop(Looper.java:214)
E/AndroidRuntime(20897): 	at android.app.ActivityThread.main(ActivityThread.java:7356)
E/AndroidRuntime(20897): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(20897): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/AndroidRuntime(20897): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

This is possibly related to #34, and I believe a fix would be similar

Position updates during buffering with no sound

While buffering, the song's current position updates while listening to getPositionStream stream but with no sound. This causes the UI progress bar to keep updating like the song is playing and the song current time updating without actually any sound. However the preloader shows its buffering. After buffering, it is updated with the current(true) time

Crash in ios

I'm seeing a crash in crashalytics. (I'm also using audio_service)

I notice that the free RAM looks limited. Do you think this is just because my app is currently RAM heavy?

Model: iPhone 6s
Version: 13.3.0 (17C54)
RAM free: 58.27 MB

Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000010
-[AudioPlayer broadcastPlaybackEvent]

Crashed: com.apple.main-thread
0  Runner                         0x10452d220 -[AudioPlayer broadcastPlaybackEvent] + 118 (AudioPlayer.m:118)
1  AVFoundation                   0x1c5f497d8 -[AVPlayerItem _unregisterInvokeAndReleasePendingSeekCompletionHandlerForSeekID:finished:] + 116
2  AVFoundation                   0x1c5f5dc24 __avplayeritem_fpItemNotificationCallback_block_invoke + 6380
3  libdispatch.dylib              0x1bbbea610 _dispatch_call_block_and_release + 24
4  libdispatch.dylib              0x1bbbeb184 _dispatch_client_callout + 16
5  libdispatch.dylib              0x1bbb9d190 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1044
6  CoreFoundation                 0x1bbe9c5e4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
7  CoreFoundation                 0x1bbe975d8 __CFRunLoopRun + 2004
8  CoreFoundation                 0x1bbe96adc CFRunLoopRunSpecific + 464
9  GraphicsServices               0x1c5e1c328 GSEventRunModal + 104
10 UIKitCore                      0x1bff91ae0 UIApplicationMain + 1936
11 Runner                         0x1044d3834 main + 7 (main.m:7)
12 libdyld.dylib                  0x1bbd20360 start + 4

[iOS] Audio Stall for few seconds on start

When I start the audio after buffering it plays for several seconds without audio then the timer and seeker reset and start playing with audio

This happen because in android
Player.STATE_READY is called when the player got the url data and buffered some audio and ready to play

but in iOS AVPlayerItemStatusReadyToPlay is called when the player got the file data like duration and ready to BUFFER to begin playing when it buffer enough to play

I'm currently working on podcast player so I made a fix for this issue
there is and observer for AVPlayer called 'timeControlStatus' it's available from iOS 10 and above, It return the AVPlayerTimeControlStatus {Paused, WaitingToPlay,Playing}

I'm going to open Pull request with this fix.

Feature: Composite Media Source

Have functionality for ConcatenatingMediaSource as in exoplayer where multiple media sources can be added.

Concatenates multiple MediaSources. The list of MediaSources can be modified during playback. It is valid for the same MediaSource instance to be present more than once in the concatenation. Access to this class is thread-safe.

This means we can setUrl/setFilePath and form even a playlist. i.e loop through queue and add media sources using the ConcatenatingMediaSource option.

exoplayer sample has implemented the code this way:

 ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource();
    for (Samples.Sample sample : SAMPLES) {
      MediaSource mediaSource = new ExtractorMediaSource.Factory(cacheDataSourceFactory)
          .createMediaSource(sample.uri);
      concatenatingMediaSource.addMediaSource(mediaSource);
    }
    player.prepare(concatenatingMediaSource);
    player.setPlayWhenReady(true);

sample.uri is the url/filePath of the media/audio file.
SAMPLES is the queue.

Hope I have been clear.

Playing a remote file and cache the file at the same time

Any suggestion on how I could play a remote files and store the files in cache for faster playing next time? One option is to use Flutter cache manager to download it too when I play it but this would mean downloading twice i.e one from the remote url (for the audioplayer) and one to store in cache for next time.

How possible is it to play the remote file while caching it for faster playing the next time?

[Feature request] Icy metadata

First of all, thank you for making this plugin and audio_service, they're both great!
I'm trying to add support for Icy metadata to the Android version of the plugin, for a personal project. I've got a somewhat working solution here: https://github.com/Jei/just_audio/tree/icy-metadata.
ExoPlayer reads Icy metadata from Icecast/Shoutcast streams by default, so it doesn't require much additional code to make it work. The only problem I'm having is that I've only been able to read the IcyInfo part of the metadata, which includes the title and the URL (if supplied by the server), while I still cannot retrieve the IcyHeaders part, which contains other useful information about the stream (bitrate, genre...). If you have any insight on this issue, it would be appreciated.
I've got a couple of questions:

  • would this be something useful to have in the main repository?
  • how should I go about making this a non-breaking change?

[Feature] pass expo exceptions back to flutter

First, thank you for the plugin,
I would like to have a possibility to know the exception that happened in expo player, so that I could catch a wrong url or 404 url ... (also related to #29) .
Let me know if PR are welcome (I could help with this), for now I do have two solutions in mind :

  1. pass exceptions through a stream of errors
  2. pass back the exception as a return (with duration, we create an object or use .catchError() ) of player.setUrl()

thanks

ExoPlayer revisited

A number of recent issues (#10, #14, #16, and possibly #17) could be addressed by finally switching to ExoPlayer as per the suggestion of @rohansohonee . The reason for not considering it until now was the difficulty of implementing untilPosition in ExoPlayer, however studying the APIs further, I think this should actually be possible as well.

It will take some time to read through all the documentation, but I plan to focus my attention here for the next while.

Loop Audio

Possibilty of repeating a song after it's complete? Is it supported or should I use my custom logic for repeating it?

Exception from ExoPlayer

I ran into one mp3 file which causes the following exception, when playing on Android:

E/ExoPlayerImplInternal(19071): Source error.
E/ExoPlayerImplInternal(19071): com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor) could read the stream.
E/ExoPlayerImplInternal(19071): 	at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractorHolder.selectExtractor(ProgressiveMediaPeriod.java:1095)
E/ExoPlayerImplInternal(19071): 	at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:974)
E/ExoPlayerImplInternal(19071): 	at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391)
E/ExoPlayerImplInternal(19071): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal(19071): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal(19071): 	at java.lang.Thread.run(Thread.java:919)

The file actually starts playing and sounds normal. Unfortunately, the audio player becomes unresponsive - all further calls (setting a new file/URL) fail. The audio player appears to be permanently stuck in the .connecting state.

The same file plays with no problems on iPhone. I also ran a check to see if this is a valid mp3 file, and it is.

  1. Any ideas why a file would play normal on iPhone (and in web browsers), but fail on Android?

  2. Is there a way to catch such exceptions?

iOS Testing help wanted

All features mentioned in the README as "untested" for iOS are virtually all implemented, although just not 100% confirmed through testing.

If an untested feature works for you, I would be grateful if you could report that below and I will reflect that in the README.

not working on some devices

this library not working on some devices such as Huawei p30 lite, samsung j7, Galexy j3pro, samsung j5, Samsung Galaxy J1, Samsong g7

and not working on Android 9

Enable cross-protocol redirects in ExoPlayer

Some podcast providers (e.g. Soundcloud) provides url to online stream, that is cross-protocol redirected (original url returns 302 response) to audio file. ExoPlayer doesn't follow cross-protocol redirects by default. Since I do not have final url, I can't play this file.
Please add an option to enable cross-protocol redirecting

  • Related issue with example here
  • In short: please use this constructor here with last parameter (optionally) set to true.

Thank you

setUrl : send cookie info

Some remote audio needs an identification to be played. Could be helpful to have setUrl take http params or create a function that takes an HttpRequest as parameter.

Crash while dispose

Player was using mp4 file from network in a stateful widget, the app crashed with log below after press the back button.

Everything in flutter doctor is OK

Detailed steps:

  1. Open the view which contains the player with mp4 file 1.
  2. Let the file downloaded, and click the play button
  3. After 1-3 seconds, press the back button.
  4. Open another view which contains the player with mp4 file 2.
  5. After 1-3 seconds, press the back button.
  6. If not crash, open another view or simply redo step 1 - 5

Following the debug steps, it crashed during the dispose();

Crash Log:

D/NetworkSecurityConfig(15198): No Network Security Config specified, using platform default
I/VideoCapabilities(15198): Unsupported profile 4 for video/mp4v-es
I/OMXClient(15198): IOmx service obtained
I/ACodec (15198): codec does not support config priority (err -2147483648)
D/AudioTrack(15198): getTimestamp_l(27): device stall time corrected using current time 31617190413800
W/AudioTrack(15198): getTimestamp_l(27): retrograde timestamp time corrected, 31617208557400 < 31617212458600
I/ExoPlayerImpl(15198): Release 806d62c [ExoPlayerLib/2.11.1] [generic_x86_arm, sdk_gphone_x86, Google, 29] [goog.exo.core]
I/ExoPlayerImpl(15198): Init 840da8c [ExoPlayerLib/2.11.1] [generic_x86_arm, sdk_gphone_x86, Google, 29]
I/OMXClient(15198): IOmx service obtained
I/ACodec (15198): codec does not support config priority (err -2147483648)
I/ACodec (15198): codec does not support config operating rate (err -2147483648)
D/AudioTrack(15198): getTimestamp_l(28): device stall time corrected using current time 31622562992700
I/ExoPlayerImpl(15198): Release 840da8c [ExoPlayerLib/2.11.1] [generic_x86_arm, sdk_gphone_x86, Google, 29] [goog.exo.core]
D/AndroidRuntime(15198): Shutting down VM
E/AndroidRuntime(15198): FATAL EXCEPTION: main
E/AndroidRuntime(15198): Process: com.cook.maker, PID: 15198
E/AndroidRuntime(15198): java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.EventChannel$EventSink.success(java.lang.Object)' on a null object reference
E/AndroidRuntime(15198): at com.ryanheise.just_audio.AudioPlayer.broadcastPlaybackEvent(AudioPlayer.java:229)
E/AndroidRuntime(15198): at com.ryanheise.just_audio.AudioPlayer.access$300(AudioPlayer.java:32)
E/AndroidRuntime(15198): at com.ryanheise.just_audio.AudioPlayer$1.run(AudioPlayer.java:65)
E/AndroidRuntime(15198): at android.os.Handler.handleCallback(Handler.java:907)
E/AndroidRuntime(15198): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(15198): at android.os.Looper.loop(Looper.java:216)
E/AndroidRuntime(15198): at android.app.ActivityThread.main(ActivityThread.java:7506)
E/AndroidRuntime(15198): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(15198): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/AndroidRuntime(15198): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:956)
I/Process (15198): Sending signal. PID: 15198 SIG: 9

(Android) UI thread is blocked at end of playback while seeking to 0.

This is a note to self.

In the finally block of the play thread, there is code to seek back to 0. This is a blocking call, but despite being executed in a background thread, it has the effect of blocking the UI thread. This is a mystery because seeking in other circumstances does not block the UI thread. This occurs both when playback naturally reaches the end of the file and also when stop() is explicitly called.

If I cannot work out the cause, it may be easiest to just remove the seek call such that the current position remains at the end of the file after playback completes. The user of the plugin can manually make a call to seek back to the start if they wish. This may be better because seeking on a network stream is slow, and not all use cases would want to perform this expensive seek operation after reaching the end of the file particularly if there is no intention to later continue playing from the start.

Queue management in just_audio

Hi @ryanheise

We must rely on using Playlists (ExoPlayer Android) and AVQueuePlayer (AVPlayer iOS).

Migrating to this approach will enable easy and straightforward approach for users to handle queue. It will also enable audio looping/repeat mode to get implemented with ease.

And lastly, it should make it way more easier to handle all the exception cases (bufferring/connecting states).

What are your thought's?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.