Spotify, Spotify Mini Oynatıcı'yı geliştirmek için Pencere İçinde Pencere API'sini nasıl kullandı?

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

Dünyanın en popüler ses akış abonelik hizmeti olan Spotify, kullanıcıların ses ve video içeriği tüketim şeklini sürekli olarak iyileştirmeyi amaçlar. Geniş bir müzik, podcast ve sesli kitap kitaplığı sunan uygulama, mobil cihazlar, bilgisayarlar ve diğer platformlarda her gün milyonlarca kullanıcıya hizmet veriyor.

Spotify, kısa süre önce masaüstü ve web oynatıcı istemcileri için Spotify Miniplayer'ı kullanıma sundu. Mini oynatıcı, kullanıcılara Spotify'a sürekli erişim sunmak için üstte kalan küçük ve kompakt bir pencerede temel oynatma kontrollerini sunacak şekilde tasarlanmıştır. Uzun zamandır talep edilen bu özellik, kullanıcıların Spotify'da en sevdikleri sanatçıların, şarkı listelerinin ve podcast'lerin keyfini çıkarırken farklı pencere ve uygulamalarda sorunsuz bir şekilde çoklu görev yapmasını sağlar.

Aşağıda, ilk "tuval hilesi"nden yeni Belge Pencere İçinde Pencere API'si üzerine inşa edilen daha gelişmiş ve kullanıcı dostu sürüme kadar mini oynatıcının gelişimi ayrıntılı olarak ele alınmaktadır.

"Tuval hilesi"

Miniplayer'ın ilk iterasyonu, 2019'da Spotify'ın web oynatıcısında hackathon projesi olarak kullanıma sunuldu. Amaç, albüm kapağını her zaman üstte olan bir pencerede görüntülemek için tarayıcının <video > için Pencere İçinde Pencere (PiP) API'sini kullanmaktı. Ancak bu API, öncelikle video öğeleri için tasarlandığından albüm kapağı resimleri gösterilemiyordu. Spotify, albüm kapağını bir kanvas öğesi olarak oluşturarak ve HTMLCanvasElement captureStream() yöntemini kullanarak gerçek zamanlı bir MediaStream nesnesi elde ederek bu sorunun üstesinden geldi. Bu akış daha sonra PiP API için kullanılan videonun kaynağı olarak kullanılır. Bu yaklaşım, Google Chrome'un "Ses Oynatma Listesi" örneğine dayanıyordu.

Spotify, PiP penceresinde hangi oynatıcı kontrollerinin gösterileceğini kontrol etmek için kanvası Media Session API'de ayarlanan uygun işlem işleyicileriyle birleştirdi. Bu sayede kullanıcılar, albüm kapağı ve oynatıcı kontrollerini içeren bir kayan pencereye sahip oldu. Bu pencereyi kullanarak diğer görevlere odaklanırken oynatmayı kontrol edebilirler.

Spotify mini oynatıcının temel penceresinin ekran görüntüsü.

Bu sayede Spotify'da temel bir mini oynatıcı kullanılabiliyordu. Ancak bu yaklaşımın bazı sınırlamaları vardı:

  • Video altyazılar, PiP penceresinde desteklenmez. Spotify'ın tüm videolarda altyazı göstermesi gerektiğinden, video oynatılmaya başlar başlamaz PiP penceresini kapatmak zorunda kalıyordu.
  • Oynatıcı kontrolleri yalnızca oynatma yerel olarak gerçekleşiyorsa görünür. Spotify, Spotify Connect (ve diğer protokoller) kullanılarak uzaktan oynatmaya izin verir ve kullanıcının bu oynatmayı da kontrol edebilmesini ister.
  • PiP penceresinin görünümünü ve tarzını özelleştirme desteği yoktur. Spotify yalnızca posterleri gösterebiliyor ve Chrome tarafından sağlanan oynatıcı kontrollerini kullanabiliyordu. Bu da Spotify markasını veya ek oynatıcı kontrollerini eklemelerini engelliyordu.

Kullanıcı arayüzü üzerinde kontrol sahibi olmamaları ve Spotify'a özgü özellikleri (ör. bir parçayı beğenme) ekleyememeleri, bu yaklaşımın masaüstü istemcileri için uygun olmadığını düşünmelerine neden oldu.

Belgelerde pencere içinde pencere özelliği: Mini oynatıcının gelişimi

2023'ün başlarında Spotify, Google Chrome'un Document Picture-in-Picture API olarak bilinen ve PiP penceresinde rastgele HTML içeriğinin görüntülenmesine olanak tanıyacak yeni bir API'yi kullanıma sunma konusundaki yeni ilgisini öğrendi. Bu gelişme, PiP penceresinin görünümü üzerinde tam kontrol sahibi olmalarını sağladığı için Spotify için heyecan vericiydi. Spotify, Kaynak Deneme sırasında Doküman Resim İçinde Resim API'si üzerine inşa edilmiş yeni bir mini oynatıcı geliştirmek için Chrome ekibiyle birlikte çalıştı.

Document PiP API, öğe ekleyebileceğiniz yeni bir her zaman üstte pencere açmanıza olanak tanır. Spotify Web Oynatıcı bir React web uygulaması olduğundan Spotify, ana uygulamadan PiP penceresine özel bileşenler oluşturmak için ReactDOM'un createPortal() yöntemini kullandı. Böylece mini oynatıcının görünümü ve özellikleri üzerinde tam kontrol sahibi oldu.

Yeni Belge Pencere İçinde Pencere API'si, Spotify'ın önceki sorunlarını da ele aldı:

  • PiP penceresindeki videolar normal video öğeleridir ve altyazılar için tam destek sunar.
  • Kullanıcı arayüzü üzerinde tam kontrol sahibi olarak, Spotify Connect kullanılarak uzaktan oynatma yapılırken bile oynatıcı kontrollerini gösterebilirsiniz.
  • Spotify, kendi görünümünü ve oynatıcı kontrollerini entegre ederek kullanıcı deneyimini iyileştirdi.
  • Spotify, Document PiP API desteğini Spotify'ın masaüstü istemcisine ekleyerek mini oynatıcıyı milyonlarca masaüstü kullanıcısına sunmayı başardı.

Yeni Spotify mini oynatıcı penceresinin ekran görüntüsü.

React kullanarak Pencere İçinde Pencere oluşturma

Aşağıdaki örnekte, Spotify ekibinin yaptığı gibi React'te belgede pencere içinde pencere özelliğini nasıl kullanabileceğiniz gösterilmektedir. MyFeature ve PiPContainer olmak üzere iki React bileşeni oluşturun.

Pencere içinde pencere penceresini yönetmekten MyFeature bileşeni sorumludur. Pencere içinde pencereyi açan ve PiPContainer bileşenini oluşturan bir düğme oluşturur. Ayrıca, pencere kapatıldığında durumu güncellemek için Pencere içinde pencere penceresinin "pagehide" etkinliğine de abone olur.

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 bileşeni, içeriği Pencere İçinde Pencere penceresinde oluşturmak için ReactDOM'un createPortal() yöntemini kullanır.

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

Sırada ne var?

Spotify, yeniliklere ve gelişmelere devam ederken mini oynatıcıyı iyileştirmeye ve özelliklerini ve kullanıcı deneyimini daha da hassaslaştırmaya kararlıdır. Henüz belirli özelliklerle ilgili bir açıklama yapamamakla birlikte, mini oynatıcının gelecekte sunabileceği olasılıklardan heyecan duyuyor.

Spotify mini oynatıcı penceresinin farklı şekillerinin ekran görüntüsü.

Doküman Resim İçinde Resim API'si, daha sezgisel ve kullanıcı dostu bir mini oynatıcı oluşturmak için esneklik ve kontrol sağladı. Diğer tarayıcı tedarikçilerinin bu API'nin sunduğu fırsatları dikkate almasını ve bu API için destek sunmayı düşünmesini umuyoruz. Bu sayede Spotify, kullandıkları tarayıcıdan bağımsız olarak tüm kullanıcılara tutarlı ve gelişmiş bir deneyim sunabilir.

Teşekkür ederiz

Mini oynatıcıyı geliştirme sürecinde yer alan tüm Spotify çalışanlarına teşekkür ederiz.

Spotify, Google Chrome ekibine işbirliği ve Doküman Resim İçinde Resim API'si için Spotify'ın geri bildirimini dikkate aldıkları için teşekkür eder.