Android Question [SOLVED] - EXOPlayer puzzler - sound not can't be heard intermittently

rleiman

Well-Known Member
Licensed User
Longtime User
Greetings,

I have an EXOPlayer puzzler for you. My app uses 3 EXO players to play 3 different sound files based on timers. All of the players play for a short while then there is no sound. The coding is set so each of the sounds are played when each of them has finished playing to create background sounds for the app.

Here is the coding:
Coding for one of the EXO Players:
Sub tmrForCrickets_Tick
       
    If blnAsongIsPlaying And PlayerForCrickets.IsPlaying = False Then

        PlayerForCrickets. _
            Prepare(PlayerForCrickets.CreateFileSource(File.DirAssets, _
                kvs.Get("Song" & intSongNumberSelected & "Creature0FileName")))
           
        PlayerForCrickets.Volume = kvs.Get("Song" & intSongNumberSelected & "Creature0Volume")
        PlayerForCrickets.Play

        Log("Playing the Crickets Timer at: " & _
            DateTime.GetHour(DateTime.Now) & ":" & DateTime.GetMinute(DateTime.Now) & _
            Chr(10) & Chr(10) & PlayerForCrickets.IsPlaying)
   
        Log("Crickets volume: " & kvs.Get("Song" & intSongNumberSelected & "Creature0Volume"))
    End If
End Sub

The highlighted section of code shows a Log statement after .Play which is where I expected to have a "True" for IsPlaying but it returns False as shown in the screen attachment. It could be the reason why the sound stops playing randomly. The strange thing is that the sound file does loop as expected for maybe about a half hour or so before playing multiple times to quickly.

According to the coding, I thought the .IsPlaying flag should be set to "True" right after the .Play is used. blnASongIsPlaying is set to True when the user taps a button to start the background sounds which should stop the code from repeating prematurely. I'm puzzled by the fact that the background sound does actually play correctly even for a short while because if the .IsPlaying flag is set to "False" like that, the player would keep playing on every second of time because that's how the timer is set up. This actually does happen after a half hour or so.

I originally used a "_Complete" handler to simply call the same coding when the player finishes the sound file but that only worked for about a half hour or so before it didn't call the coding. That's why I tried a timer approach.

All help will be appreciated.

Screenshot 2021-02-22 at 11.51.49.png
 
Last edited:

roumei

Active Member
Licensed User
I'm not sure that this solves your problem but SimpleExoPlayer needs some time to prepare the file. Try to add a Wait For the Ready event before calling Play. Adjusted example from here:
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    player1.Initialize("player")
    Dim sources As List
    sources.Initialize
    sources.Add(player1.CreateUriSource("https://html5demos.com/assets/dizzy.mp4"))
    player1.Prepare(player1.CreateListSource(sources))
    SimpleExoPlayerView1.Player = player1
        
    Wait For player_Ready ' wait for the player to be ready
    player1.Play
        
    Log(player1.IsPlaying)
    
End Sub

'Sub Player_Ready
'    Log("Ready")
'End Sub
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
I'm not sure that this solves your problem but SimpleExoPlayer needs some time to prepare the file. Try to add a Wait For the Ready event before calling Play. Adjusted example from here:
B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    player1.Initialize("player")
    Dim sources As List
    sources.Initialize
    sources.Add(player1.CreateUriSource("https://html5demos.com/assets/dizzy.mp4"))
    player1.Prepare(player1.CreateListSource(sources))
    SimpleExoPlayerView1.Player = player1
       
    Wait For player_Ready ' wait for the player to be ready
    player1.Play
       
    Log(player1.IsPlaying)
   
End Sub

'Sub Player_Ready
'    Log("Ready")
'End Sub
Thanks for the reply. I tried to put the Wait For coding in but it just stayed in my sub routine not running the "Sub Player_Ready". I will need to locate that video I think Erel posted about doing resumable subs with Wait For and learn how to use them for the future.

In the meantime, I did find that I was able to use the _Ready handler supplied with the player when creating a new sub. I placed coding to play the player only when it was ready and .IsPlaying also reports "True" now. I'm currently testing the coding to see if it still works as intended and will post the coding tomorrow.

Again, thanks. :)
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
Thanks for the reply. I tried to put the Wait For coding in but it just stayed in my sub routine not running the "Sub Player_Ready". I will need to locate that video I think Erel posted about doing resumable subs with Wait For and learn how to use them for the future.

In the meantime, I did find that I was able to use the _Ready handler supplied with the player when creating a new sub. I placed coding to play the player only when it was ready and .IsPlaying also reports "True" now. I'm currently testing the coding to see if it still works as intended and will post the coding tomorrow.

Again, thanks. :)
Here are my finding so far. After about 4 hours, several instances of the 3 players in the app started to play. I believe the culprit could be that I'm using timers which I will eliminate with different logic. Even though the logic in the coding is supposed to not allow multiple instances of 1 player from playing, I think there is a small window of time that opens up after a player finishes playing the sound file despite when in fact that the timer is ticking at 1/2 of a second. My thoughts are to not use timers and call a sub routine to directly start the player and keep it playing with .CreateLoopSource instead of using .CreateFileSource for the Prepare statement. At least I think that's where I'm supposed to use it. I will look in the forums to see if I can find any references to how to use the .CreateLoopSource statement or I may try using the Player_Complete handler sub routine to start up the player again after releasing the player resources and initialising it again.
 
Last edited:
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
Here are my finding so far. After about 4 hours, several instances of the 3 players in the app started to play. I believe the culprit could be that I'm using timers which I will eliminate with different logic. Even though the logic in the coding is supposed to not allow multiple instances of 1 player from playing, I think there is a small window of time that opens up after a player finishes playing the sound file despite when in fact that the timer is ticking at 1/2 of a second. My thoughts are to not use timers and call a sub routine to directly start the player and keep it playing with .CreateLoopSource instead of using .CreateFileSource for the Prepare statement. At least I think that's where I'm supposed to use it. I will look in the forums to see if I can find any references to how to use the .CreateLoopSource statement or I may try using the Player_Complete handler sub routine to start up the player again after releasing the player resources and initialising it again.
I'm getting closer. Removing the timer made a big difference. I'm not getting multiple running players for the same sound file any more but I seem to have hit some kind of limit on how many times a sound file can be repeated.

Please look at my coding and let me know what I didn't do correctly in the processing of the sound files in the player. The app has 3 players that can run simultaneously but the coding I'm showing is just for one particular sound file. All three players have the same logic. The coding will play the sound file for a limited amount of time and when that limit is hit, the coding still executes as shown with the Log statements in the coding. When the limit is hit, the sound will stop but the Log statements still show the code is being executed. It seems the limit is that the sound file can be heard between 2 times or up to 4 hours then I can't hear it any more. It happens intermittently. I will include the Log display if you need to see it.

Here's the coding which is in a service module:

This is how we initialised the EXO player.:
PlayerForCrickets.Initialize("PlayerForCrickets")

When the user taps the start button to play the sound file.:
Sub PlayTheSong
  
    Log("--------------------------")

    Log("Playing the song at: " & _
        DateTime.GetHour(DateTime.Now) & ":" & DateTime.GetMinute(DateTime.Now))
  
    blnAsongIsPlaying = True
    intSongNumberSelected = kvs.Get("CurrentSongSelected")
  
    PlayTheCricketsBackground
End Sub

[CODE lang="b4x" title="blnAsongIsPlaying is set to "True" when the user taps the start button." highlight="3"]Sub PlayTheCricketsBackground

If blnAsongIsPlaying And PlayerForCrickets.IsPlaying = False Then

Log("------------------------")
Log("Preparing to play Crickets.")
Log("------------------------")

PlayerForCrickets. _
Prepare(PlayerForCrickets.CreateFileSource(File.DirAssets, _
kvs.Get("Song" & intSongNumberSelected & "Creature0FileName")))
End If
End Sub
[/CODE]

When the player is ready the sound file is played.:
Sub PlayerForCrickets_Ready
  
    Log("------------------------")
    Log("Crickets player is ready.")
          
    PlayerForCrickets.Volume = kvs.Get("Song" & intSongNumberSelected & "Creature0Volume")
    PlayerForCrickets.Play

    Log("Playing the Crickets Timer at: " & _
            DateTime.GetHour(DateTime.Now) & ":" & DateTime.GetMinute(DateTime.Now) & _
            Chr(10) & Chr(10) & PlayerForCrickets.IsPlaying)
  
    Log("Crickets volume: " & kvs.Get("Song" & intSongNumberSelected & "Creature0Volume"))
    Log("------------------------")
End Sub

When the sound file has finished playing, it's played over again until the user cancels it by tapping the stop button.:
Sub PlayerForCrickets_Complete

    Log("------------------------")
    Log("Crickets player is complete.")
    Log("------------------------")
          
    blnAsongIsPlaying = True
  
    PlayerForCrickets.Release
    PlayerForCrickets.Initialize("PlayerForCrickets")

    PlayTheCricketsBackground
End Sub
 
Last edited:
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
I'm marking this thread as solved because all of the sound issues are because of the recent Android 11 update for our Samsung Galaxy S10 phone. We installed the app on an S8 running Android 9 and the sound was as smooth as butter and the audio never stopped.

Both the EXO Player and media player both work as intended if run on the S8 phone.

I now have a lot of research to do to find out if other people are experiencing the same issue with the audio stuttering. It seems even though they made several improvements to Android 11, they introduced bugs with audio playback. I'm also thinking it may have something to do with the new battery memory management they introduced in that version.

After some research on the net, I found it's a big issue with Android 11. I also tried with Chrome and playing a YouTube video and the same issue with the stuttering was heard. Most likely tomorrow, I will post a new thread in case any of you have found out how to fix this issue. I also did true to use my Bluetooth headphones and the stuttering wasn't as bad.
 
Last edited:
Upvote 0
Top