Spotify가 Picture-in-Picture API를 사용하여 Spotify 소형 플레이어를 빌드한 방법

Guido Kessels
Guido Kessels
François Beaufort
François Beaufort

전 세계에서 가장 인기 있는 오디오 스트리밍 구독 서비스인 Spotify는 사용자가 오디오 및 동영상 콘텐츠를 소비하는 방식을 지속적으로 개선하고 있습니다. 광범위한 음악, 팟캐스트, 오디오북 라이브러리를 제공하며 모바일, PC, 기타 플랫폼에서 매일 수백만 명의 사용자를 지원합니다.

최근 Spotify는 데스크톱 및 웹 플레이어 클라이언트를 위한 Spotify 미니 플레이어를 출시했습니다. 미니 플레이어는 상단에 고정되어 있는 작고 컴팩트한 창에 필수 재생 컨트롤을 제공하여 사용자가 Spotify에 지속적으로 액세스할 수 있도록 설계되었습니다. 오랫동안 요청되어 왔던 이 기능을 통해 사용자는 Spotify에서 좋아하는 아티스트, 재생목록, 팟캐스트를 즐기면서 여러 창과 앱에서 원활하게 멀티태스킹할 수 있습니다.

다음은 초기 '캔버스 해킹'부터 새로운 Document Picture-in-Picture API를 기반으로 하는 더 고급의 사용자 친화적인 버전까지 미니플레이어 개발에 관한 자세한 내용입니다.

'캔버스 해킹'

미니플레이어의 초기 버전은 2019년 Spotify 웹 플레이어에서 해킹 프로젝트로 출시되었습니다. 목표는 브라우저의 <video>용 PIP (Picture-in-Picture) API를 사용하여 상시 표시 창에 앨범 아트를 표시하는 것이었습니다. 그러나 이 API는 주로 동영상 요소용으로 설계되었으며 앨범 아트 이미지를 표시할 수 없었습니다. Spotify는 앨범 아트를 캔버스 요소로 렌더링하고 HTMLCanvasElement captureStream() 메서드를 사용하여 실시간 MediaStream 객체를 가져와 이 문제를 해결했습니다. 이 스트림은 PiP API에 사용되는 동영상의 소스로 사용됩니다. 이 접근 방식은 Google Chrome의 '오디오 재생목록' 샘플을 기반으로 합니다.

Spotify는 캔버스를 Media Session API에 설정된 적절한 작업 핸들러와 결합하여 PIP 창에 표시할 플레이어 컨트롤을 제어했습니다. 이렇게 하면 사용자에게 앨범 아트와 플레이어 컨트롤이 포함된 플로팅 창이 표시되어 다른 작업에 집중하면서 재생을 제어할 수 있습니다.

기본 Spotify 미니플레이어 창의 스크린샷

이를 통해 Spotify는 기본 미니 플레이어를 사용할 수 있게 되었습니다. 그러나 이 접근 방식에는 몇 가지 제한사항이 있습니다.

  • PiP 창 내에서는 동영상 자막이 지원되지 않습니다. Spotify는 모든 동영상에 자막을 표시해야 하므로 동영상 재생이 시작되는 즉시 PiP 창을 닫아야 했습니다.
  • 플레이어 컨트롤은 로컬에서 재생이 진행 중인 경우에만 표시됩니다. Spotify는 Spotify Connect (및 기타 프로토콜)를 사용하여 원격 재생을 허용하며 사용자가 이 재생도 제어할 수 있기를 바랍니다.
  • PiP 창의 모양과 느낌을 맞춤설정하는 기능은 지원되지 않습니다. Spotify는 아트워크를 표시하고 Chrome에서 제공하는 플레이어 컨트롤만 사용할 수 있었기 때문에 Spotify 브랜딩이나 추가 플레이어 컨트롤을 추가할 수 없었습니다.

사용자 인터페이스를 제어할 수 없고 Spotify 전용 기능 (예: 트랙에 좋아요 표시)을 추가할 수 없으므로 이 접근 방식이 데스크톱 클라이언트에 적합하지 않다고 판단했습니다.

문서 PIP 모드: 소형 플레이어의 진화

2023년 초, Spotify는 Google Chrome에서 Document Picture-in-Picture API라고 하는 PiP 창 내에 임의의 HTML 콘텐츠를 표시할 수 있는 새로운 API를 출시하는 데 다시 관심을 갖고 있다는 사실을 알게 되었습니다. 이 개발은 Spotify에 매우 반가운 소식이었습니다. PiP 창의 모양을 완전히 제어할 수 있게 되었기 때문입니다. Spotify는 시작 단계 체험판 기간 동안 Chrome팀과 협력하여 Document Picture-in-Picture API를 기반으로 하는 새로운 미니플레이어를 개발했습니다.

Document PiP API를 사용하면 요소를 연결할 수 있는 새로운 상시 사용 설정 창을 열 수 있습니다. Spotify 웹 플레이어는 React 웹 애플리케이션이므로 Spotify는 ReactDOM의 createPortal() 메서드를 사용하여 기본 애플리케이션에서 PiP 창에 맞춤 구성요소를 렌더링하여 미니 플레이어의 모양과 기능을 완전히 제어할 수 있었습니다.

새로운 Document Picture-in-Picture API는 Spotify의 이전 문제를 해결했습니다.

  • PIP 창 내의 동영상은 일반 동영상 요소이며 자막을 완벽하게 지원합니다.
  • UI를 완전히 제어할 수 있으므로 Spotify Connect를 사용하여 원격으로 재생 중일 때도 플레이어 컨트롤을 표시할 수 있습니다.
  • Spotify는 디자인과 플레이어 컨트롤을 통합하여 사용자 환경을 개선할 수 있었습니다.
  • Document PiP API 지원을 Spotify의 데스크톱 클라이언트에 제공하여 수백만 명의 데스크톱 사용자에게 미니 플레이어를 제공할 수 있었습니다.

새로운 Spotify 미니플레이어 창의 스크린샷

React를 사용하여 PIP 모드 창 만들기

다음 예는 Spotify팀과 마찬가지로 React에서 문서 PIP를 사용하는 방법을 보여줍니다. MyFeaturePiPContainer라는 두 개의 React 구성요소를 만듭니다.

MyFeature 구성요소는 PIP 모드 창을 관리합니다. PIP 모드 창을 전환하고 PiPContainer 구성요소를 렌더링하는 버튼을 렌더링합니다. 또한 PIP 모드 창의 "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 구성요소는 ReactDOM의 createPortal() 메서드를 사용하여 콘텐츠를 PIP 창에 렌더링합니다.

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는 지속적으로 발전하고 혁신하면서 미니플레이어를 개선하기 위해 노력하고 있으며, 기능과 사용자 환경을 더욱 개선할 계획입니다. 아직 구체적인 기능을 약속할 수는 없지만 향후 미니플레이어의 가능성에 기대를 모으고 있습니다.

다양한 모양의 Spotify 미니플레이어 창 스크린샷

Document Picture-in-Picture API는 더 직관적이고 사용자 친화적인 미니플레이어를 만들 수 있는 유연성과 제어 기능을 제공했습니다. 다른 브라우저 공급업체가 이 API가 제공하는 기회를 인지하고 지원을 통합하는 것을 고려하기를 바랍니다. 이를 통해 Spotify는 사용자가 선택한 브라우저와 관계없이 모든 사용자에게 일관되고 향상된 환경을 제공할 수 있습니다.

감사의 말씀

미니 플레이어를 만드는 데 참여한 모든 Spotify 직원에게 감사드립니다.

또한 Spotify는 Document Picture-in-Picture API에 관한 Spotify의 의견을 고려하고 협력해 주신 Google Chrome팀에 감사드립니다.