Podcastspeler met hoofdstukken Nieuw
Audiospeler voor een podcast of opgenomen webinar: afspelen, 15 seconden terug, 30 vooruit, snelheid (1x tot 2x), een tijdlijn met streepjes per hoofdstuk en een lijst hoofdstukken die meeloopt en waar je naartoe springt. Gewoon audio-element eronder, dus de mediatoetsen van de telefoon werken (Media Session met titel en hoofdstuk). In de demo een rustige toon als geluid. Voor praktijken, adviseurs en verenigingen met een eigen podcast.
0:00
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- Podcastspeler met hoofdstukken · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="pch">
<audio class="pch__a" preload="metadata" src="https://neddev.com/lab-media/podcast-hoofdstukken-audio.mp3"></audio>
<div class="pch__top">
<img class="pch__cov" src="https://neddev.com/lab-media/podcast-hoofdstukken-1.webp" alt="" width="600" height="327">
<div class="pch__meta"><b class="pch__ti">Personeel vinden in de bouw</b><span class="pch__sub">Ondernemen in Zwolle, aflevering 14</span></div>
</div>
<div class="pch__ctl">
<button class="pch__b pch__back" type="button" aria-label="15 seconden terug"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12a7 7 0 1 0 2.1-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M4 3.5v4.4h4.4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg><span>15</span></button>
<button class="pch__b pch__play" type="button" aria-label="Afspelen"><svg class="pch__i-pl" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5.5v13l10.5-6.5z"/></svg><svg class="pch__i-pa" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 5h3.5v14H7zM13.5 5H17v14h-3.5z"/></svg></button>
<button class="pch__b pch__fwd" type="button" aria-label="30 seconden vooruit"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M19 12a7 7 0 1 1-2.1-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M20 3.5v4.4h-4.4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg><span>30</span></button>
<div class="pch__tlw"><div class="pch__ticks" aria-hidden="true"></div><input class="pch__tl" type="range" min="0" max="160" step="1" value="0" aria-label="Tijdlijn" aria-valuetext="0:00 van 2:40"></div>
<span class="pch__t">0:00</span>
<button class="pch__spd" type="button" aria-label="Afspeelsnelheid 1 keer">1x</button>
</div>
<ol class="pch__ch" aria-label="Hoofdstukken"></ol>
</div>
</div>/* Podcastspeler met hoofdstukken · NedDev · eigen werk. */
.pch{position:absolute;inset:0;display:flex;flex-direction:column;padding:12px 14px 8px;background:#fff;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:left;box-sizing:border-box}
.pch__top{display:flex;align-items:center;gap:10px}
.pch__cov{flex:none;width:44px;height:44px;border-radius:4px;object-fit:cover}
.pch__meta{display:flex;flex-direction:column;gap:2px;min-width:0}
.pch__ti{font:600 15px/1.2 'Switzer',sans-serif;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pch__sub{font:400 12px/1.3 'Switzer',sans-serif;color:#5c5a57}
.pch__ctl{display:flex;align-items:center;gap:4px;margin:8px 0 6px}
.pch__b{position:relative;flex:none;width:30px;height:30px;padding:0;border:0;border-radius:4px;background:transparent;color:#0a0a0a;display:grid;place-items:center;cursor:pointer}
.pch__b svg{width:22px;height:22px;fill:currentColor}
.pch__back svg,.pch__fwd svg{fill:none}
.pch__b span{position:absolute;left:0;right:0;top:50%;margin-top:-6px;font:600 12px/12px 'Switzer',sans-serif;text-align:center;transform:scale(.72)}
.pch__b:hover{background:#f4f3f1}
.pch__play{width:34px;height:34px;background:#F5480F;color:#fff}
.pch__play:hover{background:#e03f0a}
.pch__i-pa{display:none}.pch.is-playing .pch__i-pl{display:none}.pch.is-playing .pch__i-pa{display:block}
.pch__tlw{position:relative;flex:1 1 auto;min-width:40px;height:24px}
.pch__ticks{position:absolute;left:6px;right:6px;top:50%;height:10px;margin-top:-5px;pointer-events:none}
.pch__ticks i{position:absolute;top:0;width:2px;height:10px;margin-left:-1px;background:#0a0a0a}
.pch__tl{position:relative;width:100%;height:24px;margin:0;-webkit-appearance:none;appearance:none;background:transparent;cursor:pointer;--p:0%}
.pch__tl::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(to right,#F5480F var(--p),#e1ded9 var(--p))}
.pch__tl::-moz-range-track{height:4px;border-radius:2px;background:linear-gradient(to right,#F5480F var(--p),#e1ded9 var(--p))}
.pch__tl::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;margin-top:-4px;border-radius:50%;background:#0a0a0a;border:0}
.pch__tl::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#0a0a0a;border:0}
.pch__t{flex:none;width:34px;font:500 12px/1 'Switzer',sans-serif;font-variant-numeric:tabular-nums;text-align:right}
.pch__spd{flex:none;min-width:36px;height:26px;padding:0 6px;border:1.5px solid #0a0a0a;border-radius:4px;background:#fff;color:#0a0a0a;font:600 12px/1 'Switzer',sans-serif;cursor:pointer;font-variant-numeric:tabular-nums}
.pch__b:focus-visible,.pch__spd:focus-visible,.pch__tl:focus-visible,.pch__cb:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.pch__ch{list-style:none;margin:0 -6px;padding:0 0 10px;overflow-y:auto;-webkit-mask:linear-gradient(#000 calc(100% - 18px),transparent);mask:linear-gradient(#000 calc(100% - 18px),transparent);flex:1 1 auto;min-height:0;scrollbar-width:thin}
.pch__cb{display:flex;gap:10px;width:100%;min-height:26px;padding:4px 6px;border:0;border-radius:4px;background:transparent;color:#0a0a0a;font:400 13px/1.3 'Switzer',sans-serif;text-align:left;cursor:pointer}
.pch__cb time{flex:none;width:30px;color:#5c5a57;font-variant-numeric:tabular-nums;font-size:12px;line-height:17px}
.pch__cb:hover{background:#f4f3f1}
.pch__cb[aria-current="true"]{background:#f4f3f1;font-weight:600}
.pch__cb[aria-current="true"] time{color:#F5480F}// Podcastspeler met hoofdstukken · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.pch');if(!w)return;
var a=w.querySelector('.pch__a'),play=w.querySelector('.pch__play'),tl=w.querySelector('.pch__tl'),t=w.querySelector('.pch__t'),spd=w.querySelector('.pch__spd'),ol=w.querySelector('.pch__ch'),ticks=w.querySelector('.pch__ticks');
var C=[[0,'Even voorstellen: Sanne de Wit van Bouwbedrijf Hattem'],[24,'Waarom vakmensen bij een kleine aannemer kiezen'],[62,'Een vacaturetekst die wel werkt'],[101,'Stageplekken via het Deltion College'],[133,'Vragen van luisteraars']];
var D=160,rates=[1,1.25,1.5,2],ri=0,cur=-1;
function f(s){s=Math.max(0,Math.floor(s||0));return Math.floor(s/60)+':'+String(s%60).padStart(2,'0');}
var btns=C.map(function(c){var li=document.createElement('li'),b=document.createElement('button');b.type='button';b.className='pch__cb';b.innerHTML='<time>'+f(c[0])+'</time><span></span>';b.querySelector('span').textContent=c[1];
b.setAttribute('aria-label',c[1]+', begint op '+f(c[0]));b.addEventListener('click',function(){a.currentTime=c[0];if(a.paused)toggle();});li.appendChild(b);ol.appendChild(li);return b;});
function drawTicks(){ticks.innerHTML='';C.slice(1).forEach(function(c){var i=document.createElement('i');i.style.left=(c[0]/D*100)+'%';ticks.appendChild(i);});}
function ch(s){var k=0;C.forEach(function(c,i){if(s>=c[0])k=i;});return k;}
function upd(){var s=a.currentTime;tl.value=s;tl.style.setProperty('--p',(s/D*100).toFixed(2)+'%');t.textContent=f(s);tl.setAttribute('aria-valuetext',f(s)+' van '+f(D)+', '+C[ch(s)][1]);
var k=ch(s);if(k!==cur){cur=k;btns.forEach(function(b,i){if(i===k)b.setAttribute('aria-current','true');else b.removeAttribute('aria-current');});
var li=btns[k].parentNode;if(li.offsetTop<ol.scrollTop||li.offsetTop+li.offsetHeight>ol.scrollTop+ol.clientHeight)ol.scrollTop=li.offsetTop-ol.offsetTop;meta();}}
function meta(){if(!('mediaSession' in navigator))return;try{navigator.mediaSession.metadata=new MediaMetadata({title:'Personeel vinden in de bouw · '+C[Math.max(0,cur)][1],artist:'Ondernemen in Zwolle',album:'Aflevering 14'});}catch(_){}}
function toggle(){if(a.paused){var p=a.play();if(p&&p.catch)p.catch(function(){});}else a.pause();}
function sync(){var p=!a.paused;w.classList.toggle('is-playing',p);play.setAttribute('aria-label',p?'Pauzeren':'Afspelen');}
play.addEventListener('click',toggle);a.addEventListener('play',sync);a.addEventListener('pause',sync);a.addEventListener('ended',sync);
a.addEventListener('timeupdate',upd);a.addEventListener('loadedmetadata',function(){if(isFinite(a.duration)){D=a.duration;tl.max=Math.floor(D);drawTicks();upd();}});
tl.addEventListener('input',function(){a.currentTime=+tl.value;upd();});
w.querySelector('.pch__back').addEventListener('click',function(){a.currentTime=Math.max(0,a.currentTime-15);upd();});
w.querySelector('.pch__fwd').addEventListener('click',function(){a.currentTime=Math.min(D,a.currentTime+30);upd();});
spd.addEventListener('click',function(){ri=(ri+1)%rates.length;a.playbackRate=rates[ri];var l=String(rates[ri]).replace('.',',');spd.textContent=l+'x';spd.setAttribute('aria-label','Afspeelsnelheid '+l+' keer');});
if('mediaSession' in navigator){try{navigator.mediaSession.setActionHandler('seekbackward',function(){a.currentTime=Math.max(0,a.currentTime-15);});navigator.mediaSession.setActionHandler('seekforward',function(){a.currentTime=Math.min(D,a.currentTime+30);});
navigator.mediaSession.setActionHandler('previoustrack',function(){var k=ch(a.currentTime);a.currentTime=C[a.currentTime-C[k][0]>3?k:Math.max(0,k-1)][0];});navigator.mediaSession.setActionHandler('nexttrack',function(){var k=ch(a.currentTime);if(k<C.length-1)a.currentTime=C[k+1][0];});}catch(_){}}
drawTicks();upd();
}
init(document.querySelector('.jouw-container'));
Meer uit componenten
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →