Playing audio dynamically (solved)

Hello!

I have a dynamic page that I want to use to display an image, a text and an audio file from a database. I know that audio format is not yet supported in databases, so I was thinking that to solve this I could use a text field with the audio URL and play it when the user clicks a button. The problem is I don’t know how or even if it’s possible to play and audio from a URL with Wix Code. It would probably be something like this:

var a = new Audio(url);
a.play();

Any help is appreciated!

4 Likes

Hi,

It is not yet possible to dynamically play audio files using Wix Code (the music player component does not yet expose a Wix Code API).
What we do have is a dynamic video player (Working with the Connect Video Player Panel | Help Center | Wix.com) with which you can dynamically play Youtube / Vimeo videos.
Another option would be to try implement that using some custom html component (see Velo: Working with the HTML iframe Element | Help Center | Wix.com)

Good luck,
Itai

Itai, thanks for your reply, after accessing the link you provided I was able to figure out a way to do this.

Here’s the solution for whoever might need it too:

  • Add a HTML component to your page and use one of the following codes:
<script>
var audio = new Audio("AudioURL");
audio.play();
</script>

OR

1 Like

I’m glad to hear that! :slight_smile:

Hi Matheus,

I am trying to do the same, but I am a bit confused. Do you mind if you tell me the steps?

Thank you in advance.

Hello Margie. Sure, follow these steps:

  • Add an HTML component to your page
  • Click to edit the code of the HTML component and add this one:
<script type="text/javascript">
  window.onmessage = (event) => {
    if (event.data) {
       let receivedData = event.data;

var audio = new Audio(receivedData);
       audio.play();
    }
  };
</script>

This code takes the data received from the page, which in this case is the direct URL to the audio file, creates an audio variable using it and plays it.

  • To send a message from the page to the HTML component you can use this code:
$w("#HTMLcomponent").postMessage("audioURL");  

In my case I’m getting the audio URL from the database, so it looks like this:

$w("#HTMLcomponent").postMessage(currentItem.audioLink);  

Keep in mind that the URL passed to the HTML component must be the direct download link to your audio. Also, if you are trying to play the audio when the page loads, you must first send a message from the HTML component to the page indicating that it’s finished loading and then make the page send the audio URL to it when it receives this message. It’s explained in the Wix API if you need more guidance.

Hope it helps!

2 Likes

Hi Matheus,

Thank you so much for answering. Which element did you use to play the audio? I am using the mini player. Attached is what I am trying to make. My song URL is from a database too. It is still not playing the song in the URL.

1 Like

Hi Margie,

If you use google Chrome I have bad new: it’s not working on it anymore. I’ve made a new post asking for guidance on how to overcome this. Basically last month they changed their policy on Autoplaying audios and videos and it doesn’t work on Wix Code anymore, even when apparently under the circunstances that it should.

You can see it here: https://www.wix.com/code/home/forum/questions-answers/playing-audio-w-html-component-doesn-t-work-on-chrome

Check if it works on FireFox. If it still doesn’t work on FireFox you can post a piece of your code with the Html Component code and the event handler for the mini player code I can help you with it.

In my case I use a Text element (it plays the audio when the user clicks the text) or I just play it when the page loads.

Hi Matheus,

Oh that’s why. I did not see your post about chrome. I thought I was getting crazy. Does it open to another tab when you play it? It works connecting to a button or text but I don’t like the fact that it does not play on the same page. Do you mind if I see your playlist page? Thank you so much keep answering my questions.

Hi Margie, no problem, I’m happy to help.

No, it plays on the same page. I think that yours is opening another page because you’re not using the direct dowload link to the audio file. Where are you hosting your files ?

Try this: upload an audio file to your Wix files (it opens the window to do it when you drag an drop a mini player to your website). Then hover it’s icon and right click on the download button. There will be an option called something like ‘‘Copy link address’’. Click on it. Now paste the link somewhere. It will be something like this:

This example is one of my audio files stored in Wix. But this is not the direct download link. On Wix, you have to delete the last piece of the link (the ‘’?''and all that’s after it) in order to get the direct download link. So for this particular example it would become:


Now this is the direct download link that you have to pass to the Html component.

If you’re storing your files somewere else (like dropbox, for example) there might be a similar trick available in order to get the direct download link. Just google it.

I don’t actually have a playlist page. I play one audio at a time on the current dynamic page. Let me know how it goes.

1 Like

Hello, I’ve found this post that describe something similar to what I would like to do.

I have an audio file (loaded on wix) that I want to play when I press a button/text on the page.
I’ve added the HTML component as you describe, added the text and copied the audiofile direct link for the download (i’ve tested and it works).

This is my page code:

When i press the text32 nothing happens.
Where do I make mistake?

Thank you in advance!

1 Like

Is there a way to alter Mateus’ HTML component above to display simple audio controls, rather than autoplay on page load? Preferably would include style markup, but even the browser controls would be better.

Here’s Mateus’ code again for reference…

<script type="text/javascript">
   window.onmessage = (event) => {
     if (event.data) {
        let receivedData = event.data;

var audio = new Audio(receivedData);
        audio.play();
      }
   };
</script>

I am searching for a way to play audio from a dynamic page connected to my Wix database with Wix Music hosted audio mp3 files. I would like to use the Wix Audio players however that is not yet available apparently. These are recorded conference audio files so no issues with music licenses.

@cerraxca Did you add the code bellow ? I’m using it on my website and its still works. If so, check if you are using Chrome. As I wrote in one of the comments above, they changed their policy so now basically the user has to interact with the Html Component before it can play a sound. My solution to that was to convert the Html Component into a button that the user has to click instead of using a regular Wix Button. You can also convert it to a text or whatever you want for the user to click on it. Once the user has interacted with it it will play the audio normally. Note that the user has to click on it everytime the page loads. Hope it helps.

 <script type="text/javascript"> 
 window.onmessage = (event) => { 
 if (event.data) { 
 let receivedData = event.data; 
 var audio = new Audio(receivedData); 
 audio.play(); } }; 
 </script> 

@AaronH you can do it by adding html code into the Html Component. With raw html code you can add the controls (buttons) that you want and use the click event of each one of them to do whatever you want with the audio (play, stop, go to next track, etc). Just google “onclick event javascript” if you need a basic starting point. It’s simple.

@Roger Schanz You can do it with the code above. You just have to pass the audio link to the html component with the postMessage function

@matheus.mvl do you mind if you share your website? I still can’t make it work. If you don’t want to share it publicly, can you please email your me your url at mocdamia@gmail.com I would greatly appreciate it.

@matheus-mvl It would be fantastic if you could make a sample website with only this code and a simple database! I would also greatly appreciate it as would all the other people looking for a workaround on this issue.

Guys ok so I’ve created a sample website with 3 examples. All of them with audio urls extracted from a simple database.

Example 1 - Using an html component as a button, it plays the audios in a loop (the next audio is played everytime the button is clicked).

Example 2 - Using an html component as a button, it plays an audio everytime the button is clicked.

Example 3 - Using an html component + a wix button, it plays an audio everytime the wix button is clicked.

Here’s the sample website: https://matheusmvl.wixsite.com/audioexample

See the codes with comments bellow. Hope it helps!

Html component #html1

<!DOCTYPE html>
<html>
<head>
<style>
.button {
    background-color: dodgerblue;
    border: none;
    color: white;
    padding: 15px 35px;
    text-align: center;
    font-size: 16px;
    cursor: pointer;
    border-radius: 8px;
    outline: none;
}
.button:hover {
    background-color: #2B689C;
}
</style>
</head>

<!– When the html component finishes loading, it executes this function that sends a message to the page –>
<body onload="htmlIsReady()">
<script type="text/javascript">

//Array that will hold the audio objects
var playList = [];
//Counter to know which audio index to play
var k = 0;
//Array that will receive the audio urls from the page
var audioLinks = [];

//Upon receving a message from the page...
window.onmessage = (event) => {
    if (event.data) {
       //Pass the audio urls array to our new array
       audioLinks = event.data;
       //Reset the counter	
       k = 0;	
       //Create the new audio objects using the audio urls received	
       for(var i = 0; i < audioLinks.length; i++)
		{
		playList[i] = new Audio();
		playList[i].src = audioLinks[i];
		}
                    }
  				};

//Function that sends a message to the page      
function htmlIsReady() {
    window.parent.postMessage("html_is_ready", "*");  
} 	

//Function that controls the loop and also plays the audio
function playNext() {
     if(k == playList.length)
     k = 0;		
     playList[k].play();
     k++;    
   }

</script>

<!– Button that executes the function that plays the audio everytime it's clicked –>
<button class="button" onclick="playNext()">Play Next (html1)</button>

</body>
</html>

Html component #html2

<!DOCTYPE html>
<html>
<head>
<style>
.button {
    background-color: dodgerblue;
    border: none;
    color: white;
    padding: 15px 25px;
    text-align: center;
    font-size: 16px;
    cursor: pointer;
    border-radius: 8px;
    outline: none;
}

.button:hover {
    background-color: #2B689C;
}
</style>
</head>

<!– When the html component finishes loading, it executes this function that sends a message to the page –>
<body onload="htmlIsReady()">
<script type="text/javascript">

//Variable that will be the audio object
var audio;
//Variable that will receive the audio url  
var audioLink;

//Upon receing a message from the page...
window.onmessage = (event) => {
    if (event.data) {
	//Passes the audio url to the new variable
        audioLink = event.data;
	//Created a new audio object with the received audio url		
	audio = new Audio(audioLink);			
                    }
  				};

//Function that sends a message to the page      
function htmlIsReady() {
    window.parent.postMessage("html_is_ready", "*");  
}	

//Funcion that plays the audio
function playAudio() {
     audio.play();   
   }

</script>

<!– Button that executes the function that plays the audio everytime it's clicked –>
<button class="button" onclick="playAudio()">Play (html2)</button>

</body>
</html>

Html component #html3

<!DOCTYPE html>
<html>
<body style="background-color:dodgerblue; color:white;font-size: 17px">

<p style="text-align:center;">HTML COMPONENT</p>
<p style="text-align:center;">INTERACT WITH IT BY CLICKING ANYWHERE INSIDE IT OR CHROME WON'T ALLOW THE AUDIO TO PLAY</p>
<p style="text-align:center;">(try clicking the button before clicking here)</p>

<script type="text/javascript">
//Upon receiving a message...
  window.onmessage = (event) => {
    if (event.data) {
       //Creates a new variable to hold the received audio url
       var audioLink = event.data;
       //Creates a new audio object using the audio url and plays it
       var audio = new Audio(audioLink);
       audio.play();        	
    }
  }; 
  
</script>
</body>
</html>

Page code

$w.onReady(function () {

   $w("#audioDataBase").onReady( () => {
 //Get the total number of items in the database 
 const numberOfAudios = $w("#audioDataBase").getTotalCount();
 //Get all the database items
     $w("#audioDataBase").getItems(0, numberOfAudios)
      .then( (result) => {
 let items = result.items;
 //Retrieve all the audio urls from the items array and puts them into a new array
 var audioURLs = items.map(item => item["audioLink"]);        

 //Upon receiving the message from the html component "html1" telling it's loaded, the page sends it the audio urls array and 
 //shows the html component, which in this case is a button. 
        $w("#html1").onMessage( (event, $w) => {                   
          $w('#html1').postMessage(audioURLs);
          $w('#html1').show();
} );  
 //Upon receiving the message from the html component "html2" telling it's loaded, the page sends it the audio url of the first
 //item of the array and then shows the html component, which in this case is also a button.
        $w("#html2").onMessage( (event, $w) => {                   
          $w('#html2').postMessage(items[0].audioLink);
          $w('#html2').show();          
} );
 //Upon clicking the button1, it sends the html component "html3" a message with the audio url of the first item of the array.
 //In this case the html component is not a button, but simple text.
      $w("#button1").onClick( (event, $w) => {        
      $w('#html3').postMessage(items[0].audioLink);  
} );

      } )
      .catch( (err) => {
 let errMsg = err.message;
 let errCode = err.code;
      } );

  } );
});
2 Likes

Great work Matheus, thanks!

I’m going to see if I can use

2 Likes

Hello

I’ve been going over the code you provided but I’m new to JavaScript and Wix so i don’t know if I’ve missed something or havent added the right data into the functions. For exaple, am i suppose to change the #audioDataBase? Do i have to create a new collection in the Database with the audio file there?

I’m trying to create a OnClick event that when an image is clicked on it plays a sound clip i have on Wix.

Any help would be appreciated. Thank you for your time.

Any chance you’d be willing to implement this on a site - for hire? Just don’t have time, and need to get it done :slight_smile: