I am trying to add play/pause toggle functionality to a single button for an mp3 player project where the play button will turn to a "||" icon when music is playing and will revert to the play button when the music is paused by only using vanilla JavaScript. I have tried implementing an if-else statement which seems to be commonly used for this type of functionality, but the icon will only change to the "||" icon when the song is played, but will not pause and change to the play icon when clicked again. I have tried creating a separate function for the task of pausing the song, but still not getting the desired result.
var playButton = document.querySelector('#play-button');
var songArtist = document.querySelector('.song-artist');
var songTitle = document.querySelector('.song-name');
var stateIcon = document.querySelector('#stateicon');
var trackList = [ {
'Songartist': 'Artist1',
'Songtitle': 'Dance',
'songfile': 'Dance.mp3'
},
{
'Songartist': 'Artist2',
'Songtitle': 'Fight',
'songfile': 'Battle.mp3'
}
];
var currentSong = 0;
var song = new Audio();
function playSong() {
song.src = trackList[currentSong].songfile;
songArtist.innerText = trackList[currentSong].Songartist;
songTitle.innerText = trackList[currentSong].Songtitle;
if (song.paused) {
stateIcon.className = 'fas fa-pause';
song.play();
} else {
stateIcon.className = 'fas fa-play';
song.pause();
}
}
<body>
<div class="screen">
<div class="song-info-text">
<p class="song-artist">Some text</p>
<p class="song-name">Some more text</p>
</div>
</div>
<div class="mp3-buttons">
<button class="button" type="button" name="button"><i class="fas fa-step-backward"></i></button>
<button id="play-button" onclick="playSong()"><i id="stateicon" class="fas fa-play"></i></button>
<button onclick="nextSong()" class="button" type="button" name="button"><i class="fas fa-step-forward"></i></button>
</div>
<script src="index.js" charset="utf-8"></script>
</body>
The snipped provided is incomplete (no element has the class "song-artist", for one). I'd suggest looking at your javascript dev console for any errors, first. Otherwise, it could be that setting the src of your audio element is resetting your audio's play state. You could try only setting the src if it's different from that of the current track.
Related
I am currently developing a music streaming platform, if you can call it that, for my final year project. I started to redeisgn a few components and wanted to make a better audio player and this is where the problem(s) started to arise. I have my content wrapped around a for loop like so
{{for song in songs}}
{{endfor}}
After that I have the following HTML section that I'm trying to get to work
<img id="playAudio" src="https://fypkmpsr.s3.eu-west-1.amazonaws.com/{{song.artwork}}" class="img-fluid" alt="{{song}}">
<audio id="audio" src="/play/{{song.id}}" type="audio/wav"></audio>
<audio controls src="/play/{{song.id}}" type="audio/wav"></audio>
<progress min="0" max="100" value="0"></progress>
<div class="controls"></div>
<button type="button" class="btn btn-secondary-outline" onclick="playPauseAudio()">
<i class="bi bi-play"></i> | <i class="bi bi-pause"></i>
</button>
<button type="button" class="btn btn-secondary-outline" onclick="muteAudio()">
<i class="bi bi-volume-mute"></i>
</button>
<input type="range" class="form-range" id="customRange1" onclick="changeVolume()">
And my accompanying JavasScript code
<script>
source = document.getElementById('source').value;
function playPauseAudio() {
var audio = document.getElementById("audio");
if (audio.paused) {
audio.play();
} else {
audio.pause();
}
}
function muteAudio() {
var audio = document.getElementById("audio");
if (audio.muted) {
audio.muted = false;
} else {
audio.muted = true;
}
}
function changeVolume() {
var audio = document.getElementById("audio");
audio.volume = document.getElementById("customRange1").value / 100;
}
var audio = document.querySelector("audio");
var progressBar = document.querySelector("progress");
progressBar.addEventListener("click", seek);
function seek(e) {
var percent = e.offsetX / this.offsetWidth;
audio.currentTime = percent * audio.duration;
progressBar.value = percent / 100;
}
</script>
And I will also supply another cause as it is related to this problem
{% for song in songs %}
<h1>{{song.title}}</h1>
<input type="hidden" id="source" name="source" value="https://fypkmpsr.s3.eu-west-1.amazonaws.com/{{song.source}}">
<div id="waveform"></div>
<button class="btn btn-primary" onclick="wavesurfer.playPause()">
<i class="fa fa-play"></i>
Play
/
<i class="fa fa-pause"></i>
Pause
</button>
<script type=text/javascript>
var wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet',
progressColor: 'purple'
});
var element = document.getElementById('source').value;
wavesurfer.load("https://fypkmpsr.s3.eu-west-1.amazonaws.com/{{song.source}}");
</script>
{% endfor %}
The problem from all of the above code is when I started to implement wavesurfer, a audio waveform visualizer. The code misbehaved for me as it created all the waveforms under one song heading / id. And it either played the last song or the first song in the database, depending on how I passed in my song source. The same applied to my own music player from the first snippet. No matter on what song I clicked on to play the audio file, it always plays the newest song i.e. the newest added id.
I've tried to break the code down and get the following as desired. I'd like to assume the problem persists from how I pass my data through and not making it unique but I'm not too sure if this is the case and where do I start from here.
The audio visualizations are meant to be under each heading and not under the newest song.
In my API class today we learned how to show the camera with the tag. We also learned how to add effects with JavaScript. But, I'm stuck on how to reverse these effects. How would I make the clear button clear the current effect?
<body>
<h1>Magic Camera</h1>
<div class="tools">
<button id="sepia">Sepia</button>
<button id="">Clear</button>
</div>
<div class="scene">
<img src="billboard.jpg">
<div class="video-container">
<video id="myCamera" autoplay></video>
</div>
</div>
<script>
var myDevices = navigator.mediaDevices;
var permissions = {
audio: false,
video: true
};
myDevices.getUserMedia(permissions).then(showCam);
function showCam(stream){
$("#myCamera")[0].srcObject = stream;
}
function addEffect(event){
var effect = event.currentTarget;
var filter = `${effect.id}(1)`;
$("#myCamera").css("filter", filter);
}
$("button").click(addEffect);
</script>
</body>```
$('#myCamera').css('filter', '');
I'm trying to develop a simple mp3 player with play/pause toggle functionality where the play button turns to a "||" icon when music is playing and reverts to the play button when the music is paused by using purely vanilla Javascript. I have viewed other posts regarding this matter, but none of them have helped me with the way I currently have my code structured.
var playButton = document.querySelector('#play-button');
var firstSong = new Audio('CloudDance.mp3');
var trackList = [firstSong];
function currentSong() {
for(var i=0; i<trackList.length; i++) {
var songID = document.querySelector('#stateicon');
if (trackList[i].paused) {
songID.id = 'fas fa-pause';
trackList[i].play();
} else {
songID.addEventListener('click', ) = 'fas fa-play';
trackList[i].pause();
}
}
}
<body>
<div class="screen">
<div class="song-info-text">
<p class="song-artist">Some text</p>
<p class="song-name">Some more text</p>
</div>
</div>
<div class="mp3-buttons">
<button class="button" type="button" name="button"><i class="fas fa-step-backward"></i></button>
<button id="play-button" onclick="currentSong()" type="button" name="button"><i id="stateicon" class="fas fa-play"></i></button>
<button class="button" type="button" name="button"><i class="fas fa-step-forward"></i></button>
</div>
<script src="index.js" charset="utf-8"></script>
</body>
All you need to do is set the class name depending on what you want. Here is your example with the fix.
songID.className = 'fas fa-pause';
Here is the sample code used in the JSFiddle link below
var playButton = document.querySelector('#play-button');
var firstSong = new
Audio('https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3');
var trackList = [firstSong];
function currentSong() {
for(var i=0; i<trackList.length; i++) {
var songID = document.querySelector('#stateicon');
if (trackList[i].paused) {
songID.className = 'fas fa-pause'; // Notice how we set className
trackList[i].play();
} else {
songID.className = 'fas fa-play'; // Notice how we set className
trackList[i].pause();
}
}
}
I also updated font-awesome css url in html to make sure the fonts would work properly. This is another part of the fix
<header>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"/>
</header>
JSFiddle Working Example
NOTE: You may end up running into issues later as you will end up playing multiple files at the same time with the way you have the for loop. So just keep in mind that you need to know which song it's currently playing so that you can properly pause or play that same song. And switch the current song when hit forward or backwards depending on the button pressed.
Is it possible to play a song using a font awesome icon, for example on the left will be the song name(mp3) and just to right of the track name will be a play font awesome icon, is it possible for a user to click on the play icon and the track starts playing and they can pause it and stop it
There will be about 10 tracks in the list
Has anyone got a sample code or a link to something similar please? I am guessing it will need some sort of javascript for the icons to be able to play, pause and stop
I found this code: http://jsfiddle.net/7341jxv6/2/ but am trying to amend it to use the font awesome play and pause icons instead of the text play and pause
My updated code is below
<audio id="audio1" src="tracks/ub40-ska/kingston-town.mp3"></audio>
<audio id="audio2" src="tracks/ub40-ska/homely-girl.mp3"></audio>
<audio id="audio3" src="tracks/ub40-ska/red-red-wine.mp3"></audio>
<audio id="audio4" src="tracks/ub40-ska/one-in-ten.mp3"></audio>
<div class="play" id="btn1"><i class="fa fa-play-circle" aria-hidden="true"></i></div>
<div class="play" id="btn2"><i class="fa fa-play-circle" aria-hidden="true"></i></div>
<div class="play" id="btn3"><i class="fa fa-play-circle" aria-hidden="true"></i></div>
<div class="play" id="btn4"><i class="fa fa-play-circle" aria-hidden="true"></i></div>
<script>
$('.play').click(function(){
var $this = $(this);
var id = $this.attr('id').replace(/btn/, '');
$this.toggleClass('active');
if($this.hasClass('active')){
$this.addClass('fa-pause-circle');
$('audio[id^="audio"]')[id-1].play();
} else {
$this.removeClass('fa-play-circle');
$('audio[id^="audio"]')[id-1].pause();
}
});
</script>
If I click on the play icon, it does play but the icon then disappears but if I click in the same place, it does pause the music
You can write click listener for the fa-icon;
DOM looks like this
<div class="play-tab">
<div class="track-name">Some Track Name<div>
<span class="icons"><i class="fa fa-play"/><span>
<div>"
JQuery
$(".play-tab").on("click" , "i", function(e){//fetch song id and play})
if you use the same button then you need a function that will change the icon and stop/play music
var myAudio = document.getElementById('media_audio');
var icon = document.getElementById('toglePlayPause');
var togglePlayPauseButton = document.getElementById('media_controls_play-pause-button');
//Event listener for the play button
togglePlayPauseButton.addEventListener("click", function() {
if ( myAudio.paused || myAudio.ended) {
if ( myAudio ) {
myAudio.title = 'Play';
icon.className = "fa fa-play";
}
myAudio.play();
} else {
if ( myAudio ) {
myAudio.title = 'Pause';
icon.className = "fa fa-pause";
}
myAudio.pause();
}
});
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="media_player">
<audio id="media_audio" >
Your browser does not support the audio tag.
</audio>
<div id='media_controls' >
<button
id="media_controls_play-pause-button"
class='icon'
title="Pause">
<i id="toglePlayPause" class="fa fa-pause"></i>
</button>
</div>
</div>
I have updated the code above as getting bit closer but got the issue of the icon disappearing after clicking play
You try to change icon on button element but the icon is on "i" tag.
To fix the bug you need to add a small fixes to your code
$('.play').click(function(){
var $this = $(this);
var id = $this.attr('id').replace(/btn/, '');
$this.toggleClass('active');
if($this.hasClass('active')){
$this.find("i").removeClass('fa-play-circle');
$this.find("i").addClass('fa-pause-circle');
$('audio[id^="audio"]')[id-1].play();
} else {
$this.find("i").removeClass('fa-pause-circle');
$this.find("i").addClass('fa-play-circle');
$('audio[id^="audio"]')[id-1].pause();
}
});
I'm new to JQuery and JavaScript and I have this situation:
<button style="background-color: #dfe52d;border:4px solid #dfe52d"
class="button" type="button" >Play Me!</button>
<audio class="audio" src="audio.mp3" type="audio/mpeg"></audio>
There are many buttons on my page, all with the same structure. For each button I want play a different sound:
$(document).ready(function(){
$("button").click(function(){
var isPlaying=false
var audio = $(this).next().attr("src");
var music = new Audio(audio);
if(isPlaying) {music.pause()}
else{music.play();$(this).text("Stop Me")}
});
});
When a button is clicked, the sound plays and the button text changes to "stop me". How can I write the code to stop the audio? Also, if the user presses another button the current song must stop. How can I achieve this? Thanks.
Try setting the isPlaying outside of the button click event and querying that so you know the state when you press the button. At the moment you set isPlaying to false every time you click.
var isPlaying=false
$(document).ready(function(){
$("button").on("click", function(){
var audio = $(this).next().attr("src");
var music = new Audio(audio);
if (!isPlaying) {
// Not playing, let's play
isPlaying = true;
music.play();
$(this).text("Stop Me")
} else {
// Stop the music
isPlaying = true;
music.pause();
$(this).text("Play");
};
});
});
Here's the cleanest solution. Most of the functionality you're looking for is already built into the JavaScript for audio tags.
<script>
$(document).ready(function(){
$("button").click(function(){
var audio = $(".audio")[0];
if (audio.paused) {
audio.play();
$(this).html("Stop me!");
} else {
audio.pause();
$(this).html("Play me!");
}
});
});
</script>
hi thanks all of you for the quick response.
unfortunately this two solution didnt work out, so i opted for this:
<button style="background-color: #dfe52d;border:4px solid #dfe52d;" class="button" onclick="document.getElementById('audio1').play()" type="button" >Play Me!</button>
<button style="background-color: #dfe52d;border:4px solid #dfe52d;" class="button" onclick="document.getElementById('audio1').pause()" type="button" >Stop Me!</button>
<button style="background-color: #dfe52d;border:4px solid #dfe52d;" class="button" onclick="document.getElementById('audio1').currentTime=0.0" type="button" >Restart Me!</button>
<audio class="audio" id="audio1" src="audio.mp3" type="audio/mpeg"></audio>
Now works fine except one problem, i need a function to stop the current sound when another button is pressed. Is it a simple task in your opinion? Thank you