Пакет use-sound: звуковые эффекты в React-приложениях

в 9:30, , рубрики: javascript, React, ReactJS, Блог компании RUVDS.com, звук, разработка, Разработка веб-сайтов

Может, дело в том, что я профессионально занимался звуком, но мне хочется, чтобы веб был бы громче.

Знаю, многие меня в этом желании не поддержат. И не без причины! Исторически сложилось так, что звуки в интернете использовались крайне неудачно и некрасиво:

  • В ранние дни веба некоторые страницы проигрывали фоновую MIDI-музыку.
  • Всплывающие мошеннические окна используют звуки для достижения своих нехороших целей. Они, с помощью звуков, стремятся привлечь внимание пользователей и сделать обман более правдоподобным.
  • Звук присутствует и в автоматически запускающихся видео (ну это совсем кошмар).

Правда, я уверен в том, что совсем отказываясь от звука — это как если вместе с водой выплеснуть и ребёнка. Звуки могут делать акценты на действиях пользователя, они способны усиливать обратную связь. Звук может немного скрасить выполнение неких скучных действий. Если звуки на веб-страницах применяют со вкусом, они способны улучшить впечатления пользователя от проекта, сделав его более «осязаемым» и реальным.

Пакет use-sound: звуковые эффекты в React-приложениях - 1

Эта идея не нова: в играх и в мобильных приложениях звуки используются постоянно. На самом деле, веб — это странное исключение из общей тенденции. Большая часть цифровых продуктов, мысли о которых приходят мне в голову, использует звуки. Я уже не говорю о тактильном отклике, который используется в мобильных приложениях для того чтобы приблизить их к реальности.

Мне, в ходе работы над моим блогом, захотелось поэкспериментировать со звуком. Многие элементы интерфейса моего блога, с которыми взаимодействуют пользователи, воспроизводят тихие короткие звуки. Например, в правой верхней части домашней страницы блога имеется пара кнопок для переключения темы и для включения и выключения звука.

Так как звуки в веб используются крайне редко, их применение может оказать большое влияние на восприятие сайта пользователями. Это — нечто вроде секретного оружия разработчика, применение которого способно привести к удивительно большому позитивному влиянию на определённые проекты.

Для того чтобы упростить использование звуков, я оформил применяемый мной для работы со звуками хук в виде самостоятельного npm-пакета use-sound и опубликовал его. Здесь я расскажу о возможностях этого хука и поделюсь советами по использованию звука в веб.

Если вам не терпится увидеть код и приступить к использованию этого хука — вот его GitHub-репозиторий.

Обзор

Пакет use-sound представляет собой React-хук, который помогает разработчикам пользоваться звуковыми эффектами. Вот пример:

import useSound from 'use-sound';
import boopSfx from '../../sounds/boop.mp3';
const BoopButton = () => {
  const [play] = useSound(boopSfx);
  return <button onClick={play}>Boop!</button>;
};

Использование этого хука добавляет примерно 1 Кб к сборке проекта. Правда, он, в асинхронном режиме загружает стороннюю зависимость Howler, размер которой составляет 10 Кб.

Хук даёт разработчику множество приятных возможностей. Среди них хочу отметить следующие:

  • Досрочная остановка проигрывания, а также — приостановка и продолжение воспроизведения.
  • Загрузка чего-то вроде звукового «спрайт-листа» и разделение его на отдельные звуки.
  • Настройка скорости воспроизведения с возможностью ускорять и замедлять воспроизведение звуков.
  • Множество прослушивателей событий.
  • Много дополнительных продвинутых возможностей, доступных благодаря Howler.

Вот документация по хуку, в которой можно найти подробное руководство по его использованию и справочник по API.

Основы работы с use-sound

▍Установка

Сначала надо установить пакет, пользуясь yarn или npm:

# Используем yarn
yarn add use-sound
# или NPM
npm install use-sound

▍Импорт

Пакет use-sound экспортирует единственное значение по умолчанию — это хук useSound. Импортировать его можно так:

import useSound from 'use-sound';

Кроме того, нужно будет импортировать аудиофайлы, которые планируется использовать.

Если вы, при работе над React-проектами, пользуетесь чем-то вроде create-react-app или Gatsby — то у вас должна быть возможность импортировать MP3-файлы так же, как вы импортируете другие ресурсы — вроде изображений:

import boopSfx from '../../sounds/boop.mp3';

Если вы пользуетесь самописной Webpack-конфигурацией, то вам, для обработки .mp3-файлов, понадобится воспользоваться загрузчиком file-loader.

Кроме того, можно работать и со звуковыми файлами, помещёнными в папки public или static. Например, демонстрационные примеры, приведённые в этом материале, используют статические файлы, размещённые в общедоступной папке.

Поиск и подготовка звуков

Установка зависимостей и написание кода — это лишь полдела. Для озвучивания страниц нам понадобится подобрать подходящие звуки.

Мой любимый ресурс, на котором можно искать звуки — это freesound.org. Почти все звуки, используемые в моём блоге, я нашёл именно там. Там имеется множество звуков с лицензией Creative Commons Zero. Для загрузки файлов нужно зарегистрироваться на ресурсе. Пользоваться звуками можно бесплатно.

Будьте готовы к тому, что для подбора подходящего звука вам придётся серьёзно порыться в содержимом freesound.org. Дело тут в том, например, что многие звуки отличаются низким качеством. Процесс поиска подходящего звука можно сравнить с процессом поиска иголки в стоге сена. А подготовка найденного звука к реальному использованию напоминает огранку неогранённого алмаза.

▍Подготовка звуков

Многие звуки, взятые с freesound.org, нуждаются в некоторых улучшениях:

  • Звуки, как и строки, могут быть обрамлены пустым пространством. Фрагменты тишины обычно вырезают, в результате соответствующий звуковой эффект воспроизводится сразу после возникновения озвучиваемого события.
  • При подготовке звуков может понадобиться настроить их громкость, сделав её такой, чтобы все звуки, используемые в одном проекте, имели бы одинаковую громкость.
  • На freesound.org имеются звуки, хранящиеся в различных аудиоформатах. Вам, вполне возможно, понадобится преобразовать понравившиеся вам звуки в MP3.

Для выполнения всех этих правок можно воспользоваться Audacity. Это — бесплатный опенсорсный кросс-платформенный аудиоредактор. Здесь я не буду рассказывать о том, как пользоваться этим редактором, но существует множество замечательных руководств по нему.

Почему я говорю о преобразовании звуков в формат MP3? Дело в том, что раньше не существовало аудио-формата, поддерживаемого всеми браузерами. Поэтому обычным делом было включение в состав проектов MP3, AIFF и WAV-файлов и использование их в окружениях, которые их поддерживают.

В современных же условиях, к счастью для нас, формат MP3 поддерживается всеми основными браузерами, включая IE 9. Звук, хранящийся в формате MP3, кроме того, очень хорошо сжат. А это позволяет выходить на файлы гораздо меньших размеров, чем при использовании альтернативных форматов, кодирующих звук без потери качества.

Звук и доступность

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

Люди, которые имеют проблемы со зрением, используют для работы с веб-страницами средства для чтения с экрана. Причём, речь идёт не только о тех, кто не видит страниц. Средствами для чтения с экрана, например, пользуются люди с дислексией, которым тяжело воспринимать текст, и люди с другими подобными проблемами. Средства для чтения с экрана — это программы, которые разбирают документы и озвучивают тексты. Если некий сайт содержит массу звуковых эффектов, они могут помешать нормальной работе программ, читающих текст с экрана. А это, в свою очередь, помешает работать с сайтом людям, полагающимся на такие программы.

По этой причине важно, чтобы в состав страниц сайта была бы включена кнопка для включения и выключения звука. При этом такая кнопка должна быть доступна для клавиатурной навигации (с использованием клавиши Tab). В идеале, до того момента, когда пользователь доберётся до такой кнопки с использованием клавиши Tab, не должно воспроизводиться никаких звуков. Кроме того, надо, чтобы веб-проект запоминал бы состояние этой кнопки — так пользователю не придётся постоянно прибегать к ней для отключения звука.

С другой стороны, слабослышащие пользователи не будут и знать о том, что некие взаимодействия со страницами сопровождаются звуком. То же относится и к людям, которые работают в интернете с выключенным звуком. По этой причине важно не полагаться исключительно на звук при выполнении неких важных действий. Если звук используется в качестве подтверждения какого-то действия пользователя — сделайте так, чтобы на странице выводилось бы и визуальное подтверждение этого действия. Сайты должны оставаться полностью работоспособными и без звуков.

Рецепты

Взглянем на несколько примеров (в соответствующем разделе оригинала этой статьи с ними можно поэкспериментировать в интерактивном режиме и послушать звуки, издаваемые разными элементами управления).

▍Флажок

Мне страшно нравится этот флажок. Если вы пользуетесь мышью, попробуйте сначала щёлкнуть по нему очень быстро, а потом — так, чтобы между моментами нажатия и отпускания кнопки мыши была бы небольшая пауза.

function Demo() {
  const [isChecked, setIsChecked] = React.useState(
    false
  );

  const [playActive] = useSound(
    '/sounds/pop-down.mp3',
    { volume: 0.25 }
  );
  const [playOn] = useSound(
    '/sounds/pop-up-on.mp3',
    { volume: 0.25 }
  );
  const [playOff] = useSound(
    '/sounds/pop-up-off.mp3',
    { volume: 0.25 }
  );

  return (
    <Checkbox
      name="demo-checkbox"
      checked={isChecked}
      size={24}
      label="I agree to self-isolate"
      onChange={() => setIsChecked(!isChecked)}
      onMouseDown={playActive}
      onMouseUp={() => {
        isChecked ? playOff() : playOn();
      }}
    />
  );
}

▍Досрочное прерывание воспроизведения звука

Иногда нужно, чтобы звук играл бы только тогда, когда пользователь взаимодействует с неким элементом управления. Обратите внимание на то, как в следующем примере сделано так, чтобы звук воспроизводился лишь тогда, когда указатель находится над элементом управления.

function Demo() {
  // Попробуйте, ради интереса, поменять 'rising-pops' на:
  // - fanfare
  // - dun-dun-dun
  // - guitar-loop
  const soundUrl = '/sounds/rising-pops.mp3';

  const [play, { stop }] = useSound(
    soundUrl,
    { volume: 0.5 }
  );

  const [isHovering, setIsHovering] = React.useState(
    false
  );

  return (
    <Button
      onMouseEnter={() => {
        setIsHovering(true);
        play();
      }}
      onMouseLeave={() => {
        setIsHovering(false);
        stop();
      }}
    >
      <ButtonContents isHovering={isHovering}>
        Hover over me!
      </ButtonContents>
    </Button>
  );
}

▍Повышение высоты звука

А вот — пример одного интересного эффекта. Он заключается в том, что звук, воспроизводимый при очередном щелчке по кнопке Like, выше звука, воспроизводимого при предыдущем щелчке по ней:

function Demo() {
  const soundUrl = '/sounds/glug-a.mp3';

  const [playbackRate, setPlaybackRate] = React.useState(0.75);

  const [play] = useSound(soundUrl, {
    playbackRate,
    volume: 0.5,
  });

  const handleClick = () => {
    setPlaybackRate(playbackRate + 0.1);
    play();
  };

  return (
    <Button onClick={handleClick}>
      <span role="img" aria-label="Heart">
      </span>
    </Button>
  );
}

▍Кнопка запуска и приостановки воспроизведения

Вот код реализации кнопки для запуска и приостановки воспроизведения звука, которая поможет вам в разработке нового Spotify:

function Demo() {
  const soundUrl = '/sounds/guitar-loop.mp3';

  const [play, { stop, isPlaying }] = useSound(soundUrl);

  return (
    <PlayButton
      active={isPlaying}
      size={60}
      iconColor="var(--color-background)"
      idleBackgroundColor="var(--color-text)"
      activeBackgroundColor="var(--color-primary)"
      play={play}
      stop={stop}
    />
  );
}

▍Звуковые «спрайт-листы»

Если вы планируете использовать в своём React-компоненте очень много звуков, то может иметь смысл использование звуковых «спрайт-листов». Звуковой «спрайт-лист» — это файл, в котором содержится множество различных звуков. Упаковывая их в один файл, мы повышаем удобство работы с ними и избегаем выполнения множества параллельных HTTP-запросов для загрузки отдельных файлов (хочется надеяться, что когда-нибудь мы сможем пользоваться HTTP/2-мультиплексированием).

Тут мы используем звуковой «спрайт-лист» для создания драм-машины. Поиграть на виртуальных барабанах можно либо с помощью мыши, либо — с помощью клавиш 1-4 на клавиатуре.

function Demo() {
  const soundUrl = '/sounds/909-drums.mp3';

  const [play] = useSound(soundUrl, {
    sprite: {
      kick: [0, 350],
      hihat: [374, 160],
      snare: [666, 290],
      cowbell: [968, 200],
    }
  });

  // Пользовательский хук, прослушивающий событие 'keydown',
  // и вызывающий подходящий обработчик.
  useKeyboardBindings({
    1: () => play({ id: 'kick' }),
    2: () => play({ id: 'hihat' }),
    3: () => play({ id: 'snare' }),
    4: () => play({ id: 'cowbell' }),
  })

  return (
    <>
      <Button
        aria-label="kick"
        onMouseDown={() => play({ id: 'kick' })}
      >
        1
      </Button>
      <Button
        aria-label="hihat"
        onMouseDown={() => play({ id: 'hihat' })}
      >
        2
      </Button>
      <Button
        aria-label="snare"
        onMouseDown={() => play({ id: 'snare' })}
      >
        3
      </Button>
      <Button
        aria-label="cowbell"
        onMouseDown={() => play({ id: 'cowbell' })}
      >
        4
      </Button>
    </>
  );
}

Подробности о применении звуковых «спрайт-листов» в пакете use-sound можно почитать здесь.

Итоги

В сфере использования звуков при разработке веб-сайтов меня больше всего будоражит то, что это — область, которая исследована очень слабо. Я уже довольно давно экспериментирую со звуками, но всё ещё чувствую, что нахожусь лишь в самом начале пути.

Итак, теперь в вашем распоряжении есть инструменты, используя которые вы можете приступить к собственным экспериментам со звуком. Предлагаю вам этим заняться и узнать о том, куда это вас приведёт.

Уважаемые читатели! Как вы относитесь к применению звуков на веб-страницах?

Пакет use-sound: звуковые эффекты в React-приложениях - 2

Автор: ru_vds

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js