wavesurfer.builder.es6.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /**
  2. * @file
  3. * Audiofield build Wavesurfer audio player.
  4. */
  5. (($, Drupal) => {
  6. 'use strict';
  7. Drupal.AudiofieldWavesurfer = {};
  8. /**
  9. * Generate a wavesurfer player.
  10. *
  11. * @param {jQuery} context
  12. * The Drupal context for which we are finding and generating this player.
  13. * @param {array} file
  14. * The audio file for which we are generating a player.
  15. * @param {jQuery} settings
  16. * The Drupal settings for this player..
  17. */
  18. Drupal.AudiofieldWavesurfer.generate = (context, file, settings) => {
  19. $.each($(context).find(`#${file.id}`).once('generate-waveform'), (index, wavecontainer) => {
  20. // Create waveform.
  21. const wavesurfer = WaveSurfer.create({
  22. container: `#${$(wavecontainer).attr('id')} .waveform`,
  23. audioRate: settings.audioRate,
  24. autoCenter: settings.autoCenter,
  25. barGap: settings.barGap,
  26. barHeight: settings.barHeight,
  27. barWidth: settings.barWidth,
  28. cursorColor: settings.cursorColor,
  29. cursorWidth: settings.cursorWidth,
  30. forceDecode: settings.forceDecode,
  31. normalize: settings.normalize,
  32. progressColor: settings.progressColor,
  33. responsive: settings.responsive,
  34. waveColor: settings.waveColor,
  35. });
  36. // Load the file.
  37. wavesurfer.load(file.path);
  38. // Set the default volume.
  39. wavesurfer.setVolume(settings.volume);
  40. // Handle play/pause.
  41. $(wavecontainer).find('.player-button.playpause').on('click', (event) => {
  42. Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
  43. });
  44. // Handle volume change.
  45. $(wavecontainer).find('.volume').on('change', (event) => {
  46. wavesurfer.setVolume(($(event.currentTarget).val() / 10));
  47. });
  48. // Handle autoplay.
  49. if (!!settings.autoplay) {
  50. wavesurfer.on('ready', wavesurfer.play.bind(wavesurfer));
  51. }
  52. });
  53. };
  54. /**
  55. * Generate a wavesurfer playlist player.
  56. *
  57. * @param {jQuery} context
  58. * The Drupal context for which we are finding and generating this player.
  59. * @param {jQuery} settings
  60. * The Drupal settings for this player.
  61. */
  62. Drupal.AudiofieldWavesurfer.generatePlaylist = (context, settings) => {
  63. $.each($(context).find('#wavesurfer_playlist').once('generate-waveform'), (index, wavecontainer) => {
  64. // Create waveform.
  65. const wavesurfer = WaveSurfer.create({
  66. container: `#${$(wavecontainer).attr('id')} .waveform`,
  67. audioRate: settings.audioRate,
  68. autoCenter: settings.autoCenter,
  69. barGap: settings.barGap,
  70. barHeight: settings.barHeight,
  71. barWidth: settings.barWidth,
  72. cursorColor: settings.cursorColor,
  73. cursorWidth: settings.cursorWidth,
  74. forceDecode: settings.forceDecode,
  75. normalize: settings.normalize,
  76. progressColor: settings.progressColor,
  77. responsive: settings.responsive,
  78. waveColor: settings.waveColor,
  79. });
  80. // Set the default volume.
  81. wavesurfer.setVolume(settings.volume);
  82. // Load the first file.
  83. const first = $(wavecontainer).find('.playlist .track').first();
  84. // Get the label and update it with the first filename.
  85. const label = $(wavecontainer).find('label').first();
  86. label.html(`Playing: ${first.html()}`);
  87. // Set the playing class on the first element.
  88. first.addClass('playing');
  89. // Load the file.
  90. wavesurfer.load(first.attr('data-src'));
  91. // Handle play/pause.
  92. $(wavecontainer).find('.player-button.playpause').on('click', (event) => {
  93. Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
  94. });
  95. // Handle next/previous.
  96. $(wavecontainer).find('.player-button.next').on('click', (event) => {
  97. Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
  98. });
  99. $(wavecontainer).find('.player-button.previous').on('click', (event) => {
  100. Drupal.AudiofieldWavesurfer.Previous(wavecontainer, wavesurfer);
  101. });
  102. // Handle clicking track.
  103. $(wavecontainer).find('.playlist .track').on('click', (event) => {
  104. // Check if the track is already playing.
  105. if ($(this).hasClass('playing')) {
  106. // Play/pause the track if it is already loaded.
  107. Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
  108. }
  109. else {
  110. // Load the track.
  111. Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, $(event.currentTarget));
  112. }
  113. });
  114. // Handle volume change.
  115. $(wavecontainer).find('.volume').on('change', (event) => {
  116. wavesurfer.setVolume(($(event.currentTarget).val() / 10));
  117. });
  118. // Handle autoplay.
  119. if (!!settings.autoplay) {
  120. wavesurfer.on('ready', wavesurfer.play.bind(wavesurfer));
  121. }
  122. // Handle track finishing.
  123. wavesurfer.on('finish', (event) => {
  124. Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
  125. });
  126. });
  127. };
  128. /**
  129. * Play or pause the wavesurfer and set appropriate classes.
  130. *
  131. * @param {jQuery} wavecontainer
  132. * The container of the wavesurfer element we are accessing.
  133. * @param {jQuery} wavesurfer
  134. * The wavesurfer player we are accessing.
  135. */
  136. Drupal.AudiofieldWavesurfer.PlayPause = (wavecontainer, wavesurfer) => {
  137. wavesurfer.playPause();
  138. const button = $(wavecontainer).find('.player-button.playpause');
  139. if (wavesurfer.isPlaying()) {
  140. $(wavecontainer).addClass('playing');
  141. button.html('Pause');
  142. }
  143. else {
  144. $(wavecontainer).removeClass('playing');
  145. button.html('Play');
  146. }
  147. };
  148. /**
  149. * Load track on wavesurfer and set appropriate classes.
  150. *
  151. * @param {jQuery} wavecontainer
  152. * The container of the wavesurfer element we are accessing.
  153. * @param {jQuery} wavesurfer
  154. * The wavesurfer player we are accessing.
  155. * @param {jQuery} track
  156. * The track being loaded into the player.
  157. */
  158. Drupal.AudiofieldWavesurfer.Load = (wavecontainer, wavesurfer, track) => {
  159. // Load the track.
  160. wavesurfer.load(track.attr('data-src'));
  161. wavesurfer.on('ready', (event) => {
  162. $(wavecontainer).removeClass('playing');
  163. $(wavecontainer).addClass('playing');
  164. $(wavecontainer).find('.player-button.playpause').html('Pause');
  165. wavesurfer.play();
  166. });
  167. // Remove playing from all other tracks.
  168. $(wavecontainer).find('.track').removeClass('playing');
  169. // Set the class on this track.
  170. track.addClass('playing');
  171. // Show what's playing.
  172. $(wavecontainer).find('label').first().html(`Playing: ${track.html()}`);
  173. };
  174. /**
  175. * Skip track forward on wavesurfer and set appropriate classes.
  176. *
  177. * @param {jQuery} wavecontainer
  178. * The container of the wavesurfer element we are accessing.
  179. * @param {jQuery} wavesurfer
  180. * The wavesurfer player we are accessing.
  181. */
  182. Drupal.AudiofieldWavesurfer.Next = (wavecontainer, wavesurfer) => {
  183. if (wavesurfer.isPlaying()) {
  184. Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
  185. }
  186. // Find the next track.
  187. let track = $(wavecontainer).find('.track.playing').next();
  188. if (typeof track.attr('data-src') === 'undefined') {
  189. track = $(wavecontainer).find('.track').first();
  190. }
  191. // Load the track.
  192. Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, track);
  193. };
  194. /**
  195. * Skip track back on wavesurfer and set appropriate classes.
  196. *
  197. * @param {jQuery} wavecontainer
  198. * The container of the wavesurfer element we are accessing.
  199. * @param {jQuery} wavesurfer
  200. * The wavesurfer player we are accessing.
  201. */
  202. Drupal.AudiofieldWavesurfer.Previous = (wavecontainer, wavesurfer) => {
  203. if (wavesurfer.isPlaying()) {
  204. Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
  205. }
  206. // Find the next track.
  207. let track = $(wavecontainer).find('.track.playing').prev();
  208. if (typeof track.attr('data-src') === 'undefined') {
  209. track = $(wavecontainer).find('.track').last();
  210. }
  211. // Load the track.
  212. Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, track);
  213. };
  214. /**
  215. * Attach the behaviors to generate the audio player.
  216. *
  217. * @type {Drupal~behavior}
  218. *
  219. * @prop {Drupal~behaviorAttach} attach
  220. * Attaches generation of Wavesurfer audio players.
  221. */
  222. Drupal.behaviors.audiofieldwavesurfer = {
  223. attach: (context, settings) => {
  224. $.each(settings.audiofieldwavesurfer, (key, settingEntry) => {
  225. // Default audio player.
  226. if (settingEntry.playertype === 'default') {
  227. // Loop over the files.
  228. $.each(settingEntry.files, (key2, file) => {
  229. Drupal.AudiofieldWavesurfer.generate(context, file, settingEntry);
  230. });
  231. }
  232. else if (settingEntry.playertype === 'playlist') {
  233. Drupal.AudiofieldWavesurfer.generatePlaylist(context, settingEntry);
  234. }
  235. });
  236. },
  237. };
  238. })(jQuery, Drupal);