Compare commits
4 Commits
a3aeb03c64
...
02d84da263
Author | SHA1 | Date | |
---|---|---|---|
02d84da263 | |||
2219b56ee0 | |||
0b86e12689 | |||
af53a973f4 |
19
README.md
19
README.md
@ -2,12 +2,24 @@
|
||||
|
||||
lecteur audio pour l'émission Libre à vous
|
||||
|
||||
## Être débuté
|
||||
servir le dossier local avec le package npm **serve** afin de ne pas avoir de problème de requête CORS,
|
||||
```bash
|
||||
serve .
|
||||
```
|
||||
et ouvrir localhost://5000
|
||||
ou lancer index.html dans un navigateur.
|
||||
|
||||
Attention, il faut créer un objet surfer avec WaveSurfer et appliquer ensuite dessus les actions de play pause et etc, pas directement sur WaveSurver, mais bien ses instances.
|
||||
On peut aussi faire plusieurs instances.
|
||||
|
||||
## liens
|
||||
|
||||
https://github.com/katspaugh/wavesurfer.js
|
||||
|
||||
démo du rendu recherché:
|
||||
https://dev.to/jamland/audio-player-with-wavesurfer-js-react-1g3b
|
||||
https://codesandbox.io/s/audio-player-with-wavesurferjs-react-bd499?from-embed
|
||||
|
||||
marqueurs pour chapitres
|
||||
https://wavesurfer-js.org/plugins/markers.html
|
||||
@ -16,4 +28,9 @@ rendu des vagues en avance côté serveur
|
||||
https://wavesurfer-js.org/faq
|
||||
|
||||
https://521dimensions.com/open-source/amplitudejs/docs/fx/waveforms.html#displaying-waveform-elements
|
||||
https://wavesurfer-js.org
|
||||
https://wavesurfer-js.org
|
||||
|
||||
## génération de wave peaks
|
||||
|
||||
avec audiowaveforms
|
||||
|
||||
|
BIN
audio/demo.wav
Normal file
BIN
audio/demo.wav
Normal file
Binary file not shown.
98
index.html
98
index.html
@ -6,33 +6,83 @@
|
||||
</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<link rel="stylesheet" href="style.css"/>
|
||||
<script src="js/wavesurfer.min.js"></script>
|
||||
<script type="application/javascript" src="js/wavesurfer.js"></script>
|
||||
<script src="js/regions.min.js"></script>
|
||||
<script src="js/markers.min.js"></script>
|
||||
<script type="application/javascript" src="js/main.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1> Example de lecteur audio enrichi</h1>
|
||||
<blockquote>
|
||||
Code de vincent:
|
||||
<figure>
|
||||
<figcaption>Écoute de l'émission intégrale</figcaption>
|
||||
<audio id="player" controls preload="metadata">
|
||||
<source src="https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/20210622/libre-a-vous-20210622.ogg"
|
||||
type="audio/ogg">
|
||||
<source id="audio"
|
||||
src="https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/20210622/libre-a-vous-20210622.mp3"
|
||||
type="audio/mp3">
|
||||
Votre navigateur ne supporte pas l'élément <code>audio</code>
|
||||
</audio>
|
||||
</figure>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<audio src="audio/anitra.mp4" controls></audio>
|
||||
<!-- a div where the div will be placed -->
|
||||
<body onkeyup="silverSurfer.playPause()">
|
||||
<h1> Example de lecteur audio enrichi pour Libre à vous</h1>
|
||||
<section>
|
||||
<h1> Rendu enrichi </h1>
|
||||
|
||||
<div id="waveform"></div>
|
||||
|
||||
<script>
|
||||
const player = new Plyr('#player');
|
||||
</script>
|
||||
<!-- contient les audio peaks sera remplacé par WaveSurfer -->
|
||||
<div id="wave_box">
|
||||
<div id="waveform"></div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
|
||||
<button class="clickable forward" onclick="silverSurfer.skip(-30)">⏩ -30s</button>
|
||||
<button class="clickable play-pause" onclick="silverSurfer.playPause()">⏯️</button>
|
||||
<button class="clickable forward" onclick="silverSurfer.skip(30)">⏩ +30s</button>
|
||||
<button class="clickable forward" onclick="silverSurfer.stop()">stop</button>
|
||||
|
||||
<input type="range" id="volume" name="volume"
|
||||
value="60" onchange="onVolumeChange"
|
||||
min="0" max="100">
|
||||
<label for="volume">Volume</label>
|
||||
</div>
|
||||
<h2>Sections</h2>
|
||||
<ul>
|
||||
<li class="clickable ">
|
||||
intro
|
||||
</li>
|
||||
<li class="clickable " onclick="silverSurfer.play(60)">
|
||||
01:00 chronique A
|
||||
</li>
|
||||
<li class="clickable ">
|
||||
sujet principal
|
||||
</li>
|
||||
<li class="clickable ">
|
||||
pause musicale 1
|
||||
</li>
|
||||
<li class="clickable ">
|
||||
chronique B
|
||||
</li>
|
||||
<li class="clickable ">
|
||||
clotûre
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<audio id="anitra" src="audio/anitra.mp4" controls></audio>
|
||||
</section>
|
||||
<section>
|
||||
|
||||
<blockquote>
|
||||
Code de vincent:
|
||||
<figure>
|
||||
<figcaption>Écoute de l'émission intégrale</figcaption>
|
||||
<audio id="player" controls preload="metadata">
|
||||
<source src="https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/20210622/libre-a-vous-20210622.ogg"
|
||||
type="audio/ogg">
|
||||
<source id="audio"
|
||||
src="https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/20210622/libre-a-vous-20210622.mp3"
|
||||
type="audio/mp3">
|
||||
Votre navigateur ne supporte pas l'élément <code>audio</code>
|
||||
</audio>
|
||||
</figure>
|
||||
</blockquote>
|
||||
<hr>
|
||||
Anitra:
|
||||
<audio id="to_pick" controls preload="metadata">
|
||||
<source src="http://localhost:5000/audio/demo.wav"
|
||||
type="audio/mp4">
|
||||
Votre navigateur ne supporte pas l'élément <code>audio</code>
|
||||
</audio>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
109
js/main.js
Normal file
109
js/main.js
Normal file
@ -0,0 +1,109 @@
|
||||
|
||||
|
||||
let silverSurfer = {}
|
||||
|
||||
const handlePlayPause = () => {
|
||||
silverSurfer.playPause();
|
||||
};
|
||||
|
||||
const onVolumeChange = e => {
|
||||
console.log(e)
|
||||
const {target} = e;
|
||||
const newVolume = +target.value;
|
||||
|
||||
if (newVolume) {
|
||||
setVolume(newVolume);
|
||||
WaveSurfer.current.setVolume(newVolume || 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
console.log('page is fully loaded', WaveSurfer);
|
||||
|
||||
|
||||
const refElement = document.querySelector('#waveform')
|
||||
// const url = '/audio/anitra.mp4'
|
||||
// const url = document.querySelector('#player source').src
|
||||
const url = 'http://localhost:5000/audio/anitra.mp4'
|
||||
// const url = 'https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/20210622/libre-a-vous-20210622.ogg'
|
||||
|
||||
console.log('hello from main.js', refElement)
|
||||
const waveoptions = {
|
||||
// container: refElement,
|
||||
container: document.querySelector('#waveform'),
|
||||
// The color can be either a simple CSS color or a Canvas gradient
|
||||
waveColor: '#ffa492',
|
||||
progressColor: 'hsla(12,100%,43%,0.5)',
|
||||
cursorColor: '#fff',
|
||||
// This parameter makes the waveform look like SoundCloud's player
|
||||
barWidth: 1,
|
||||
barHeight: 10,
|
||||
backend: 'MediaElement',
|
||||
plugins: [
|
||||
// rectangles de zones
|
||||
WaveSurfer.regions.create({
|
||||
regionsMinLength: 2,
|
||||
regions: [
|
||||
{
|
||||
start: 50,
|
||||
end: 70,
|
||||
loop: false,
|
||||
color: 'hsla(400, 100%, 30%, 0.25)'
|
||||
},
|
||||
{
|
||||
start: 150,
|
||||
end: 200,
|
||||
loop: false,
|
||||
color: 'hsla(200, 50%, 70%, 0.25)',
|
||||
minLength: 1
|
||||
}
|
||||
],
|
||||
dragSelection: {
|
||||
slop: 5
|
||||
}
|
||||
}),
|
||||
// marque pages avec texte
|
||||
WaveSurfer.markers.create({
|
||||
markers: [
|
||||
{
|
||||
time: 0,
|
||||
label: "intro",
|
||||
color: '#ff990a'
|
||||
},
|
||||
{
|
||||
time: 10,
|
||||
label: "chronique 1",
|
||||
color: '#ff990a'
|
||||
},
|
||||
{
|
||||
time: 50,
|
||||
label: "une pause musicale",
|
||||
color: '#00ffcc',
|
||||
position: 'top'
|
||||
},
|
||||
{
|
||||
time: 70,
|
||||
label: "le sujet principal",
|
||||
color: '#00ffcc',
|
||||
position: 'top'
|
||||
},
|
||||
{
|
||||
time: 200,
|
||||
label: "la fin",
|
||||
color: '#00ffcc',
|
||||
position: 'top'
|
||||
},
|
||||
]
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
console.log('url', url);
|
||||
silverSurfer = WaveSurfer.create(waveoptions)
|
||||
silverSurfer.load(url)
|
||||
console.log('silverSurfer', silverSurfer);
|
||||
|
||||
});
|
||||
|
7
js/markers.min.js
vendored
Normal file
7
js/markers.min.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* wavesurfer.js markers plugin 5.1.0 (2021-06-20)
|
||||
* https://wavesurfer-js.org
|
||||
* @license BSD-3-Clause
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("WaveSurfer",[],t):"object"==typeof exports?exports.WaveSurfer=t():(e.WaveSurfer=e.WaveSurfer||{},e.WaveSurfer.markers=t())}(this,(function(){return(()=>{"use strict";var e={188:(e,t)=>{function r(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=function(){function e(t,r){var i=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.params=t,this.wavesurfer=r,this.util=r.util,this.style=this.util.style,this.markerWidth=11,this.markerHeight=22,this._onResize=function(){i._updateMarkerPositions()},this._onBackendCreated=function(){i.wrapper=i.wavesurfer.drawer.wrapper,i.params.markers&&i.params.markers.forEach((function(e){return i.add(e)})),window.addEventListener("resize",i._onResize,!0),window.addEventListener("orientationchange",i._onResize,!0),i.wavesurfer.on("zoom",i._onResize)},this.markers=[],this._onReady=function(){i.wrapper=i.wavesurfer.drawer.wrapper,i._updateMarkerPositions()}}var t,i,a;return t=e,a=[{key:"create",value:function(t){return{name:"markers",deferInit:!(!t||!t.deferInit)&&t.deferInit,params:t,staticProps:{addMarker:function(e){return this.initialisedPluginList.markers||this.initPlugin("markers"),this.markers.add(e)},clearMarkers:function(){this.markers&&this.markers.clear()}},instance:e}}}],(i=[{key:"init",value:function(){this.wavesurfer.isReady?(this._onBackendCreated(),this._onReady()):(this.wavesurfer.once("ready",this._onReady),this.wavesurfer.once("backend-created",this._onBackendCreated))}},{key:"destroy",value:function(){this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("backend-created",this._onBackendCreated),this.wavesurfer.un("zoom",this._onResize),window.removeEventListener("resize",this._onResize,!0),window.removeEventListener("orientationchange",this._onResize,!0),this.clear()}},{key:"add",value:function(e){var t={time:e.time,label:e.label,color:e.color||"#D8D8D8",position:e.position||"bottom"};return e.markerElement&&(this.markerWidth=e.markerElement.width,this.markerHeight=e.markerElement.height),t.el=this._createMarkerElement(t,e.markerElement),this.wrapper.appendChild(t.el),this.markers.push(t),this._updateMarkerPositions(),t}},{key:"remove",value:function(e){var t=this.markers[e];t&&(this.wrapper.removeChild(t.el),this.markers.splice(e,1))}},{key:"_createPointerSVG",value:function(e,t){var r="http://www.w3.org/2000/svg",i=document.createElementNS(r,"svg"),a=document.createElementNS(r,"polygon");return i.setAttribute("viewBox","0 0 40 80"),a.setAttribute("id","polygon"),a.setAttribute("stroke","#979797"),a.setAttribute("fill",e),a.setAttribute("points","20 0 40 30 40 80 0 80 0 30"),"top"==t&&a.setAttribute("transform","rotate(180, 20 40)"),i.appendChild(a),this.style(i,{width:this.markerWidth+"px",height:this.markerHeight+"px","min-width":this.markerWidth+"px","margin-right":"5px","z-index":4}),i}},{key:"_createMarkerElement",value:function(e,t){var r=this,i=e.label,a=e.time,n=document.createElement("marker");n.className="wavesurfer-marker",this.style(n,{position:"absolute",height:"100%",display:"flex",overflow:"hidden","flex-direction":"top"==e.position?"column-reverse":"column"});var s=document.createElement("div");this.style(s,{"flex-grow":1,"margin-left":this.markerWidth/2-.5+"px",background:"black",width:"1px",opacity:.1}),n.appendChild(s);var o=document.createElement("div"),u=t||this._createPointerSVG(e.color,e.position);if(o.appendChild(u),i){var d=document.createElement("span");d.innerText=i,this.style(d,{"font-family":"monospace","font-size":"90%"}),o.appendChild(d)}return this.style(o,{display:"flex","align-items":"center",cursor:"pointer"}),n.appendChild(o),o.addEventListener("click",(function(t){t.stopPropagation(),r.wavesurfer.setCurrentTime(a),r.wavesurfer.fireEvent("marker-click",e,t)})),n}},{key:"_updateMarkerPositions",value:function(){for(var e=this.wavesurfer.getDuration(),t=0;t<this.markers.length;t++){var r=this.markers[t],i=this.wavesurfer.drawer.width/this.wavesurfer.params.pixelRatio,a=i*Math.min(r.time/e,1)-this.markerWidth/2;this.style(r.el,{left:a+"px","max-width":i-a+"px"})}}},{key:"clear",value:function(){for(;this.markers.length>0;)this.remove(0)}}])&&r(t.prototype,i),a&&r(t,a),e}();t.default=i,e.exports=t.default}},t={};return function r(i){var a=t[i];if(void 0!==a)return a.exports;var n=t[i]={exports:{}};return e[i](n,n.exports,r),n.exports}(188)})()}));
|
||||
//# sourceMappingURL=wavesurfer.markers.min.js.map
|
7
js/regions.min.js
vendored
Normal file
7
js/regions.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6463
js/wavesurfer.js
Normal file
6463
js/wavesurfer.js
Normal file
File diff suppressed because it is too large
Load Diff
1
js/wavesurfer.js.map
Normal file
1
js/wavesurfer.js.map
Normal file
File diff suppressed because one or more lines are too long
2367
js/wavesurfer.min.js
vendored
Executable file → Normal file
2367
js/wavesurfer.min.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
1
js/wavesurfer.min.js.map
Normal file
1
js/wavesurfer.min.js.map
Normal file
File diff suppressed because one or more lines are too long
46
style.css
46
style.css
@ -1,3 +1,49 @@
|
||||
body{
|
||||
margin: 5em;
|
||||
background: #ccc;
|
||||
}
|
||||
.clickable{
|
||||
cursor:pointer;
|
||||
color: white;
|
||||
}
|
||||
.clickable:hover{
|
||||
background: #222
|
||||
}
|
||||
li.clickable{
|
||||
padding: 1em;
|
||||
}
|
||||
button{
|
||||
padding: 1em;
|
||||
border-radius: 10em;
|
||||
min-width: 2em;
|
||||
min-height: 2em;
|
||||
background: #222;
|
||||
border-width: 0;
|
||||
}
|
||||
#media_player{
|
||||
margin: 2em auto;
|
||||
border: solid 1px grey;
|
||||
padding: 2em;
|
||||
}
|
||||
meter{
|
||||
background: black;
|
||||
}
|
||||
|
||||
audio{
|
||||
width: 100%;
|
||||
}
|
||||
#wave_box{
|
||||
border-radius: 0.25em;
|
||||
background: #222;
|
||||
padding: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
}
|
||||
|
||||
marker span{
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul{
|
||||
background: #111;
|
||||
}
|
Loading…
Reference in New Issue
Block a user