Hoe Spotify de Picture-in-Picture API gebruikte om de Spotify Miniplayer te bouwen

François Beaufort
François Beaufort

Spotify, 's werelds populairste abonnementsdienst voor audiostreaming, streeft er voortdurend naar de manier te verbeteren waarop gebruikers audio- en video-inhoud consumeren. Het biedt een uitgebreide bibliotheek met muziek, podcasts en audioboeken en bedient dagelijks miljoenen gebruikers op mobiel, pc en andere platforms.

Onlangs heeft Spotify de Spotify Miniplayer uitgebracht voor hun desktop- en webplayer-clients. De Miniplayer is ontworpen om essentiële afspeelbedieningen te bieden in een klein, compact venster dat bovenaan blijft staan, waardoor gebruikers constant toegang hebben tot Spotify. Dit is een lang gevraagde functie en stelt gebruikers in staat naadloos te multitasken in verschillende vensters en apps terwijl ze genieten van hun favoriete artiesten, afspeellijsten en podcasts op Spotify.

Wat volgt is een gedetailleerd overzicht van de ontwikkeling van de Miniplayer, van de eerste "canvashack" tot de meer geavanceerde, gebruiksvriendelijke versie gebouwd op de nieuwe Document Picture-in-Picture API .

De ‘canvashack’

De eerste versie van de Miniplayer werd in 2019 gelanceerd op Spotify's Web Player als een hackproject . Het doel was om de Picture-in-Picture (PiP) API van de browser te gebruiken voor <video> om albumhoezen weer te geven in een venster dat altijd bovenaan staat. Deze API was echter voornamelijk ontworpen voor video-elementen en het was niet mogelijk om albumhoezen te tonen. Spotify omzeilde dit door de albumhoezen om te zetten in een canvaselement en de HTMLCanvasElement captureStream() methode te gebruiken om een ​​real-time MediaStream-object te verkrijgen. Deze stream dient vervolgens als bron voor de video die wordt gebruikt voor de PiP API. Deze aanpak was gebaseerd op het voorbeeld van de "Audio Playlist" van Google Chrome .

Spotify combineerde het canvas met de juiste actiehandlers die in de Media Session API waren ingesteld om te bepalen welke spelerbedieningen in het PiP-venster zouden verschijnen. Dit gaf gebruikers een zwevend venster met albumhoezen en spelerbediening, waarmee ze het afspelen konden regelen terwijl ze zich op andere taken konden concentreren.

Schermafbeelding van het standaard Spotify Miniplayer-venster.

Hierdoor kon Spotify een eenvoudige minispeler hebben. De aanpak had echter verschillende beperkingen:

  • Video-ondertitels worden niet ondersteund in het PiP-venster. Omdat Spotify bij alle video's ondertiteling moest tonen, waren ze genoodzaakt het PiP-venster te sluiten zodra een video begon te spelen.
  • Spelerbedieningen zijn alleen zichtbaar als het afspelen lokaal plaatsvindt. Spotify maakt afspelen op afstand mogelijk via Spotify Connect (en andere protocollen) en wil dat de gebruiker dit afspelen ook kan bedienen
  • Er is geen ondersteuning voor het aanpassen van de look-and-feel van het PiP-venster. Spotify kon alleen illustraties weergeven en de afspeelbedieningen gebruiken die door Chrome worden geleverd, waardoor ze de Spotify-branding of extra afspeelbedieningen niet konden toevoegen.

Het gebrek aan controle over de gebruikersinterface en het onvermogen om hier specifieke Spotify-functies toe te voegen (bijvoorbeeld het leuk vinden van een nummer) zorgden ervoor dat ze vonden dat deze aanpak niet goed paste bij hun desktopclient.

Document Picture-in-Picture: De evolutie van de minispeler

Begin 2023 hoorde Spotify van de hernieuwde interesse van Google Chrome in het lanceren van een nieuwe API waarmee willekeurige HTML-inhoud in het PiP-venster kan worden weergegeven, bekend als de Document Picture-in-Picture API . Deze ontwikkeling was spannend voor Spotify omdat het hen volledige controle zou geven over het uiterlijk van het PiP-venster. Spotify heeft tijdens de Origin-proefperiode samengewerkt met het Chrome-team om een ​​nieuwe minispeler te ontwikkelen die is gebaseerd op de Document Picture-in-Picture API.

Met de Document PiP API kunt u een nieuw Always-on-Top-venster openen waaraan u elementen kunt koppelen. Omdat de Spotify Web Player een React-webapplicatie is, gebruikte Spotify de createPortal() methode van ReactDOM om aangepaste componenten vanuit de hoofdapplicatie in het PiP-venster weer te geven, waardoor volledige controle werd gegeven over het uiterlijk en de functies van de Miniplayer.

De nieuwe Document Picture-in-Picture API loste ook de eerdere problemen van Spotify op:

  • Video's in het PiP-venster zijn gewone video-elementen en bieden volledige ondersteuning voor ondertitels.
  • Met volledige controle over de gebruikersinterface kunnen de bedieningselementen van de speler worden weergegeven, zelfs wanneer het afspelen op afstand plaatsvindt met behulp van Spotify Connect.
  • Spotify kon hun look-and-feel en spelerbediening integreren, waardoor de gebruikerservaring werd verbeterd.
  • Ze waren in staat om ondersteuning voor de Document PiP API naar Spotify's Desktop-client te brengen, waardoor ze de Miniplayer naar miljoenen desktopgebruikers konden brengen.

Screenshot van het nieuwe Spotify Miniplayer-venster.

Maak een Picture-in-Picture-venster met React

Het volgende voorbeeld laat zien hoe u Document Picture-in-Picture in React kunt gebruiken, net als het Spotify-team. U maakt twee React-componenten: MyFeature en PiPContainer .

De MyFeature component is verantwoordelijk voor het beheer van het Picture-in-Picture-venster. Het geeft een knop weer die het Picture-in-Picture-venster schakelt en de PiPContainer component rendert. Het abonneert zich ook op de "pagehide" -gebeurtenis van het Picture-in-Picture-venster om de status bij te werken wanneer het venster wordt gesloten.

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>
    </>
  );
};

De PiPContainer component gebruikt de createPortal()- methode van ReactDOM om inhoud in het Picture-in-Picture-venster weer te geven.

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;
};

Wat is het volgende

Terwijl Spotify zich blijft ontwikkelen en innoveren, blijven ze zich inzetten voor het verbeteren van de minispeler en zijn ze van plan de functies en gebruikerservaring ervan verder te verfijnen. Hoewel ze zich nog niet kunnen binden aan specifieke functies, zijn ze enthousiast over de toekomstige mogelijkheden van de minispeler.

Screenshot van de verschillende vormen van het Spotify Miniplayer-venster.

De Document Picture-in-Picture API heeft de flexibiliteit en controle geboden om een ​​meer intuïtieve en gebruiksvriendelijke minispeler te creëren. De hoop is dat andere browserleveranciers kennis zullen nemen van de mogelijkheden die deze API biedt en zullen overwegen om er ondersteuning voor op te nemen. Hierdoor zou Spotify een consistente en verbeterde ervaring kunnen bieden voor alle gebruikers, ongeacht de door hen gekozen browser.

Dankbetuigingen

Dank aan iedereen bij Spotify die betrokken was bij het bouwen van de minispeler.

Spotify wil ook het Google Chrome-team bedanken voor hun samenwerking en voor het rekening houden met de feedback van Spotify voor de Document Picture-in-Picture API.