Custom Audio Player with Web Component and Web Audio API
HTML-код
- Опубликовано: 31 май 2024
- A step-by-step guide on how to create a custom audio player with web component and web audio API with powerful CSS and Javascript techniques
website = beforesemicolon.com/blog
medium = / beforesemicolon
[Follow]
- Instagram = / before_semicolon_
- twitter = / beforesemicolon
- facebook = / beforesemicolon
- codepen = codepen.io/beforesemicolon
- reddit = / beforesemicolon
[Playlist]
• Build Web Views & UI E...
[Source Code]
github.com/beforesemicolon/BF...
How do you solve audio player needs of your projects now?
Would like to see the same implementation in a specific UI library or framework?
- react
- angular
- vue
- svelte
- web components
- other
Yeah you can
This channel is a treasure for new devs
I really think so :)
This channel deserve more views! Thanks for this awesome video
I appreciate that! thank you!
This one saved me hours of try and error. Thanks Mate
Glad to help. Thanks for the feedback
This is very nice, I always wondered how custom media players are made.
There you have it. Hopefully this help you get enough idea of the behind the scenes
Thanks for this quality content
Anytime :). Stay tuned for more
Yes, it is grat channel about web development!
Thanks and welcome to BFS :)
Hello!
Thanks for yout great explainer.
Can I ask?
How to make to playe only one track in same time, when on the page plased several audio players?
Thanks!
Thank you. Just to make sure I understand you. You want to know how to place several players on the page playing at the same time?
Great video; appreciate the pace. One thing, I got to your website (specifically your blog) but you don't have RSS. I would add that as while RSS isn't the "killer app" for the masses those who use RSS are often powerful advocates.
Thank you. Thats something I am currently working on as I am redoing the website. Appreciate the feedback. Thanks
Is there a way to capture a webcams audio and put into a html or css, script for a webpage. I have been trying to find a way to install my cams audio while I am in a live video session to my webpage but have not found any scripts showing how to do this? I also like to see if I can put a listen live to my show button when clicked it goes into the webpage and show a player for my live broadcast. is there a way to do this??
Certainly it can. Its done all over RUclips and Twitch.
What you are describing is the magic of WebRTC. We are not talking about a simple script but an entire system setup depending on how deep you want to go.
Here is an article that gives you a glimpse over it: web.dev/getusermedia-intro/
Learn more about WebRTC here: developer.mozilla.org/en-US/docs/Web/API/WebRTC_API
great work, I really like it
Thank you
thank you so much for this work, please tell me how to make sure that when playing another track on the page, the first one is paused
No problem.
For that you will need some type of audio manager which has references to all audio tags and keeps track on what it is currently playing. Once one is played you iterate to all other ones and pause() them.
If you only have one tag and have multiple audio, you probably need a playlist player.
@@BeforeSemicolon there are several tags on the page, is it possible to track clicks somehow, I'm just learning and it's a little difficult for me to understand all this))) tried to intercept events, but failed)
document.addEventListener('play', function(e) {
var audios = document.getElementsByTagName('audio');
for(var i = 0; i < audios.length; i++) {
if(audios[i] != e.target) {
audios[i].pause();
}
}
}, true);
Add the same class to all of them and query them by it.
You will have to dispatch the play and pause events from the audio component where they happen
dispatchEvent(new CustomEvent(“playing”))
dispatchEvent(new CustomEvent(“paused”))
this will be the now 13th comment with literally the same message - love your content
Haha keep them coming yo…I appreciate it. Will do my best so you keep posting these comments :)
Hello, how do you think we can make this work on ios devices and safari because there is no support for the webkit-slider-thumb ?
Hi. There are a few ways but first let me recommend you a quick read on this in general: www.hongkiat.com/blog/html5-range-slider-style/
A more elaborated alternative is to create that element from scratch using javascript, you our HTML tags and CSS without forgetting accessibility support.
Try it out, let me know, ill try to update the code as well
Hi everyone, can you help me ? How can I make the sound bars with rounded corner like bar-radius: 5 (or something like this)
You can follow this to achieve rounded corners:
stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-using-html-canvas
@@BeforeSemicolon ok, thank you very much
Anytime
geezeus way above my head tbh
Sorry.. anything i can help you with?
I am now struggling with the streaming, because i am serving the audio from a proxy and i get hundreds of calls when you start playing with the progress bar, is there a simple way to limit the calls? may be if the progress bar has less positions? thanks a lot!
This implementation does not do anything about calling the BE. All that is handled by the browser. If you provide a streaming link then data is fetched as it plays and move the progress bar. Browser is simply trying to collect the chunks for the audio i believe.
What is the behavior when you use a simple audio tag? If the same then id look at your BE setup else, share more details for me to understand the issue better.
Progress is for every second and by default is set to 1.
You can specify the “step” attribute on the “progress-bar” input field and see if that helps.
@@BeforeSemicolon Thanks again for your reply. The simple audio tag sends hundreds of requests, most of them cancelled while you drag the bar from side to side fast. If you point the url to an S3 bucket, then its AWS problem, but if you point to your own proxy server (to protect the S3 links) then you receive hundreds of requests in your poors man BE. The perfect goal would be to avoid those hundreds of calls just making the progress bar "jump" in increments instead of allowing "pixel level" movement. Any advice to make that right is a great help. I cant check that in the BE because if this scales and a load balancer sends each chunk request to a different container in the BE, i cant track the possition to filter some of them.
Im looking into this. Will get back to you sson
Greate content mate. Would you please let me know what extension you use to format HTML inside JavaScript?
thanks!!
Thanks. I am using WebStorm here. It has its own HTML in Js intellisence
@@BeforeSemicolon ooh ok, I didn't realize that. I'm kinda struggling to find a VS code extension that can help me with that.
I am currently building one for that actually. Your best bet would something like this marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html
Hi, thanks for your videos, I love them! But can you make a tutorial how to make a custom tag input in html css and js?
Thank you.
Have you see this video I made? ruclips.net/video/3AK3vspZvvM/видео.html
It can be wrapped in a webcomponent pretty easily.
@@BeforeSemicolon Yea I saw this video, but you don't have a tutorial how to make a custom TAG input in html css and javascript. I found no good tutorial on youtube that explains how to do that :(
Ill try to make some here, meanwhile let me recommend a read developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
@@BeforeSemicolon Thank you :D
Is there a way to stream audio? I have a local radio station and I would like to put it on my html
Hi Junior, I dont quite understand the question, you can just provide the link or path to the audio and should be fine. Did you try and it did not work?
having issue with: MediaElementAudioSource outputs zeroes due to CORS access restrictions for FILE...
If your file is coming from server then allow cors on that endpoint at least. Which server are you using?
@@BeforeSemicolon I am not working on server yet it is on local disk. when i make research i see that chrome doesnt give permission to autoplay any audio. So i need to disable it i guess but i couldnt find how to do it.
Thats new to me. Ill have that in mind but I dont know the solution for this issue yet
Try setting crossorigin="anonymous" on the audio tag
Thanks for the tutorial. The source code works perfectly in Safari after adding an audio file. Chrome however doesn't have a good luck. The duration and time value works well but the actual sound doesn't play. Does anyone have a clue?
Thanks for feedback.
The video is done using chrome. Can you tell me what version and OS you are using?
Do you see any errors in the console that you can provide as well?
@@BeforeSemicolon thanks for getting back to me promptly mate. Here goes what I've got:
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
MediaElementAudioSource outputs zeroes due to CORS access restrictions for file:///Users/{username}/sites/BFS-Projects/sound-of-waves-marine-drive-mumbai.mp3
Chrome Version 111.0.5563.19 (Official Build) beta (x86_64)
MacOS BigSur Version 11.6.5 (20G527)
Seems like that Chrome bans playing music without the user interacting the page first. I however removed the 'autoplay' prop in the audio-player tag but still doesn't work!
Thank you. Ill get back to you after I reproduce and fix this
@@BeforeSemicolon thank you so much!
If you are just right clicking on the HTML file and opening it in chrome you will likely get CORS error and therefore will not play but you will see the progress bar move.
Open it in some localhost project and it will be fine.
Neat.. (BUT) I am stumped .. No Audio when I click (yes I have the sample mp3 named "audio2.mp3" .. Progress Bar moves forward.. (But no Sound or spectrum) ?? any Idea WHY ??
This likely permissions of the browser
www.alphr.com/fixes-sound-not-working-chrome/
Please let me know about the browser, version and OS. Inspect and let me know if any error or warning is shown in the console
@@BeforeSemicolon My browser version is (Chrome) Version 111.0.5563.65 (Official Build) (64-bit) (Up to date it says) OS is Windows 10. In Chrome the setting (Sites can play sounds selected ON) Just won't play your Downloaded Code example.. (Off Line) .. I was reading that (Browsers will Block) off-line Visualizations because of Security ??.. Is there a way to (Bypass the Security Restriction safely ??)
If you are just right clicking on the HTML file and opening it in chrome you will likely get CORS error and therefore will not play but you will see the progress bar move.
Open it in some localhost project and it will be fine.
@@BeforeSemicolon No I am not "Right Clicking" open with chrome.. I just "Double Left click" on the index.html (Default Browser is Chrome) no sound no visualization ... Only the player visible.. When Play is clicked the progress bar moves (and time) that is all.. (opening in what you call) -- LocalHost project.. (I am a noob) and don't know how to do that😥
Yeah thats the same thing. Dont open it straight from a file in the browser (right or double click). You will see a CORS warning/error in the console when you inspect the page.
Creating a project/app should be the first thing you learn before anything. You can create a react app. Any app should be fine. Then you just add this to it and use it normally. Imma let you do the homework on that.
Looking to spice up the Google site audio player.
Sounds interesting. Please share resulting
Thanks for your video. The player works nicely, but I found a little bug and don't know how to fix it. (maybe that's my problem, not yours)
On my main page, some players play a particular song. Then, I visit another one using ... and then go back to the main page in the same way. As soon as I visit the main page, all audio players start playing all together and there is a huge chaos. I hope You can help me, thanks!
Thanks for the feedback. Are you setting autoplay?
@@BeforeSemicolon OMG, yes. I even didn't notice it. Thank You so much!
👍🏼👍🏼👍🏼
what's the problem with that Howl.js because it reset if i play then puase then play ???
class AudioPlayer {
constructor(srcAudio, srcAudioId) {
this.srcAudio = srcAudio;
this.srcAudioId = srcAudioId;
this.isPlaying = false;
this.seekPosition = 0;
this.player = new Howl({
src: srcAudio,
html5: true,
onplay: () => {
this.isPlaying = true;
console.log('onplay ' + this.srcAudioId);
},
onended: () => {
this.isPlaying = false;
console.log('onended ' + this.srcAudioId);
},
onpause: () => {
this.isPlaying = false;
this.seekPosition = this.player.seek();
console.log('onpause ' + this.srcAudioId);
},
onseek: (event) => {
console.log('onseek ' + this.srcAudioId);
console.log(event);
},
});
}
play() {
console.log('play ' + this.srcAudioId);
this.player.seek(this.seekPosition);
this.player.play();
this.isPlaying = true;
}
pause() {
console.log('pause ' + this.srcAudioId);
this.seekPosition = this.player.seek();
this.player.pause();
this.isPlaying = false;
}
togglePlay() {
if (this.player.playing([this.srcAudioId])) {
this.pause();
} else {
this.play();
}
}
}
const audioModuleControll = (() => {
let audioPlayers = {};
function togglePlayAudio(element) {
const srcAudio = element.getAttribute('data-audio');
const srcAudioId = element.getAttribute('data-id');
if (audioPlayers[srcAudioId]) {
const player = audioPlayers[srcAudioId];
player.togglePlay();
} else {
console.log('playing for the first time', srcAudioId);
const player = new AudioPlayer(srcAudio, srcAudioId);
player.play();
audioPlayers[srcAudioId] = player;
}
}
function addEventListenersFun() {
const playButtons = document.querySelectorAll('.voice-assistant-item .playstory');
playButtons.forEach(function(playButton) {
playButton.addEventListener('click', function(event) {
togglePlayAudio(this);
});
});
}
return {
addEventListenersFun: addEventListenersFun
};
})();
document.addEventListener("DOMContentLoaded", () => {
audioModuleControll.addEventListenersFun();
});
This video does not use Howl.js. Im not familiar with it to help you
@@BeforeSemicolon
thanks for your answer but what about this js code i wrote but it work on firfox not on chrome and not seek the audio in good maner not seek well it work but the point of seek when click not work specially if click after the middle of the audio progess bar
I'm not super into JS. So I thought what the hell is this syntax
this.attachShadow(init: {mode: 'open'})
Only then I realized, it's your editor showing a helper.
This is init; {} syntax is similar to keyword lists in Elixir, that's why I was confused.
I will be dropping a different version of this with a web component library I created to make all this much easier www.npmjs.com/package/cwco
Hopefully you won’t get confused by these things.
Audio Context API? Isn't the name Web Audio API? or is this something distinct?
Audio Context is part of Web Audio API.
@@BeforeSemicolon Yes but the title said Audio Context API previously.
Yup! Thanks for catching that :)
I have a question is working for android?
Hi, whats the question?
About 400 lines of JS and 25 lines of HTML. Simplicity in mind, my brain is fried with all of the algorithms lmaoo I need to learn more before taking on this much without a reference.
Hehe no biggie. Nothing like couple hours reading wouldn’t solve. Thanks
How autoplay code?
I dont understand the question…
The autoplay is just an attribute you can set on the player.
Hi, I'm new to React. I'm using NextJs 13 with Typescript. I need to extract the title from an audio stream. I already made an app using Java for Android using stream and is working and I would like to know how to do this in ReactJs. I know there are packages like “Icy Metadata”, but I don't know how to use it. Can you help me? The link of WebRadio is this: servidor18.brlogic.com:7436/live?type=.m3u
How is the client making the request?
An approach would be for the client to request details about what needs to be streamed and in that details there is a link for the stream.
From the details you would know what to display then stream the media.
Otherwise, look at the response header and look at what metadata is been shared.
This is not a React or UI issue. Its general network and API question. Id recommend jumping into that
Can we do this using React?
You can. Its totally possible
@@BeforeSemicolon I'm going to attempt it following your video. Since i will be extending React.Component instead will still be able to use the same code you wrote within your class? Or would that not work properly? thanks!
Does not work like that…create a normal react component and move thongs from my code to it piece by piece
Were you able to get this working in React?
You can use it in React or any other framework.
web-highlights.com/blog/how-to-use-web-components-in-react/
Please multitrack player for web
Will work on it. Stay tuned for an entire library build videos 😊
Cool, but now I don’t know why any of this works.
Two things to become familiar with
- web components (i have a video for it in this channel)
- the Web Audio API (can get super complex)
All that on top of basic JS, CSS, HTML knowledge
please if you can read my custom js code and give me feedback i hope you will do i paste it in reply i use foreach in my project from db then i used the custom js then it not supported in all browers so i go to Howl so if you can help in custom js i will be happey for that.
Hey there, excellent craft! much respect. Though I am experiencing clicks and pops on the audio, anyone also having the same? @BeforeSemicolon, any experience with that?
Hi, sorry to hear that. Im yet to experience such thing. My guess would be that maybe it is related to the gain. Can you make sure the gain is been initialized first to a valid and positive number ?