Limeplay - Open Source Video Player UI ComponentsLimeplay

Picture-in-Picture Control

Toggle Picture-in-Picture mode for video playback

Installation

npx shadcn add @limeplay/picture-in-picture-control

Add Event & Action Bridge

Import the usePictureInPictureStates hook in your existing PlayerHooks component.

components/limeplay/player-hooks.tsx
"use client"

import React from "react"

import { usePictureInPictureStates } from "@/hooks/limeplay/use-picture-in-picture"
import { usePlaybackStates } from "@/hooks/limeplay/use-playback"
import { usePlayerStates } from "@/hooks/limeplay/use-player"

export const PlayerHooks = React.memo(() => {
  usePlayerStates()
  usePlaybackStates()
  usePictureInPictureStates() 

  return null
})

Add the Store States

lib/create-media-store.ts
import { createPictureInPictureStore, PictureInPictureStore } from "@/hooks/limeplay/use-picture-in-picture"
import { createPlaybackStore, PlaybackStore } from "@/hooks/limeplay/use-playback"

export type TypeMediaStore = PictureInPictureStore &
  PlaybackStore &
  {}

export function createMediaStore(initProps?: Partial<CreateMediaStoreProps>) {
  const mediaStore = create<TypeMediaStore>()((...etc) => ({
    ...createPictureInPictureStore(...etc),
    ...createPlaybackStore(...etc),
    ...initProps,
  }))
  return mediaStore
}

Example Usage

  1. Design the Picture-in-Picture button with icon states.
components/player/picture-in-picture-button.tsx
import { PictureInPictureIcon } from "@phosphor-icons/react"

import { Button } from "@/components/ui/button"
import { useMediaStore } from "@/components/limeplay/media-provider"
import { PictureInPictureControl } from "@/components/limeplay/picture-in-picture-control"

export function PictureInPictureButton() {
  const isPictureInPictureActive = useMediaStore(
    (state) => state.isPictureInPictureActive
  )

  return (
    <PictureInPictureControl asChild shortcut="P">
      <Button variant="ghost" size="icon">
        <PictureInPictureIcon
          weight={isPictureInPictureActive ? "fill" : "regular"}
          size={18}
        />
      </Button>
    </PictureInPictureControl>
  )
}
  1. Use the component in your player.
components/player/bottom-controls.tsx
<PictureInPictureButton />

Understanding

The PictureInPictureControl component uses the usePictureInPicture() hook to toggle Picture-in-Picture mode. You can use the isPictureInPictureActive field from media store to display the current PiP state.

Picture-in-Picture mode allows the video to float in a small window that stays on top of other windows, enabling users to continue watching while working on other tasks. The component automatically detects browser support and disables itself when PiP is unavailable.

Browser Support

PiP API is natively not supported in Firefox. Reference

API Reference

Prop

Type

On this page