bookmark-audio-fragment/app/audio-player/ contentscript.js
87 lines
2.2 KiB

  1. import * as WaveformPlaylist from 'waveform-playlist';
  2. import delay from 'delay';
  3. import { parseMediaFragmentIdentifier } from '../util/media-fragment-identifier.js';
  4. async function init() {
  5. document.body.innerHTML = `
  6. <main>
  7. <div id="controls">
  8. <button id="playpause">⏯</button>
  9. <div>
  10. <label for="volume" id="volume-label">🔊</label>
  11. <input type="range" min="0" max="100" value="100" id="volume" />
  12. </div>
  13. </div>
  14. <div id="container">
  15. </div>
  16. </main>
  17. `;
  18. const playlist = WaveformPlaylist.init({
  19. container: document.getElementById('container'),
  20. timescale: true,
  21. waveHeight: 100,
  22. state: 'select',
  23. });
  24. const eventEmitter = playlist.getEventEmitter();
  25. // Hook up play/pause and volume inputs
  26. const playpauseEl = document.getElementById('playpause');
  27. const volumeEl = document.getElementById('volume');
  28. playpauseEl.addEventListener('click',
  29. e => eventEmitter.emit(playlist.isPlaying() ? 'pause' : 'play')
  30. );
  31. volumeEl.addEventListener('input',
  32. e => eventEmitter.emit("mastervolumechange", e.target.value)
  33. );
  34. // Load the file
  35. await playlist.load([{
  36. src: document.URL,
  37. }]);
  38. function syncFragmentToSelection() {
  39. // Read target fragment from URL
  40. let start, end;
  41. const fragmentIdentifier = window.location.hash;
  42. if (fragmentIdentifier) {
  43. try {
  44. const parsed = parseMediaFragmentIdentifier(fragmentIdentifier);
  45. start = parsed.start;
  46. end = parsed.end;
  47. } catch (err) {}
  48. }
  49. // Emit event to update selection in player
  50. eventEmitter.emit('select', start, end);
  51. }
  52. // Bind window hash change to update player
  53. window.addEventListener('hashchange', async function() {
  54. if(playlist.isPlaying()) {
  55. eventEmitter.emit('stop')
  56. // pause needs a small delay, coz the lib doesn't
  57. // update player view (drawRequest) when isPlaying() = true.
  58. await delay(10);
  59. }
  60. await syncFragmentToSelection();
  61. eventEmitter.emit('play');
  62. });
  63. // Read start & end from window location.
  64. syncFragmentToSelection();
  65. // Start playing. A tiny delay seems needed in Firefox to show the cursor at the right place.
  66. requestAnimationFrame(() => eventEmitter.emit('play'));
  67. return playlist;
  68. }
  69. init().then(playlist => {
  70. // Store playlist as a shared global variable.
  71. self.playlist = playlist;
  72. });