Geen geluid meer


#1

Al redelijk veel quizzes gespeeld via deze website en altijd perfect verlopen, maar vandaag liep het mis. Er is geen enkel (achtergrond)geluid meer op de website.

  • Niet via Chrome, niet via Firefox (allebei allerlaatste versie).
  • Alle volumes staan op maximum
  • Systeemgeluiden, geluid in andere games en zo werken wel perfect.
  • Geluid van andere websites (YouTube, sound board websites, enz.), in andere tabs, werken wel goed.
  • De audio instellingen specifiek voor deze website in Chrome staan goed.
  • Als ik de debugger open in Chrome, dan krijg ik in de console wel deze melding een of meerdere keren:
    howler.js:2283 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu
  • Ik voer heel regelmatig Windows Update uit (nieuwe security policy?)

Windows 10.0.17763
Chrome 71.0.3578.98

Zijn er al andere gebruikers die dit gemeld hebben?

UPDATE: Net ook getest op een andere pc met nieuwe en oudere versies van browsers, ook geen geluid. Firefox debug console geeft “De aan decodeAudioData doorgegeven buffer bevat een onbekend inhoudstype.”


#2

De howler.js demo speelt geluid goed af (https://howlerjs.com/#player).

Is het mogelijk dat de geluidsbestanden simpelweg niet meer bestaan of opvraagbaar zijn?
/sounds/correct.* enz.


#3

Gisteren gequized en alles werkte perfect. Internet gewoon over gsm en 4g.


#4

Alles heeft te maken met de recent gewijzigde autoplay policy van vele browsers. Om geluiden te synchroniseren over alle schermen luisteren de aangesloten quizvensters naar een server en spelen ze zelf (m.a.w. autoplay) de geluiden af die op dat moment nodig zijn. De demo van Howler daarentegen valt onder geluiden afspelen nadat een gebruiker op iets klikt.
Ik wacht tot er meer duidelijkheid is, zie:


#5

Waarschijnlijk doordat je de site al een tijdje gebruikt dat je browser kwis.app op de whitelist heeft gezet mbt autoplay. Voor iedere gebruiker zal dit, als ik die nieuwe policy mag geloven, anders zijn.


#6

Inderdaad, ik vreesde al dat het de autoplay policy was. Aangezien ik geen premium tijd meer heb, kan ik volgende workaround niet testen, maar misschien kan jij dat?

  • In Chrome de volgende url bezoeken: chrome://flags/#autoplay-policy
  • Dan bij Autoplay policy kiezen voor No user gesture is required

#7

Kan door de Media Engagement Index (MEI) inderdaad zijn dat sommige gebruikers nog geluid zullen hebben… waarschijnlijk tot ze hun browsergegevens wissen.


#8

Bij mij werkt ie op Chrome als ik dat aanvink. :+1:

Hopelijk komt er zoiets binnenkort waarbij de gebruiker zelf kan kiezen:
2018-08-13-13-27-14-ca343c
Simpel en duidelijk (ipv een vage MEI die voor iedereen anders is)


#9

In de nieuwe quizversie heb ik nu consistent geluid met onderstaande code (Howler.js heb ik verwijderd). Voorlopig zou ik geen geluid op het deelnemersscherm zetten en alles via het quizmastertoestel. Zo kan ik die autoplay policy omzeilen. Bij het klikken op “Start Ronde” roep ik de setup() functie aan om ook op mobiele toestellen geluid te hebben.

// BASED ON: https://github.com/google/emoji-scavenger-hunt

export const AUDIO = {
  CLOCK_END: 'clockEnd',
  CLOCK_TICKING: 'clockTicking',
  CORRECT: 'correct',
  WRONG: 'wrong',
  VICTORY: 'victory',
  DEFEAT: 'defeat',
  CLICK_WET: 'clickWet',
  CLICK_DRY: 'clickDry'
};

export default class AudioPlayer {
  sources;

  constructor() {
    this.sources = {
      [AUDIO.CLOCK_END]: new Audio('/sounds/clock-end.mp3'),
      [AUDIO.CLOCK_TICKING]: new Audio('/sounds/clock.mp3'),
      [AUDIO.CORRECT]: new Audio('/sounds/correct.mp3'),
      [AUDIO.WRONG]: new Audio('/sounds/wrong.mp3'),
      [AUDIO.VICTORY]: new Audio('/sounds/victory.mp3'),
      [AUDIO.DEFEAT]: new Audio('/sounds/defeat.mp3'),
      [AUDIO.CLICK_WET]: new Audio('/sounds/click-wet.mp3'),
      [AUDIO.CLICK_DRY]: new Audio('/sounds/click-dry.mp3')
    };
  }

  /**
   * Cycles audio sources for the game and plays them and immediately pausing
   * them after. This ensures they are ready for play later on during the game
   * lifecycle and can be played from JavaScript functions.
   */
  setup() {
    // We need to start and pause the audio sources when the game is
    // initialized since we can't play audio sources from JS on mobile
    // when not initiated from a user action (like a click event).
    for (const item of Object.keys(this.sources)) {
      this.sources[item].muted = true;
      let playPromise = this.sources[item].play();
      if (playPromise !== undefined) {
        playPromise
          .then(() => {
            this.sources[item].pause();
            this.sources[item].muted = false;
          })
          .catch(error => {
            console.error(error);
          });
      }
    }
  }

  /**
   * Resets all audio sources.
   */
  reset() {
    for (const item of Object.keys(this.sources)) {
      this.pause(item);
    }
  }

  /**
   * Plays a provided audio file.
   * @param audio The audio file to play.
   * @param loop Indicates if the audio file should loop.
   */
  play(audio, volume = 1, loop = false, startTime = 0, endTime) {
    let audioElement = this.sources[audio];
    if (loop) {
      audioElement.loop = true;
    }
    // set volume
    audioElement.volume = volume;
    audioElement.currentTime = startTime;
    let playPromise = audioElement.play();

    if (endTime !== undefined) {
      const timeUpdate = e => {
        if (audioElement.currentTime >= endTime) {
          audioElement.pause();
          audioElement.removeEventListener('timeupdate', timeUpdate);
        }
      };

      audioElement.addEventListener('timeupdate', timeUpdate);
    }

    if (playPromise !== undefined) {
      playPromise.catch(error => {
        console.error(error);
      });
    }
  }

  /**
   * Pauses an audio file.
   * @param audio The audio file to pause.
   */
  pause(audio) {
    this.sources[audio].pause();
    this.sources[audio].currentTime = 0;
  }

  /**
   * Checks if the provided audio file is currently playing.
   * @param audio The audio file to test against.
   * @returns true if the audio is playing, false if not.
   */
  isPlaying(audio) {
    return !this.sources[audio].paused;
  }
}