{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "live-video",
  "title": "Default Live Video Skin",
  "description": "A complete live video skin with live-edge, captions, remote playback, feedback, and input controls.",
  "dependencies": [
    "@videojs/react@10.0.0-beta.32",
    "react"
  ],
  "registryDependencies": [
    "@videojs/_button-tooltip",
    "@videojs/_resolve-class-name",
    "@videojs/_style-theme",
    "@videojs/airplay-button",
    "@videojs/buffering-indicator",
    "@videojs/captions-menu",
    "@videojs/cast-button",
    "@videojs/container",
    "@videojs/error-dialog",
    "@videojs/fullscreen-button",
    "@videojs/live-button",
    "@videojs/pip-button",
    "@videojs/play-button",
    "@videojs/poster",
    "@videojs/status-announcer",
    "@videojs/status-indicator",
    "@videojs/volume-indicator",
    "@videojs/volume-popover"
  ],
  "files": [
    {
      "path": "skins/files/live-video/skins/live-video/controls.tsx",
      "content": "/** @jsxImportSource react */\n\nimport { Controls, Tooltip } from '@videojs/react';\n\nimport { cn } from '@/components/videojs/lib/resolve-class-name';\nimport { AirPlayButton } from '@/components/videojs/ui/airplay-button';\nimport { ButtonTooltip } from '@/components/videojs/ui/button-tooltip';\nimport { CaptionsMenu } from '@/components/videojs/ui/captions-menu';\nimport { CastButton } from '@/components/videojs/ui/cast-button';\nimport { FullscreenButton } from '@/components/videojs/ui/fullscreen-button';\nimport { LiveButton } from '@/components/videojs/ui/live-button';\nimport { PiPButton } from '@/components/videojs/ui/pip-button';\nimport { PlayButton } from '@/components/videojs/ui/play-button';\nimport { VolumePopover } from '@/components/videojs/ui/volume-popover';\n\nexport function DefaultLiveVideoControls() {\n  return (\n    <Controls.Root>\n      <Controls.Backdrop\n        className={\n          'pointer-events-none absolute inset-0 z-10 rounded-[inherit] bg-(image:--media-controls-gradient) transition-opacity duration-media-controls ease-out not-data-visible:opacity-0'\n        }\n      />\n      <Controls.Content\n        className={cn(\n          'video-controls',\n          'group/controls text-media-controls-foreground text-shadow-media',\n          'duration-media-controls-half ease-out',\n          'contents p-1 transition-[filter,opacity,scale,translate]',\n          'media-compact:absolute media-compact:inset-x-2 media-compact:bottom-2 media-compact:z-10',\n          'media-compact:flex media-compact:items-center media-compact:rounded-media-controls',\n          'media-compact:bg-media-popover media-compact:text-media-popover-foreground',\n          'media-compact:surface-media media-compact:after:surface-media-inset',\n          'media-wide:inset-x-3 media-wide:bottom-3',\n          'media-compact:not-data-visible:pointer-events-none media-compact:not-data-visible:opacity-0',\n          'media-compact:not-data-visible:scale-media-hidden media-compact:not-data-visible:translate-y-media-hidden-offset',\n          'media-compact:pointer-fine:not-data-visible:blur-media-hidden',\n          'media-compact:not-data-visible:duration-media-controls',\n          'gap-px'\n        )}\n      >\n        <Tooltip.Provider>\n          <Controls.Group\n            className={cn(\n              'absolute inset-x-2 bottom-2 z-10 flex origin-bottom items-center rounded-media-controls p-1',\n              'media-max-compact:bg-media-popover media-max-compact:text-media-popover-foreground',\n              'media-max-compact:surface-media media-max-compact:after:surface-media-inset',\n              'media-compact:contents',\n              'media-max-compact:group-[:not([data-visible])]/controls:pointer-events-none',\n              'media-max-compact:group-[:not([data-visible])]/controls:opacity-0',\n              'media-max-compact:group-[:not([data-visible])]/controls:scale-media-hidden',\n              'media-max-compact:pointer-fine:group-[:not([data-visible])]/controls:blur-media-hidden',\n              'transition-[filter,opacity,scale,translate] duration-media-controls-half ease-out',\n              'media-max-compact:group-[:not([data-visible])]/controls:duration-media-controls',\n              'media-max-compact:group-[:not([data-visible])]/controls:translate-y-media-hidden-offset',\n              'gap-px'\n            )}\n          >\n            <ButtonTooltip side=\"top\">\n              <PlayButton />\n            </ButtonTooltip>\n            <LiveButton />\n            <div aria-hidden=\"true\" className={'flex-1'} />\n            <VolumePopover />\n            <CaptionsMenu className={'media-max-compact:hidden'} />\n            <ButtonTooltip side=\"top\">\n              <CastButton />\n            </ButtonTooltip>\n            <ButtonTooltip side=\"top\">\n              <AirPlayButton />\n            </ButtonTooltip>\n            <ButtonTooltip side=\"top\">\n              <PiPButton />\n            </ButtonTooltip>\n            <ButtonTooltip side=\"top\">\n              <FullscreenButton />\n            </ButtonTooltip>\n          </Controls.Group>\n        </Tooltip.Provider>\n      </Controls.Content>\n    </Controls.Root>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/videojs/skins/live-video/controls.tsx"
    },
    {
      "path": "skins/files/live-video/skins/live-video/gestures.tsx",
      "content": "/** @jsxImportSource react */\n\nimport { Gesture } from '@videojs/react';\n\nexport interface LiveVideoGesturesProps {\n  disabled?: boolean | undefined;\n}\n\nexport function LiveVideoGestures({ disabled = false }: LiveVideoGesturesProps = {}) {\n  return (\n    <>\n      <Gesture disabled={disabled} type=\"tap\" action=\"togglePaused\" pointer=\"mouse\" region=\"center\" />\n      <Gesture disabled={disabled} type=\"tap\" action=\"toggleControls\" pointer=\"touch\" />\n      <Gesture disabled={disabled} type=\"doubletap\" action=\"toggleFullscreen\" region=\"center\" />\n    </>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/videojs/skins/live-video/gestures.tsx"
    },
    {
      "path": "skins/files/live-video/skins/live-video/hotkeys.tsx",
      "content": "/** @jsxImportSource react */\n\nimport { Hotkey } from '@videojs/react';\n\nimport { LivePlaybackHotkeys } from '../shared/live-playback-hotkeys';\n\nexport interface LiveVideoHotkeysProps {\n  disabled?: boolean | undefined;\n}\n\nexport function LiveVideoHotkeys({ disabled = false }: LiveVideoHotkeysProps = {}) {\n  return (\n    <>\n      <LivePlaybackHotkeys disabled={disabled} />\n      <Hotkey disabled={disabled} keys=\"f\" action=\"toggleFullscreen\" />\n      <Hotkey disabled={disabled} keys=\"c\" action=\"toggleSubtitles\" />\n      <Hotkey disabled={disabled} keys=\"i\" action=\"togglePictureInPicture\" />\n    </>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/videojs/skins/live-video/hotkeys.tsx"
    },
    {
      "path": "skins/files/live-video/skins/live-video/skin.tsx",
      "content": "/** @jsxImportSource react */\n\nimport '../../styles/theme.css';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '@/components/videojs/lib/resolve-class-name';\nimport { BufferingIndicator } from '@/components/videojs/ui/buffering-indicator';\nimport { Container } from '@/components/videojs/ui/container';\nimport { ErrorDialog } from '@/components/videojs/ui/error-dialog';\nimport { Poster } from '@/components/videojs/ui/poster';\n\nimport { DefaultLiveVideoControls } from './controls';\nimport { LiveVideoGestures } from './gestures';\nimport { LiveVideoHotkeys } from './hotkeys';\nimport { LiveVideoStatusIndicators } from './status-indicators';\n\nexport interface DefaultLiveVideoSkinProps extends Omit<NonNullable<ComponentProps<typeof Container>>, 'children'> {\n  children?: ReactNode;\n  renderPoster?: NonNullable<ComponentProps<typeof Poster>>['children'];\n}\n\nexport function DefaultLiveVideoSkin({ children, className, renderPoster, ...props }: DefaultLiveVideoSkinProps = {}) {\n  return (\n    <Container\n      className={cn('pointer-fine:not-data-controls-visible:cursor-none', className)}\n      data-theme=\"default\"\n      data-preset=\"live-video\"\n      {...props}\n    >\n      {children}\n      <Poster>{renderPoster}</Poster>\n      <BufferingIndicator />\n      <ErrorDialog />\n      <DefaultLiveVideoControls />\n      <LiveVideoHotkeys />\n      <LiveVideoGestures />\n      <LiveVideoStatusIndicators />\n    </Container>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/videojs/skins/live-video/skin.tsx"
    },
    {
      "path": "skins/files/live-video/skins/live-video/status-indicators.tsx",
      "content": "/** @jsxImportSource react */\n\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '@/components/videojs/lib/resolve-class-name';\nimport { StatusAnnouncer } from '@/components/videojs/ui/status-announcer';\nimport { PlaybackStatusIndicator, StatusIndicator } from '@/components/videojs/ui/status-indicator';\nimport { VolumeIndicator } from '@/components/videojs/ui/volume-indicator';\n\nexport type LiveVideoStatusIndicatorsProps = Omit<ComponentProps<'div'>, 'children'>;\n\nexport function LiveVideoStatusIndicators({ className, ...props }: LiveVideoStatusIndicatorsProps = {}) {\n  return (\n    <>\n      <StatusAnnouncer />\n      <div\n        className={cn(\n          'pointer-events-none absolute inset-0 grid grid-cols-3 items-center justify-items-center text-media-controls-foreground',\n          className\n        )}\n        {...props}\n      >\n        <VolumeIndicator />\n        <StatusIndicator />\n        <PlaybackStatusIndicator />\n      </div>\n    </>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/videojs/skins/live-video/status-indicators.tsx"
    },
    {
      "path": "skins/files/live-video/skins/shared/live-playback-hotkeys.tsx",
      "content": "/** @jsxImportSource react */\n\nimport { Hotkey } from '@videojs/react';\n\nexport interface LivePlaybackHotkeysProps {\n  disabled?: boolean | undefined;\n}\n\nexport function LivePlaybackHotkeys({ disabled = false }: LivePlaybackHotkeysProps = {}) {\n  return (\n    <>\n      <Hotkey disabled={disabled} keys=\"Space\" action=\"togglePaused\" />\n      <Hotkey disabled={disabled} keys=\"k\" action=\"togglePaused\" />\n      <Hotkey disabled={disabled} keys=\"m\" action=\"toggleMuted\" />\n      <Hotkey disabled={disabled} keys=\"ArrowUp\" action=\"volumeStep\" />\n      <Hotkey disabled={disabled} keys=\"ArrowDown\" action=\"volumeStep\" />\n    </>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/videojs/skins/shared/live-playback-hotkeys.tsx"
    }
  ],
  "meta": {
    "framework": "react",
    "style": "tailwind",
    "role": "skin",
    "styling": "tailwind",
    "preset": "live-video",
    "media": "video",
    "theme": "default",
    "public": true
  },
  "docs": "Requires `@videojs/react@10.0.0-beta.32`, which is installed with this item.\n\n```tsx\nimport { HlsJsVideo } from '@videojs/react/media/hlsjs-video';\nimport { LiveVideoPlayer } from '@videojs/react/live-video';\n\nimport { DefaultLiveVideoSkin } from '@/components/videojs/skins/live-video/skin';\n\nexport function Player({ src }: { src: string }) {\n  return (\n    <LiveVideoPlayer>\n      <DefaultLiveVideoSkin className=\"aspect-video w-full\">\n        <HlsJsVideo src={src} />\n      </DefaultLiveVideoSkin>\n    </LiveVideoPlayer>\n  );\n}\n```",
  "categories": [
    "media",
    "skins",
    "live-video"
  ],
  "type": "registry:block"
}