Подводные камни
===============

Данное руководство объясняет некоторые особенности работы библиотеки. Как html5 audio, так и flash являются весьма
нестабильными технологиями и имеют разную поддержку в разных браузерах. Большую часть этих проблем данная библиотека 
решает, но, тем не менее, остаются вещи, которые нельзя решить с помощью js или которые являются неочевидными для разработчиков.

Flash
-----

### Flash и оверлей

Существует по меньшей мере две проблемы с flash, которые невозможно 100% продиагностировать с помощью js:
  - узнать точную версию flash-плеера;
  - узнать, есть ли блокировщик flash в браузере.
  
Узнать точную версию flash нельзя, т.к. некоторые плагины для браузеров выводят совершенно неадекватные номера версий.
Встречались случаи, когда номер версии был 99.999.999 или наоборот 0.0.0. С блокировщиками flash ситуация усложняется -
некоторые блокировщики специально стараются замаскировать свое присутствие, другие не очень корректно
производят блокировку (например, позволяют flash-апплету полностью загрузиться и даже выполнить какой-нибудь код и лишь
после этого блокируют их). Более того, если flash-апплет невидим, то у пользователя нет никакой возможности
узнать о факте блокировки и тем более нет возможности разблокировать его.

Для решения данной проблемы конструктор плеера принимает в качестве необязательного аргумента html-элемент для
отображения оверлея. В этот оверлей помещается прозрачный flash-апплет плеера. Это позволяет в случае необходимости
показать пользователю, что flash-блокировщик сработал некорректно и его нужно отключить. Большая часть блокировщиков позволяет
отменить блокировку простым кликом по данному html-элементу, поэтому плеер прослушивает событие клика. Если после
наступления этого события flash-апплет по-прежнему оказывается недоступен, плеер пытается применить другую технологию воспроизведения или перезагружает апплет.

***ВАЖНО!*** После того как плеер был успешно инициализирован, не нужный более оверлей нельзя просто удалить из DOM дерева.
Также нельзя скрыть его с помощью стиля `display: none`. Это приведет к тому, что плеер перейдет в нерабочее состояние.
Для того чтобы скрыть ненужный оверлей, можно, например, вынести его за пределы страницы следующим css-стилем:

```css
  position: absolute;
  top: -9999px;
  left: -9999px;
```

### Некоторые особенности flash
Во flash-реализации плеера есть несколько особенностей, про которые стоит знать.

 1. flash-апплет является синглтоном. При создании любого количества плееров с внутренним типом flash - апплет
 будет загружен и включен в страницу только один раз. Сам апплет является чем-то вроде фабрики и моста одновременно.
 Он создает во flash окружении экземпляры flash-плееров и коммутирует запросы и события, связанные с этими плеерами.
 У этого решения есть как плюсы, так и минусы:
  Плюсы:
  - существенно меньше потребление памяти при использовании нескольких плееров на странице;
  - при наличии flash-блокеров инициализация требуется всего один раз для любого количества плееров.
  Минус:
  - при крахе апплета "умрут" сразу все плееры, которые используют flash-реализацию (такое пока не наблюдалось, но
 вероятность все же существует).
  
 2. Текущая реализация flash-плеера достаточно проста и потому имеет одно ограничение: нельзя ставить позицию
 воспроизведения дальше загруженной части трека. При установке позиции воспроизведения следует всегда считывать
 возвращаемое значение - оно будет отражать реальную позицию, на которую было установлено воспроизведение (или как
 вариант полагаться только на события обновления позиции воспроизведения).

HTML5
-----

### HTML5 и мобильные браузеры
В мобильных браузерах есть сразу несколько проблем с воспроизведением звука в html5 audio элементе. 

 1. Элементы audio начинают работать и воспроизводить звук, только если команда play была вызвана внутри обработчика
 пользовательского события. Это поведние присутствует также и в большинстве десктопных браузеров. Задачу начальной
 инициализации API берет на себя, прослушивая события keydown, mousedown, и touchstart на объекте body.
 Это требуется выполнить всего лишь один раз, далее можно спокойно пользоваться элементом.
  
 2. Мобильные браузеры работают некорректно, когда на странице присутствует два и более элементов audio:
 
  - Только один элемент может быть активным. Если запустить воспроизведение во втором, то в первом оно остановится.
  - После такого сценария остановки первый элемент "умирает". Повторная попытка запустить воспроизведение в этом
  элементе не даст результатов. От этого помогает только вызов на первом элементе
  метода load.
  - Даже если трек полностью закешировался и ссылка в элементе audio не менялась, повторный вызов метода load
   повторно загрузит трек снуля. Кеширование не применяется.
    
 Данная библиотека решает перечисленные выше проблемы - при запуске воспроизведения трека
 скрипт следит за процессом загрузки и обновления позиции воспроизведения и, если воспроизведение на самом деле не
 начинается, то скрипт перезагружает трек и запускает воспроизведение заново с точки, на которой оно остановилось.
 При отладке работы плеера следует учитывать данное поведение.
  
 3. Некоторые мобильные браузеры запрещают элементу audio изменять громкость. Для того чтобы проверить, есть ли
 возможность программного изменения громкости, сделан метод isDeviceVolume.
  
### Web Audio API
Технология Web Audio API самая новая из всех перечисленных, но самая перспективная. Однако у данной технологии есть ряд недостатков:

 1. Для воспроизведения треков со стороннего домена с помощью Web Audio API требуется, чтобы медиа-файлы приходили
 с правильным заголовком Access-Control-Allow-Origin, иначе Web Audio API не сможет получить доступ к данным трека. При
 этом в разных браузерах это приводит к разным результатам: одни браузеры просто ничего не делают, в других наступает
 тишина. Если планируется динамически подключать Web Audio API во время воспроизведения трека, следует заранее включить
 режим CORS (метод toggleCrossDomain); в противном случае потребуется перезагрузить трек после включения этого режима.
 Более того, в FF 39 обнаружена ошибка, при которой даже перезагрузка трека не обеспечивает корректной
 работы Web Audio API.
 
 ***ВАЖНО!*** - при включенном режиме CORS аудио элемент не сможет загружать
 данные со сторонних доменов, если в ответе не будет правильного заголовка Access-Control-Allow-Origin. Не рекомендуется включать этот
 режим, если не планируется использование Web Audio API.
  
 2. Web Audio API не работает в полной мере в большинстве мобильных браузеров, несмотря на то что удается создать контекст и при создании различных AudioNode
 не возникает никаких ошибок и нормально воспроизводится звук. Поэтому для мобильных браузеров Web Audio API превентивно
 отключен.

 3. Web Audio API может существенно увеличить нагрузку на CPU, в т.ч. вызвать "заикание" звука. Стоит предоставить
 пользователю возможность отключить использование Web Audio API.
