Video player
Um player de vídeo com barra de busca arrastável, controles que se ocultam sozinhos, atalhos de teclado, velocidade, picture in picture e tela cheia.
pnpm dlx shadcn@latest add https://hextaui.com/r/video-player.jsonAdiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.
Adicione os tokens de tema ao seu CSS global, se ainda não o fez.
Instale as dependências.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnCopie e cole o código a seguir no seu projeto.
components/ui/video-player.tsx components/ui/button.tsx components/ui/dropdown-menu.tsx components/ui/kbd.tsx components/ui/spinner.tsx components/ui/tooltip.tsx Atualize os caminhos de importação para corresponder à configuração do seu projeto.
Barra
variant="bar" coloca os controles sob a imagem, na superfície da página. Eles nunca ocultam nem cobrem o vídeo.
Mínimo
Use apenas as partes de que precisa. tooltips={false} desativa as dicas de hover, e type="remaining" conta regressivamente em vez de progressivamente.
Deslocamentos de busca e velocidades
offset define quanto cada botão de busca salta, e rates define as velocidades do menu.
Atalhos na página inteira
Os atalhos funcionam enquanto o foco está dentro do player. globalShortcuts também escuta na página, mas nunca enquanto você digita em um campo, usa um botão ou tem um menu ou dialog aberto. Use para um player por página.
Legendas
Adicione um <track> e VideoPlayerCaptionsButton. As legendas são desenhadas pelo player, então sobem enquanto os controles aparecem em vez de ficarem escondidas atrás deles. Uma faixa de outra origem precisa de crossOrigin no vídeo.
Controles personalizados
useVideoPlayer lê estado e ações de qualquer componente dentro do player. Selecione apenas o que usa, para o componente renderizar de novo somente quando esse valor mudar.
Erro
Quando a fonte falha, o player mostra errorMessage, anuncia e desabilita os controles que não podem funcionar.
Da direita para a esquerda
Os rótulos seguem o idioma da página. A linha do tempo e os controles de reprodução permanecem da esquerda para a direita, como nos players de mídia das plataformas.
Funcionam enquanto o foco está em qualquer lugar dentro do player, ou na página com globalShortcuts. São ignorados enquanto uma tecla modificadora está segurada ou o foco está em um campo de texto.
| Tecla | Ação |
|---|---|
| SpaceK | Reproduz ou pausa. |
| J | Volta 10 segundos. |
| L | Avança 10 segundos. |
| ←→ | Volta ou avança 5 segundos. Na barra de busca, Shift salta 10. |
| ↑↓ | Aumenta ou diminui o volume em 5%. |
| M | Silencia ou reativa o som. |
| C | Liga ou desliga as legendas, quando o vídeo as tem. |
| F | Entra ou sai da tela cheia. |
| I | Abre ou fecha o picture in picture, onde houver suporte. |
| Shift+.Shift+, | Acelera ou desacelera a reprodução. |
| 0–9 | Salta de 0% a 90% do vídeo. |
| HomeEnd | Salta para o início ou o fim. |
- O player é uma região rotulada. Todo botão tem um nome que acompanha seu estado (Play, Pause, Replay) e um tooltip com seu atalho.
- A barra de busca e o volume são sliders. A barra de busca lê seu valor como “1 minute 5 seconds of 3 minutes”.
- Ações de atalhos e cliques no vídeo são anunciadas de forma educada, por exemplo “Paused” ou “Volume 40%”. Erros de carregamento são anunciados como um alerta.
- Na variante overlay, os controles somem com fade após 2,5 segundos de reprodução sem movimento do ponteiro. Permanecem visíveis enquanto pausado, enquanto você passa o mouse ou os usa com o teclado, e enquanto um menu está aberto.
- Em telas touch, um toque mostra ou oculta os controles e um toque duplo no terço esquerdo ou direito volta ou avança 10 segundos. Continue tocando para somar 10 segundos a cada vez.
- O botão de legendas é um toggle com
aria-pressed. Ele escolhe a última faixa que você usou, depois uma no idioma do navegador, depois a primeira. - Com movimento reduzido, controles e feedback aparecem com fade, sem mover nem escalar.
A barra de busca e o volume são construídos sobre o slider do Base UI, e os botões sobre Button, Tooltip e Dropdown menu do HextaUI.
| Prop | Tipo | Padrão |
|---|---|---|
variantoverlay faz controles de ocultação automática flutuarem sobre o vídeo. bar os coloca abaixo dele. | "overlay" | "bar" | "overlay" |
shortcutsAtalhos de teclado enquanto o foco está no player. | boolean | true |
globalShortcutsEscute também os atalhos na página inteira. | boolean | false |
errorMessage | ReactNode | "This video can’t be played." |
| Atributo | Descrição |
|---|---|
data-slot="video-player" | Selecione a raiz no CSS. |
data-variant | A variante atual. |
data-controls | "visible" ou "hidden". O cursor se oculta junto com os controles. |
data-fullscreen | Presente enquanto o player está em tela cheia. |
aria-busy | Definido enquanto a reprodução espera por dados. |
O elemento <video>. Aceita todos os atributos de vídeo e filhos <source> ou <track>. Um clique reproduz ou pausa, um clique duplo alterna a tela cheia, um toque mostra ou oculta os controles e um toque duplo em qualquer lado faz a busca.
| Prop | Tipo | Padrão |
|---|---|---|
autoPlayInicia a reprodução na montagem, exceto com movimento reduzido. | boolean | false |
playsInline | boolean | true |
preload | "none" | "metadata" | "auto" | "metadata" |
doubleTapSeekSegundos que um toque duplo em qualquer lado salta em telas touch. false desativa. | number | false | 10 |
renderTroque por outro elemento de mídia, como um elemento de vídeo HLS. | ReactElement | (props, state) => ReactElement | <video> |
| Atributo | Descrição |
|---|---|
data-slot="video-player-content" | Seleciona o vídeo no CSS. |
| Prop | Tipo | Padrão |
|---|---|---|
tooltipsMostra o rótulo e o atalho de cada controle no hover. | boolean | true |
| Atributo | Descrição |
|---|---|
data-slot="video-player-controls" | Seleciona a barra de controles no CSS. |
data-hidden | Presente enquanto os controles do overlay estão ocultos. |
Sempre ocupa sua própria linha acima dos botões. O hover mostra o tempo sob o ponteiro, e a trilha mais clara mostra o que já foi carregado.
| Prop | Tipo | Padrão |
|---|---|---|
label | string | "Seek" |
onValueChange | (value: number, details) => void | – |
onValueCommitted | (value: number, details) => void | – |
disabled | boolean | false |
| Atributo | Descrição |
|---|---|
data-slot="video-player-seek-bar" | Seleciona a barra de busca no CSS. |
data-dragging | Presente enquanto você arrasta a barra. |
data-previewing | Presente no controle enquanto o tempo do hover é exibido. |
--video-player-buffered | A parte carregada do vídeo, de 0 a 1. |
--video-player-hover | A posição do ponteiro ao longo da barra, de 0 a 1. |
| Prop | Tipo | Padrão |
|---|---|---|
playLabel | string | "Play" |
pauseLabel | string | "Pause" |
replayLabel | string | "Replay" |
...propsTodas as props do Button, incluindo variant e size. | ButtonProps | – |
| Atributo | Descrição |
|---|---|
data-slot="video-player-play-button" | Seleciona o botão no CSS. |
data-state | "paused", "playing" ou "ended". |
| Prop | Tipo | Padrão |
|---|---|---|
offsetSegundos a saltar. Valores negativos voltam. | number | 10 |
label | string | "Forward 10 seconds" |
...propsTodas as props do Button, incluindo variant e size. | ButtonProps | – |
| Atributo | Descrição |
|---|---|
data-slot="video-player-seek-button" | Seleciona o botão no CSS. |
data-direction | "backward" ou "forward". |
Um botão de mudo com um slider que abre no hover ou no foco. Em telas touch só aparece o botão de mudo, já que os celulares controlam o volume com os próprios botões.
| Prop | Tipo | Padrão |
|---|---|---|
label | string | "Volume" |
muteLabel | string | "Mute" |
unmuteLabel | string | "Unmute" |
| Atributo | Descrição |
|---|---|
data-slot="video-player-volume" | Selecione o grupo no CSS. |
data-slot="video-player-mute-button" | O botão de mudo. Também exportado como VideoPlayerMuteButton. |
data-state | No botão de mudo: "muted", "low" ou "high". |
| Prop | Tipo | Padrão |
|---|---|---|
type | "both" | "elapsed" | "remaining" | "duration" | "both" |
| Atributo | Descrição |
|---|---|
data-slot="video-player-time" | Seleciona o tempo no CSS. |
data-type | O tipo atual. |
| Prop | Tipo | Padrão |
|---|---|---|
rates | number[] | [0.5, 0.75, 1, 1.25, 1.5, 2] |
label | string | "Playback speed" |
normalLabel | string | "Normal" |
| Atributo | Descrição |
|---|---|
data-slot="video-player-playback-rate" | Seleciona o gatilho do menu no CSS. |
Coloca o player inteiro em tela cheia, ou o próprio vídeo no iPhone. Não renderiza nada onde a tela cheia não está disponível.
| Prop | Tipo | Padrão |
|---|---|---|
enterLabel | string | "Full screen" |
exitLabel | string | "Exit full screen" |
| Atributo | Descrição |
|---|---|
data-slot="video-player-fullscreen-button" | Seleciona o botão no CSS. |
data-state | "on" ou "off". |
Não renderiza nada até o vídeo ter uma faixa de legendas.
| Prop | Tipo | Padrão |
|---|---|---|
label | string | "Captions" |
| Atributo | Descrição |
|---|---|
data-slot="video-player-captions-button" | Seleciona o botão no CSS. |
data-state | "on" ou "off". |
data-slot="video-player-captions" | O texto da legenda sobre o vídeo. data-lifted está presente enquanto ela fica acima dos controles. |
Não renderiza nada em navegadores sem picture in picture.
| Prop | Tipo | Padrão |
|---|---|---|
enterLabel | string | "Picture in picture" |
exitLabel | string | "Exit picture in picture" |
| Atributo | Descrição |
|---|---|
data-slot="video-player-pip-button" | Seleciona o botão no CSS. |
data-state | "on" ou "off". |
Preenche o espaço livre na linha de controles, empurrando os controles seguintes para o fim.
Retorna o estado e as ações do player. Passe um seletor que retorne um único valor.
| Prop | Tipo | Padrão |
|---|---|---|
state | paused, ended, started, waiting, scrubbing, currentTime, duration, buffered, volume, muted, playbackRate, fullscreen, pictureInPicture, error, hasCaptions, captions, caption | – |
actions | play, pause, togglePaused, seek, seekBy, setVolume, toggleMuted, setPlaybackRate, toggleFullscreen, togglePictureInPicture, toggleCaptions | – |
- ButtonBotões em todas as variantes e tamanhos, com um fluxo integrado de carregamento, sucesso e erro que dispensa o spinner em requisições rápidas.
- Dropdown menuUm menu de ações e opções atrás de um botão, com grupos, submenus, itens de checkbox e de rádio e atalhos.
- KbdTeclas para atalhos que mostram os símbolos certos em cada plataforma, são lidas corretamente por leitores de tela e afundam com as teclas reais.
- MotionAs curvas de easing, as durações e a verificação de movimento reduzido com que todo componente anima, além de hooks para transformações de tamanho e destaques deslizantes.
- SpinnerUm indicador de carregamento com tracinhos no estilo Apple ou um anel que "respira", que pode esperar antes de aparecer e permanecer o suficiente para não piscar.
- TooltipUma dica curta no hover ou no foco do teclado que abre após uma breve pausa, alterna instantaneamente entre vizinhos e exibe atalhos.