Spotify, самая популярная в мире служба подписки на потоковое аудио, постоянно стремится улучшить способы потребления пользователями аудио- и видеоконтента. Предлагая обширную библиотеку музыки, подкастов и аудиокниг, он ежедневно обслуживает миллионы пользователей на мобильных устройствах, ПК и других платформах.
Недавно Spotify выпустила Spotify Miniplayer для своих клиентов для настольных компьютеров и веб-плееров. Миниплеер предназначен для предоставления основных элементов управления воспроизведением в небольшом компактном окне, которое остается сверху, предоставляя пользователям постоянный доступ к Spotify. Это давно востребованная функция, которая позволяет пользователям беспрепятственно выполнять несколько задач в разных окнах и приложениях, наслаждаясь любимыми исполнителями, плейлистами и подкастами на Spotify.
Далее следует подробный обзор разработки Miniplayer, от начального «хака холста» до более совершенной, удобной для пользователя версии, построенной на новом API Document Picture-in-Picture .
«Холстовый хак»
Первоначальная версия Miniplayer была запущена в 2019 году на Spotify Web Player как хакерский проект . Целью было использовать браузерный API «Картинка в картинке» (PiP) для <video> для отображения обложки альбома в окне, всегда находящемся поверх экрана. Однако этот API в первую очередь был разработан для видеоэлементов, и показывать изображения обложек альбомов было невозможно. Spotify обошёл эту проблему, визуализировав обложку альбома в элементе холста и используя метод HTMLCanvasElement
captureStream()
для получения объекта MediaStream в реальном времени. Затем этот поток служит источником видео, используемого для API PiP. Этот подход был основан на образце «Аудио-плейлиста» Google Chrome .
Spotify объединил холст с соответствующими обработчиками действий, установленными в API сеанса мультимедиа, чтобы контролировать, какие элементы управления проигрывателем будут отображаться в окне PiP. Это дало пользователям плавающее окно с обложками альбомов и элементами управления проигрывателем, которые они могли использовать для управления воспроизведением, одновременно сосредотачиваясь на других задачах.
Это позволило Spotify иметь базовый мини-плеер. Однако этот подход имел ряд ограничений:
- Субтитры видео не поддерживаются в окне PiP. Поскольку Spotify требовалось показывать субтитры на всех видео, они были вынуждены закрыть окно PiP, как только видео начало воспроизводиться.
- Элементы управления проигрывателем видны только в том случае, если воспроизведение происходит локально. Spotify позволяет удаленное воспроизведение с помощью Spotify Connect (и других протоколов) и хочет, чтобы пользователь также мог управлять этим воспроизведением.
- Нет поддержки настройки внешнего вида окна PiP. Spotify мог отображать только изображения и использовать элементы управления проигрывателем, предоставленные Chrome, что не позволяло им добавлять фирменный стиль Spotify или дополнительные элементы управления проигрывателем.
Отсутствие контроля над пользовательским интерфейсом и невозможность добавить сюда определенные функции Spotify (например, лайк трека) означали, что они не считали этот подход подходящим для их настольного клиента.
Документ «Картинка в картинке»: эволюция миниплеера
В начале 2023 года Spotify узнал о возобновлении интереса Google Chrome к запуску нового API, который позволил бы отображать произвольный HTML-контент внутри окна PiP, известный как API Document Picture-in-Picture . Эта разработка была интересна для Spotify, поскольку она давала им полный контроль над внешним видом окна PiP. Spotify сотрудничал с командой Chrome во время пробной версии Origin для разработки нового мини-плеера, основанного на API Document Picture-in-Picture.
API Document PiP позволяет открыть новое окно, которое всегда находится сверху, к которому можно прикреплять элементы. Поскольку веб-плеер Spotify является веб-приложением React, Spotify использовал метод createPortal()
ReactDOM для рендеринга пользовательских компонентов в окно PiP из основного приложения, предоставляя полный контроль над внешним видом и функциями миниплеера.
Новый API Document Picture-in-Picture также решил предыдущие проблемы Spotify:
- Видео внутри окна PiP представляют собой обычные видеоэлементы и полностью поддерживают субтитры.
- Благодаря полному контролю над пользовательским интерфейсом элементы управления проигрывателя могут отображаться даже при удаленном воспроизведении с помощью Spotify Connect.
- Spotify удалось интегрировать их внешний вид и элементы управления проигрывателем, что повысило удобство использования.
- Им удалось обеспечить поддержку Document PiP API в клиенте Spotify для настольных компьютеров, что позволило им предоставить Miniplayer миллионам пользователей настольных компьютеров.
Создайте окно «картинка в картинке» с помощью React
В следующем примере показано, как вы можете использовать документ «Картинка в картинке» в React, как это сделала команда Spotify. Вы создадите два компонента React: MyFeature
и PiPContainer
.
Компонент MyFeature
отвечает за управление окном «Картинка в картинке». Он отображает кнопку, которая переключает окно «Картинка в картинке», и отображает компонент PiPContainer
. Он также подписывается на событие "pagehide"
окна «Картинка в картинке», чтобы обновлять состояние при закрытии окна.
const MyFeature = () => {
const [pipWindow, setPiPWindow] = useState<Window | null>(
documentPictureInPicture.window
);
const handleClick = useCallback(async () => {
if (pipWindow) {
pipWindow.close();
} else {
const newWindow = await documentPictureInPicture.requestWindow();
setPiPWindow(newWindow);
}
}, [pipWindow]);
useEffect(() => {
const handleWindowClose = (): void => {
setPiPWindow(null);
};
pipWindow?.addEventListener("pagehide", handleWindowClose);
return () => {
pipWindow?.removeEventListener("pagehide", handleWindowClose);
};
}, [pipWindow]);
return (
<>
<button onClick={handleClick}>
{pipWindow ? "Close PiP Window" : "Open PiP Window"}
</button>
<PiPContainer pipWindow={pipWindow}>Hello World 👋!</PiPContainer>
</>
);
};
Компонент PiPContainer
использует метод createPortal() ReactDOM для рендеринга контента в окно «картинка в картинке».
type Props = PropsWithChildren<{
pipWindow: Window | null;
}>;
const PiPContainer = ({ pipWindow, children }: Props) => {
useEffect(() => {
if (pipWindow) {
cloneStyles(window.document, pipWindow.document);
}
}, [pipWindow]);
return pipWindow ? createPortal(children, pipWindow.document.body) : null;
};
Что дальше
Поскольку Spotify продолжает развиваться и внедрять инновации, они по-прежнему стремятся совершенствовать Miniplayer и планируют и дальше совершенствовать его функции и удобство использования. Хотя они еще не могут остановиться на конкретных функциях, они с нетерпением ждут будущих возможностей миниплеера.
API Document Picture-in-Picture обеспечивает гибкость и контроль для создания более интуитивно понятного и удобного для пользователя мини-плеера. Мы надеемся, что другие поставщики браузеров обратят внимание на возможности, которые предлагает этот API, и рассмотрят возможность включения его поддержки. Это позволит Spotify предоставлять единообразный и расширенный опыт для всех пользователей, независимо от выбранного ими браузера.
Благодарности
Спасибо всем в Spotify, кто участвовал в создании миниплеера.
Spotify также хотел бы поблагодарить команду Google Chrome за сотрудничество и за то, что они приняли во внимание отзывы Spotify для API Document Picture-in-Picture.