Play/Pause Toggle Button

1,909 views
Skip to first unread message

Isaac Franks

unread,
Jul 18, 2018, 3:23:52 PM7/18/18
to DroidScript
I looked at the reference for a toggle button, but every time I utilized the code it would not work. How would I go about making a play/pause button in javascript that is the same button?

alex.symbroson

unread,
Jul 18, 2018, 3:31:12 PM7/18/18
to DroidScript
Could you show us what you tried so far? So we can figure out where the mistake was

Isaac Franks

unread,
Jul 18, 2018, 5:00:50 PM7/18/18
to DroidScript
Definitely. I tried a few configurations.

#1

<script>
    //Called after application is started.
    function OnStart()
   
    function toggle (button) {
      if (button.value == "Play")  }
         button.value == "Pause";
       }  else {
              button.value == "Play";
     }
   }
</script>

var myAudio = document.getElementById("myAudio");
var isPlaying = false;

function togglePlay() {
  if (isPlaying) {
    myAudio.pause()
  } else {
    myAudio.play();
  }
};
myAudio.onplaying = function() {
  isPlaying = true;
};
myAudio.onpause = function() {
  isPlaying = false;
};


I can't really apply the above code anyways because I use the following in mine:
<p align="center" ><button onclick="playSound1()" class="styled">Sound1</button></p>

<script>
player1 = app.CreateMediaPlayer();

player1.SetFile( "SOUNDFILEGOESHERE.mp3" );

function playSound1()
{
player1.Play();
}
</script>

I know its a bit all over the place, but I am still learning to understand it all. Can you see where I made my mistake?

alex.symbroson

unread,
Jul 18, 2018, 5:15:32 PM7/18/18
to DroidScript
So are you creating an html or a js app? It seems like you mixed some things up.
can you post an spk of your project please (attach file in desktop mode) because I'm confused what your actual code is

the first one looks like some html element and the second one like some DroidScript code but I don't see the toggle button. Are you having problems with the html toggle or a DS toggle button control?

alex.symbroson

unread,
Jul 18, 2018, 5:23:17 PM7/18/18
to DroidScript
The general logic should be clear:
at first dedine a callback function - no matter which type if button you have.
For toggles in the callback function either start or stop the audio player dependent on wether it is checked or not.
You can also use a normal button and change the text to 'play' or 'pause' as you already did but you also have to start and stop your player there. Seems like you forgot that?

BareK

unread,
Jul 18, 2018, 6:05:26 PM7/18/18
to DroidScript

Isaac Franks

unread,
Jul 19, 2018, 12:10:58 PM7/19/18
to DroidScript
Yes, it is related to that post. I am not asking for code samples, just for assistance with the logic. I am still new to coding to coding and have been learning as I code with bits of HTML, CSS and JS knowledge I am picking up from SoloLearn, AppMurai, etc.
I was mixing html and javascript to deal with code I understood more. It still works, is it a problem that it is mixed? Thanks for the assistance on logic. I have been studying Droidscript references and the ones mentioned above, but the logic is a bit tricky to me. Do you have any alternatives learning sources you would suggest because I have like 10 amazing app ideas that I want to try once I get the hang of all this and just need to learn more?

alex.symbroson

unread,
Jul 19, 2018, 12:46:08 PM7/19/18
to DroidScript
If you want to mix HTML and DroidScript you need to create an HTML app
If you create a normal DroidScript JS app you cant use HTML.
That's why I asked you - Do you want to create a JS or HTML app?

Button example:

var player, file = "/Sys/Snd/Poing.ogg";


function OnStart() {
    player
= app.CreateMediaPlayer();
    player
.SetFile(file);
    player
.SetOnComplete(player_OnComplete);
   
   
var lay = app.CreateLayout("linear","fillxy,vcenter");
    btnToggle
= app.CreateButton("Play");
    btnToggle
.SetOnTouch(btnToggle_OnTouch);
    lay
.AddChild(btnToggle);
    app
.AddLayout(lay);
}


function btnToggle_OnTouch() {
   
switch(btnToggle.GetText()) {
       
case "Play": case "Resume":
           
if(!player.IsPlaying()) {
                player
.Play();
                btnToggle
.SetText("Pause");
           
}
       
break;
       
       
case "Pause":
           
if(player.IsPlaying()) {
                player
.Pause();
                btnToggle
.SetText("Resume");
           
}
       
break;
   
}
}


function player_OnComplete() {
    btnToggle
.SetText("Play");
}



alex.symbroson

unread,
Jul 19, 2018, 1:29:29 PM7/19/18
to DroidScript
Html could be just this:


<html>
<head>
   
<meta name="viewport" content="width=device-width">
   
<script src='file:///android_asset/app.js'></script>
</head>
 
<script>
   
function OnStart() {
        app
.MakeFolder(app.GetAppPath() + "/Snd")
        app
.CopyFile("/Sys/Snd/Poing.ogg", app.GetAppPath()+"/Snd/Poing.ogg");
       
        audio
.src = "Snd/Poing.ogg";
        audio
.type = "audio/ogg";
   
}
</script>

<body onload="app.Start()" style="background-color:#ffffff;">
   
<audio id="audio" controls></audio>
</body>
</html>

or this one:

<html>
<head>
   
<meta name="viewport" content="width=device-width">
   
<script src='file:///android_asset/app.js'></script>
</head>
 
<script>
   
var player;
   
   
function OnStart() {
        app
.MakeFolder(app.GetAppPath() + "/Snd")
        app
.CopyFile("/Sys/Snd/Poing.ogg", app.GetAppPath()+"/Snd/Poing.ogg");
       
        player
= new Audio
        player
.onended = player_OnComplete;
        player
.src = "Snd/Poing.ogg";
        player
.type = "audio/ogg";
   
}
   
   
function btnToggle_OnTouch() {
       
switch(btnToggle.value) {
           
case "Play":
           
case "Resume":
               
if(player.paused) {
                    player
.play();
                    btnToggle
.value = "Pause";
               
}
           
break;
           
           
case "Pause":
               
if(!player.paused) {
                    player
.pause();
                    btnToggle
.value = "Resume";
               
}
           
break;
       
}
   
}
   
   
   
function player_OnComplete() {
        btnToggle
.value = "Play";
   
}
</script>


<body onload="app.Start()" style="background-color:#ffffff;">
   
<input id="btnToggle" type="button" value="Play" onclick="btnToggle_OnTouch()" onended="player_OnComplete()">
</body>
</html>


hope it helps

actually the first html example is the best for you because you don't need to do anything...

Isaac Franks

unread,
Jul 20, 2018, 2:40:58 PM7/20/18
to DroidScript
That is above and beyond what I had expected, thank you alex!!

Without giving me sample code, could you just example to me what the two values in SetVolume (value, value) represent so that I can individually (and internally) set the volume of my buttons?

alex.symbroson

unread,
Jul 20, 2018, 2:43:40 PM7/20/18
to DroidScript
Maybe it is the left and right speaker volume?

Isaac Franks

unread,
Jul 20, 2018, 2:51:22 PM7/20/18
to DroidScript
Right, makes sense. I can just change player to player2 to create a second button too, right?

Isaac Franks

unread,
Jul 20, 2018, 2:57:06 PM7/20/18
to DroidScript
Never mind, got it. Thank you so much!!!

BareK

unread,
Jul 20, 2018, 6:40:33 PM7/20/18
to DroidScript
Of course you can create multiple mediaplayer objects.
If you want to play/loop a few sounds simultaneously this is the way to go.

In some cases it's also a good idea to reuse the same mediaplayer objects (if there are a lot of sounds to play for exemple).

This post of Steve Garman might interest you as you're in a learning phase:
https://groups.google.com/d/msg/androidscript/MvnGyrAUOAY/Fj3bK-ZbAgAJ

Isaac Franks

unread,
Jul 21, 2018, 4:41:44 PM7/21/18
to DroidScript
Oh no, I am not trying to play them simultaneously. I want to be able to play one sound per button.

alex.symbroson

unread,
Jul 21, 2018, 4:47:29 PM7/21/18
to DroidScript
then it is even easier - just pass different paths for different buttons to player.SetFile()

Ev. rodrigo dos santos

unread,
Jul 29, 2018, 11:01:11 PM7/29/18
to DroidScript
//Handle Play button.
function btnPlay_OnTouch() 
{
    if(player.IsPlaying()){
   player.Pause();
   play.SetText("[fa-play]");
  svc.SendMessage( "pause" );
    }
    else{ 
        player.Play();
        svc.SendMessage( "play" );
        play.SetText("[fa-pause]");
    }
//player.Play();
}

Isaac Franks

unread,
Aug 7, 2018, 11:47:15 AM8/7/18
to DroidScript
When you talk about crossing different paths for different files do you mean that I would just use player and player 2 with the appropriate files to select the right sound for the button? I kept having 2 play buttons that played the same sound.

BareK

unread,
Aug 7, 2018, 12:03:56 PM8/7/18
to DroidScript
I think he means something like this:

function OnStart()
{  
    lay
= app.CreateLayout( 'Linear', 'FillXY,VCenter' );
   
    btn1
= app.CreateButton( 'Play sound 1' );
    btn1
.SetOnTouch( btn1_OnTouch );
    lay
.AddChild( btn1 );
   
    btn2
= app.CreateButton( 'Play sound 2' );
    btn2
.SetOnTouch( btn2_OnTouch );
    lay
.AddChild( btn2 );
   
    app
.AddLayout( lay );
   
    player
= app.CreateMediaPlayer();
    player
.SetOnReady( player_OnReady );
}

function btn1_OnTouch()
{
    player
.SetFile( '/Sys/Snd/Poing.ogg' );
}

function btn2_OnTouch()
{
    player
.SetFile( '/Sys/Snd/Trill.ogg' );
}

function player_OnReady()
{
    player
.SetLooping( true );
    player
.Play();
}

Isaac Franks

unread,
Aug 8, 2018, 12:48:32 PM8/8/18
to DroidScript
Oh! I think I must have been separating my paths. Can I set the volume of the specified file with .SetVolume(); ? I can barely hear the sounds.

BareK

unread,
Aug 8, 2018, 2:28:10 PM8/8/18
to DroidScript
Of course you can using player.SetVolume( 1.0, 1.0 );

Isaac Franks

unread,
Aug 8, 2018, 2:47:23 PM8/8/18
to DroidScript
And to individually set each file with a specific volume would I do something like:

function btn1_OnTouch()
{
    player
.SetFile( '/Sys/Snd/Poing.ogg' );
    player.SetVolume( 3.0, 3.0 );
}

function btn2_OnTouch()
{
    player
.SetFile( '/Sys/Snd/Trill.ogg' );
    player.SetVolume( 1.0, 1.0 );

BareK

unread,
Aug 8, 2018, 3:26:24 PM8/8/18
to DroidScript
You should try it and see if it fits your needs, it's the best way :)
But you should keep in mind that SetVolume( left, right ) takes a percentage in paramter (1.0 means 100%).
Volume won't go over 100%, so SetVolume( 3.0, 3.0 ) wille have the same effect than SetVolume( 1.0, 1.0 );
If one of the sound is not 'earable' and the other is, thats the quality of the file that is to blame.
You can try to lower the loudest one to have something more harmonic, but that's all.
Alternatively you can increase the volume of the lowest file with programs like mp3Gain (windows) or any mp3 volume booster app on the playstore.

Isaac Franks

unread,
Aug 10, 2018, 12:58:11 PM8/10/18
to DroidScript
That makes sense because I have tested SetVolume in the past and anything over 1.0 never produced a different result. It makes sense that I would have to change the actual file volume. Not a sample, but can you tell me if I did the stop correctly then? The original purpose of this post was to determine if I could make a pause/play button, but with a loop a stop/play would work just fine. Could I do the following?

if  player.SetLooping (true);
   player.Play ();

else

  player.Stop ();

or would it be more like:

if (player.IsPlaying); {
   player.Stop();
}
else {
    player.Play();
 }

  player.SetLooping(true);

BareK

unread,
Aug 10, 2018, 2:29:04 PM8/10/18
to DroidScript
You need to use SetLooping( true ) only once (as it belongs to the player, not to the file).
The you'll need to check if player.IsPlaying() in order to play or stop it.

So it becomes:

if( player.IsPlaying() )
{
player.Stop();
}
elle
{
player.Play();
}

Isaac Franks

unread,
Aug 13, 2018, 1:47:08 PM8/13/18
to DroidScript
Okay, so it would look something like this in the end?


function OnStart()
{  
    lay
= app.CreateLayout( 'Linear', 'FillXY,VCenter' );
   
    btn1
= app.CreateButton( 'Play sound 1' );
    btn1
.SetOnTouch( btn1_OnTouch );
    lay
.AddChild( btn1 );
   
    btn2
= app.CreateButton( 'Play sound 2' );
    btn2
.SetOnTouch( btn2_OnTouch );
    lay
.AddChild( btn2 );
   
    app
.AddLayout( lay );
   
    player
= app.CreateMediaPlayer();
    player
.SetOnReady( player_OnReady );
}

function btn1_OnTouch()
{
    player
.SetFile( '/Sys/Snd/Poing.ogg' );
    player.SetLooping( true );
}

function btn2_OnTouch()
{
    player
.SetFile( '/Sys/Snd/Trill.ogg' );
}

function player_OnReady()
{
   

if( player.IsPlaying() )
{
    player.Stop();
}
else
{
    player.Play();

}

Does that make sense?

BareK

unread,
Aug 13, 2018, 2:22:50 PM8/13/18
to DroidScript
As always the better is to test :)
That way I saw that (as I didn't suspected it) you have to re-set the player on looping each time you change the file.

But anyway, telling the player to 'stop' if it is 'playing' on the 'OnReady' callback doesn't make sense.
When you set a new file to the player, it stops playing by itself (so calling 'SetFile' make 'IsPlaying' returning 'false').
Then the player loads completely the file and calls the 'OnReady' function when it's ready to be played (so at this step, 'IsPlaying' will always be false).

So you'll have the same result just writing:

function player_OnReady()
{
    player
.Play();
}

To achieve what you want, you have to check if the player 'IsPlaying' when you touch a button, so before setting the (new) file.
Here is the code you need:

function OnStart()
{  
    lay
= app.CreateLayout( 'Linear', 'FillXY,VCenter' );
   
    btn1
= app.CreateButton( 'Play sound 1' );
    btn1
.SetOnTouch( btn1_OnTouch );
    lay
.AddChild( btn1 );
   
    btn2
= app.CreateButton( 'Play sound 2' );
    btn2
.SetOnTouch( btn2_OnTouch );
    lay
.AddChild( btn2 );
   
    app
.AddLayout( lay );
   
    player
= app.CreateMediaPlayer();
    player
.SetOnReady( player_OnReady );
}

function btn1_OnTouch()
{

   
if( player.IsPlaying() )
   
{
        player
.Stop();
   
}
   
else
   
{

        player
.SetFile( '/Sys/Snd/Poing.ogg' );
   
}
}

function btn2_OnTouch()
{

   
if( player.IsPlaying() )
   
{
        player
.Stop();
   
}
   
else
   
{
        player
.SetFile( '/Sys/Snd/Trill.ogg' );
   
}
}

function player_OnReady()
{

    player
.SetLooping( true );
    player
.Play();
}

And as you're answer was about Toggle buttons, you'd better to do something like this:

function OnStart()
{  
    lay
= app.CreateLayout( 'Linear', 'FillXY,VCenter' );

   
    btn1
= app.CreateToggle( 'Play sound 1' );

    btn1
.SetOnTouch( btn1_OnTouch );
    lay
.AddChild( btn1 );

   
    btn2
= app.CreateToggle( 'Play sound 2' );

    btn2
.SetOnTouch( btn2_OnTouch );
    lay
.AddChild( btn2 );
   
    app
.AddLayout( lay );
   
    player
= app.CreateMediaPlayer();
    player
.SetOnReady( player_OnReady );
}

function btn1_OnTouch( isChecked )
{
   
if( isChecked == true )
   
{
        player
.SetFile( '/Sys/Snd/Poing.ogg' );
   
}
   
else
   
{
        player
.Stop();
   
}
   
   
// Uncheck the other button
    btn2
.SetChecked( false );
}

function btn2_OnTouch( isChecked )
{
   
if( isChecked == true )
   
{
        player
.SetFile( '/Sys/Snd/Trill.ogg' );
   
}
   
else
   
{
        player
.Stop();
   
}
   
   
// Uncheck the other button
    btn1
.SetChecked( false );

}

function player_OnReady()
{
    player
.SetLooping( true );
    player
.Play();
}

Here it makes more sense ;)
Hop it'll help you in your learning process!

Isaac Franks

unread,
Aug 15, 2018, 2:03:43 PM8/15/18
to DroidScript
I know I have a long way to go, but seriously, thank you for all of your help. I have been working away at this for at least a month, if not more, and I just was not able to wrap my mind around it. Thank you, you have been very generous with your time!!!

BareK

unread,
Aug 15, 2018, 2:26:13 PM8/15/18
to DroidScript
You're welcome :)
Keep it up and some day you'll help back ;)
Reply all
Reply to author
Forward
0 new messages