Приостановить все, кроме щелкнувшего игрока (waversurfer + Drupal) - PullRequest
0 голосов
/ 30 октября 2019

[РЕДАКТИРОВАТЬ: Я сам FITFO, LOL - см. Ответ, который я написал здесь]

Хорошо, так что я схожу с ума от этого в течение нескольких недель ...

У меня есть несколько случаевИгрок Wavesurfer на моем сайте Drupal. Когда я нажимаю «play» на одном, я хочу, чтобы все остальные воспроизводящиеся в данный момент экземпляры Wavesurfer делали паузу.

Я перепробовал все, что смог найти, но не могу заставить его работать.

Вот как Drupal реализует Wavesurfer:

(function ($, Drupal) {
  'use strict';

  Drupal.AudiofieldWavesurfer = {};

  Drupal.AudiofieldWavesurfer.generate = function (context, file, settings) {
    $.each($(context).find('#' + file.id).once('generate-waveform'), function (index, wavecontainer) {
      var wavesurfer = WaveSurfer.create({
        container: '#' + $(wavecontainer).attr('id') + ' .waveform',
        audioRate: settings.audioRate,
        autoCenter: settings.autoCenter,
        barGap: settings.barGap,
        barHeight: settings.barHeight,
        barWidth: settings.barWidth,
        cursorColor: settings.cursorColor,
        cursorWidth: settings.cursorWidth,
        forceDecode: settings.forceDecode,
        normalize: settings.normalize,
        progressColor: settings.progressColor,
        responsive: settings.responsive,
        waveColor: settings.waveColor
      });

      wavesurfer.load(file.path);

      wavesurfer.setVolume(1);

      $(wavecontainer).find('.player-button.playpause').on('click', function (event) {
        Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
      });

      $(wavecontainer).find('.volume').on('change', function (event) {
        wavesurfer.setVolume($(event.currentTarget).val() / 10);
      });

      if (!!settings.autoplay) {
        wavesurfer.on('ready', wavesurfer.play.bind(wavesurfer));
      }
    });
  };


  Drupal.AudiofieldWavesurfer.PlayPause = function (wavecontainer, wavesurfer) {
        wavesurfer.playPause();
        var button = $(wavecontainer).find('.player-button.playpause');
        if (wavesurfer.isPlaying()) {
          $(wavecontainer).addClass('playing');
          button.html('<i class="fas fa-pause-circle fa-2x"></i>');
        } else {
          $(wavecontainer).removeClass('playing');
          button.html('<i class="fas fa-play-circle fa-2x"></i>');
        }
      };

И вот как я сейчас пытаюсь приостановить все остальные:

document.addEventListener('playPause', function(e){
    var audios = document.getElementsByClassName('audiofield-wavesurfer');
    for(var i = 0, len = audios.length; i < len; i++){
        if(audios[i] != e.target && audios[i].hasClass('playing')){
            audios[i].playPause();
        }
    }
}, true);

Кажется, это не сработает (читалв Drupal.behaviours и попытался изменить эту часть, тоже не повезло.

Я также попытался просто позволить функции PlayPause запускаться через каждого игрока при нажатии следующим образом:

  Drupal.AudiofieldWavesurfer.PlayPause = function (wavecontainer, wavesurfer) {
    $.each($(Drupal.AudiofieldWavesurfer), function() {
        wavesurfer.playPause();
        var button = $(wavecontainer).find('.player-button.playpause');
        if (wavesurfer.isPlaying()) {
          $(wavecontainer).addClass('playing');
          button.html('<i class="fas fa-pause-circle fa-2x"></i>');
        } else {
          $(wavecontainer).removeClass('playing');
          button.html('<i class="fas fa-play-circle fa-2x"></i>');
        }
      })};

… или здесь:

  Drupal.AudiofieldWavesurfer.generate = function (context, file, settings) {
    $.each($(context).find('#' + file.id).once('generate-waveform'), function (index, wavecontainer) {
      var wavesurfer = WaveSurfer.create({
        container: '#' + $(wavecontainer).attr('id') + ' .waveform',
        audioRate: settings.audioRate,
        autoCenter: settings.autoCenter,
        barGap: settings.barGap,
        barHeight: settings.barHeight,
        barWidth: settings.barWidth,
        cursorColor: settings.cursorColor,
        cursorWidth: settings.cursorWidth,
        forceDecode: settings.forceDecode,
        normalize: settings.normalize,
        progressColor: settings.progressColor,
        responsive: settings.responsive,
        waveColor: settings.waveColor
      });

      wavesurfer.load(file.path);

      wavesurfer.setVolume(1);

      // ---- HERE MY CODE: --------

      $(wavecontainer).find('.player-button.playpause').on('click', function (event) {
        $.each($(context).find('#' + file.id), function(idx, obj) {
            $(obj).stop();
        });
        Drupal.AudiofieldWavesurfer.PlayPause($(wavecontainer), wavesurfer);
      });

но все, что не сработало и для меня ... кто-нибудь знает, как помочь мне разобраться в этом? Спасет мою жизнь !!!

1 Ответ

0 голосов
/ 04 ноября 2019

Я ЭТО СДЕЛАЛ! Я НАСТОЯЩИЙ ФРЭКИНГ СДЕЛАЛ ЭТО! WOOHOO !!

Посмотрите и проверьте сами: https://www.ohmniphonic.com/#srvcs

Итак, для всех, кто пытается использовать FITFO:

После нескольких недель прочесывания в интернете,ищу патчи, учебные пособия или даже просто подсказки, как заставить playPause приостанавливать все, кроме волнового переключателя в Drupal (= со строгим режимом, jQuery, объектными классами, сложными областями видимости / замыканиями,…), я почти сдался - но на самом деле копал глубокоизучая все новые стандарты кодирования JS / Drupal / etc и экспериментируя с devtools / console / etc, мне удалось заставить его работать. Вот мой код:

JS:

// array to store wavesurfers, defined outside function for scope,
const audios = [];

// Start of regular Drupal/wavesurfer function
(function ($, Drupal) {
  'use strict';
  Drupal.AudiofieldWavesurfer = {};
  Drupal.AudiofieldWavesurfer.generate = function (context, file, settings) {
    $.each($(context).find('#' + file.id).once('generate-waveform'), function (index, wavecontainer) {
      var wavesurfer = WaveSurfer.create({
        container: '#' + $(wavecontainer).attr('id') + ' .waveform',
        // params
      });

      // […]
      // closure to better access play buttons outside function
      wavesurfer.button = function(wc) {
          return $(wc).find('.player-button.playpause');
      }(wavecontainer);

      // used button-closure for this
      $(wavesurfer.button).on('click', function (event) {
            Drupal.AudiofieldWavesurfer.PlayPause($(wavecontainer), wavesurfer);
      });

      // […]
      // add wavesurfer to array.
      audios.push(wavesurfer);
    });
  };

// Custom playPause function
  Drupal.AudiofieldWavesurfer.PlayPause = function (wavecontainer, wavesurfer) {

    // Loop through waveurfers and update classes
    audios.forEach(function(obj) {
        // if it's the audio from the play button
          wavesurfer.playPause();
          if (wavesurfer.isPlaying()) {
            $(wavesurfer.button).html('<i class="fas fa-pause-circle"></i>');
          } else {
            $(wavesurfer.button).html('<i class="fas fa-play-circle"></i>');
          }
        } else {
            if (obj.isPlaying()) {
                $(obj.button).html('<i class="fas fa-play-circle"></i>');
                obj.pause();
            }
        }
    });
  };

// […]
})(jQuery, Drupal);

CSS:

.blazy > .grid {
    display: inline-block;
    margin: 0;
    padding: 0;
    width: -webkit-fill-available;
}

.playbtn-container {
    position: relative;
    -webkit-backface-visibility: hidden;
}

.player-button {
    font-size: 7em !important;
    height: 98px;
    position: absolute;
    display: block !important;
    z-index: 2;
    margin-top: -30px;
    margin-left: 0;
    color: #f71735;
    background: white;
    background: rgba(255,255,255,0.4);
    border-radius: 100%;
    -webkit-transition: all 0.1s ease  0s;
    -moz-transition: all 0.1s ease  0s;
    -ms-transition: all 0.1s ease  0s;
    -o-transition: all 0.1s ease  0s;
    -apple-transition: all 0.1s ease  0s;
    transition: all 0.1s ease  0s;
}

.player-button:hover {
    font-size: 8em !important;
    height: 112px;
    margin-top: -35px;
    margin-left: -5px;
    -webkit-transition: all 0.1s ease  0s;
    -moz-transition: all 0.1s ease  0s;
    -ms-transition: all 0.1s ease  0s;
    -o-transition: all 0.1s ease  0s;
    -apple-transition: all 0.1s ease  0s;
    transition: all 0.1s ease  0s;
}

HTML (хранится как шаблон TWIG в Drupa)):

<div class="audiofield">
  {% for file in files %}
    <div class="audiofield-wavesurfer" id="wavesurfer_{{ file.id }}">
      <div id="audiofield-audio-player-{{ file.id }}" class="waveform"></div>
      <div class="playbtn-container">
          <div class="player-button playpause play">
              <i class="fas fa-play-circle fa-2x"></i>
          </div>
      </div>
    </div>
  {% endfor %}
</div>

Итак, короче говоря, лучший подход, кажется, хранить каждый волновой серфер в массиве и затем циклически проходить по этому массиву для playPause - то, что также было предложено в webz, но не работало так же для этого контекста (каламбур, лель)…

Adter больше ничего не работал, и я уже узнал о новых переменных областях и тому подобном, я разработал идею массива с нуля, используя сегодняшние обходные пути, приемы и рекомендуемые методы. Наиболее важно:

  1. определение массива вне функции Drupal, чтобы он был общедоступным
  2. , создание замыкания для wavesurfer.button, так что он становится публичным свойством

Так как я также добавил некоторые другие приятные функции и FX, мне также пришлось сделать немного больше, но для простоты (для тех, у кого есть похожие проблемы) я сократил код до важного.

Если у вас естьлюбые вопросы или отзывы: fireAway! ;)

...