Compare commits

..

No commits in common. "02d84da26332612a375c2d8f260f41fef8d97d5e" and "a3aeb03c643bf4f893e50375578e8b307ad0d9d3" have entirely different histories.

11 changed files with 30 additions and 9088 deletions

View File

@ -2,24 +2,12 @@
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
@ -28,9 +16,4 @@ 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
## génération de wave peaks
avec audiowaveforms
https://wavesurfer-js.org

Binary file not shown.

View File

@ -6,83 +6,33 @@
</title>
<meta charset="UTF-8"/>
<link rel="stylesheet" href="style.css"/>
<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>
<script src="js/wavesurfer.min.js"></script>
</head>
<body onkeyup="silverSurfer.playPause()">
<h1> Example de lecteur audio enrichi pour Libre à vous</h1>
<section>
<h1> Rendu enrichi </h1>
<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 -->
<div id="waveform"></div>
<!-- contient les audio peaks sera remplacé par WaveSurfer -->
<div id="wave_box">
<div id="waveform"></div>
</div>
<script>
const player = new Plyr('#player');
</script>
<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>

View File

@ -1,109 +0,0 @@
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
View File

@ -1,7 +0,0 @@
/*!
* 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

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

2367
js/wavesurfer.min.js vendored Normal file → Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,49 +1,3 @@
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;
}