1

I apologize if the title isn't clear, I created a simple audio player with html and java, is there a way to put multiple of these on my website without the need to rewrite all the variables, IDs and stuff?

I think I'd need to use classes, but I don't really have much knowledge about OOP, so any help is appreciated.

Here's my html:

<body>
    <div id="wrapper">
        <fieldset>
            <legend>Song</legend>
            <div id='player'>
                <audio id="music_player" preload="metadata" loop>
                    <source src="music\song.mp3">
                </audio>
                <input type="image" src="images/playButton.png" onclick="play_aud()" id="play_button">
                <input type="image" src="images/pauseButton.png" onclick="pause_aud()" id="play_button">
                <input type="image" src="images/stopButton.png" onclick="stop_aud()" id="play_button">
                <span id="current-time" class="time">0:00</span>
                <input type="range" id="seek-slider" max="100" value="0">
                <span id="duration" class="time">0:00</span>
                <input type="image" src="images/volumeButton.png" id="vol_img" onclick="mute()">
                <input type="range" id="change_vol" onchange="change_vol()" step="0.05" min="0" max="1" value="1">
            </div>
        </fieldset>
    </div>
</body>
<script src="script.js"></script>

And Javascript:


let muteState = 'unmute';

var player;

const audioButton = document.getElementById('vol-img');
const currentTimeContainer = document.getElementById('current-time');
const audio = document.querySelector('audio');
const durationContainer = document.getElementById('duration');
const seekSlider = document.getElementById('seek-slider')
const calculateTime = (secs) => {
    const minutes = Math.floor(secs / 60);
    const seconds = Math.floor(secs % 60);
    const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
    return `${minutes}:${returnedSeconds}`;
}
const displayDuration = () => {
    durationContainer.textContent = calculateTime(audio.duration);
}
const setSliderMax = () => {
    seekSlider.max = Math.floor(audio.duration);
}
const displayBufferedAmount = () => {
    const bufferedAmount = Math.floor(audio.buffered.end(audio.buffered.length - 1));
    audioPlayerContainer.style.setProperty('--buffered-width', `${(bufferedAmount / seekSlider.max) * 100}%`);
}

function startplayer() 
{
 player = document.getElementById('music_player');
 player.controls = false;
}
function play_aud() 
{
 player.play();
} 
function pause_aud() 
{
 player.pause();
}
function stop_aud() 
{
 player.pause();
 player.currentTime = 0;
}
function change_vol()
{
 player.volume=document.getElementById("change_vol").value;
}
function mute()
{
    if(muteState == 'mute')
    {
        document.getElementById('vol_img').src = 'images/volumeButton.png';
        muteState = 'unmute';
        audio.muted = false;
    }
    else
    {
        document.getElementById('vol_img').src = 'images/volumeButtonmute.png';
        muteState = 'mute'
        audio.muted = true;
    }
};

if (audio.readyState > 0) {
    displayDuration();
    setSliderMax();
    displayBufferedAmount();
} else {
    audio.addEventListener('loadedmetadata', () => {
        displayDuration();
        setSliderMax();
        displayBufferedAmount();
    });
}

audio.addEventListener('progress', displayBufferedAmount);

seekSlider.addEventListener('input', () => {
  currentTimeContainer.textContent = calculateTime(seekSlider.value);
});

seekSlider.addEventListener('change', () => {
    audio.currentTime = seekSlider.value;
});
audio.addEventListener('timeupdate', () => {
    seekSlider.value = Math.floor(audio.currentTime);
    currentTimeContainer.textContent = calculateTime(audio.currentTime);
});

1 Answer 1

1

i have converted all code to class based so now you can create as many instances as you want

i have changed all getElementById to querySelector since its more suitable for this situation

class audio_player{
    constructor(root){
        this.html = `
            <div id="wrapper">
                <fieldset>
                    <legend>Song</legend>
                    <div id='player'>
                        <audio id="music_player" preload="metadata" loop>
                            <source src="music\song.mp3">
                        </audio>
                        <input type="image" src="images/playButton.png" onclick="play_aud()" id="play_button">
                        <input type="image" src="images/pauseButton.png" onclick="pause_aud()" id="play_button">
                        <input type="image" src="images/stopButton.png" onclick="stop_aud()" id="play_button">
                        <span id="current-time" class="time">0:00</span>
                        <input type="range" id="seek-slider" max="100" value="0">
                        <span id="duration" class="time">0:00</span>
                        <input type="image" src="images/volumeButton.png" id="vol_img" onclick="mute()">
                        <input type="range" id="change_vol" onchange="change_vol()" step="0.05" min="0" max="1" value="1">
                    </div>
                </fieldset>
            </div>    
        `
        root.innerHTML = this.html
        this.html = root
        this.interactivity()
    }

    interactivity(){
        let muteState = 'unmute';
        var player;

        const audioButton = this.html.querySelector('#vol-img');
        const currentTimeContainer = this.html.querySelector('#current-time');
        const audio = this.html.querySelector('audio');
        const durationContainer = this.html.querySelector('#duration');
        const seekSlider = this.html.querySelector('#seek-slider')
        const calculateTime = (secs) => {
            const minutes = Math.floor(secs / 60);
            const seconds = Math.floor(secs % 60);
            const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
            return `${minutes}:${returnedSeconds}`;
        }
        const displayDuration = () => {
            durationContainer.textContent = calculateTime(audio.duration);
        }
        const setSliderMax = () => {
            seekSlider.max = Math.floor(audio.duration);
        }
        const displayBufferedAmount = () => {
            const bufferedAmount = Math.floor(audio.buffered.end(audio.buffered.length - 1));
            audioPlayerContainer.style.setProperty('--buffered-width', `${(bufferedAmount / seekSlider.max) * 100}%`);
        }

        function startplayer() 
        {
        player = this.html.querySelector('#music_player');
        player.controls = false;
        }
        function play_aud() 
        {
        player.play();
        } 
        function pause_aud() 
        {
        player.pause();
        }
        function stop_aud() 
        {
        player.pause();
        player.currentTime = 0;
        }
        function change_vol()
        {
        player.volume=this.html.querySelector("#change_vol").value;
        }
        function mute()
        {
            if(muteState == 'mute')
            {
                this.html.querySelector('#vol_img').src = 'images/volumeButton.png';
                muteState = 'unmute';
                audio.muted = false;
            }
            else
            {
                this.html.querySelector('#vol_img').src = 'images/volumeButtonmute.png';
                muteState = 'mute'
                audio.muted = true;
            }
        };

        if (audio.readyState > 0) {
            displayDuration();
            setSliderMax();
            displayBufferedAmount();
        } else {
            audio.addEventListener('loadedmetadata', () => {
                displayDuration();
                setSliderMax();
                displayBufferedAmount();
            });
        }

        audio.addEventListener('progress', displayBufferedAmount);

        seekSlider.addEventListener('input', () => {
        currentTimeContainer.textContent = calculateTime(seekSlider.value);
        });

        seekSlider.addEventListener('change', () => {
            audio.currentTime = seekSlider.value;
        });
        audio.addEventListener('timeupdate', () => {
            seekSlider.value = Math.floor(audio.currentTime);
            currentTimeContainer.textContent = calculateTime(audio.currentTime);
        });
    }
    
}


const newAudio1 = new audio_player(document.querySelector(".player1"))
const newAudio2 = new audio_player(document.querySelector(".player2"))
const newAudio3 = new audio_player(document.querySelector(".player3"))
<div class="player1"></div>
<div class="player2"></div>
<div class="player3"></div>

Sign up to request clarification or add additional context in comments.

1 Comment

as i can see there are some inline onClick which is not working with object model you can fix them by binding onclick inside interactivity by doing query like this.html.querySelector("#play").onclick = player.play for all inline onClick events do this and it will work normally

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.