Video player
ドラッグ可能なシークバー、自動で隠れるコントロール、キーボードショートカット、再生速度、ピクチャーインピクチャー、全画面表示を備えた動画プレーヤー。
pnpm dlx shadcn@latest add https://hextaui.com/r/video-player.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
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 インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
バー
variant="bar" は、コントロールをページの面の上、映像の下に置きます。動画を隠したり覆ったりすることはありません。
ミニマル
必要なパーツだけを使います。tooltips={false} はホバーのヒントをオフにし、type="remaining" は加算ではなくカウントダウンにします。
シークのオフセットと速度
offset は各シークボタンがジャンプする量を、rates はメニューの速度を設定します。
ページ全体のショートカット
ショートカットは、フォーカスがプレーヤー内にある間機能します。globalShortcuts はページ上でもリッスンしますが、フィールドに入力中、ボタンを使用中、メニューやダイアログが開いている間は機能しません。ページに1つのプレーヤーがある場合に使います。
字幕
<track> と VideoPlayerCaptionsButton を追加します。字幕はプレーヤーが描画するため、コントロールの表示中はその裏に隠れず、上に移動します。クロスオリジンのトラックでは、video に crossOrigin が必要です。
カスタムコントロール
useVideoPlayer は、プレーヤー内の任意のコンポーネントから状態とアクションを読み取ります。使うものだけを選択すると、その値が変わったときだけコンポーネントが再レンダリングされます。
エラー
ソースの読み込みに失敗すると、プレーヤーは errorMessage を表示して読み上げ、動作しないコントロールを無効にします。
右から左
ラベルはページの言語に従います。タイムラインと再生コントロールは、プラットフォームのメディアプレーヤーと同様に、左から右のままです。
これらは、フォーカスがプレーヤー内のどこかにある間、または globalShortcuts ならページ上で機能します。修飾キーが押されている間や、フォーカスがテキストフィールドにある間はスキップされます。
| キー | アクション |
|---|---|
| SpaceK | 再生または一時停止します。 |
| J | 10秒戻ります。 |
| L | 10秒進みます。 |
| ←→ | 5秒戻る、または進みます。シークバー上では Shift で10秒ジャンプします。 |
| ↑↓ | 音量を5%ずつ上げ下げします。 |
| M | ミュートまたはミュート解除します。 |
| C | 動画に字幕がある場合、字幕のオンとオフを切り替えます。 |
| F | 全画面表示に入る、または終了します。 |
| I | 対応している環境で、ピクチャーインピクチャーを開閉します。 |
| Shift+.Shift+, | 再生速度を上げ下げします。 |
| 0–9 | 動画の0%から90%にジャンプします。 |
| HomeEnd | 先頭または末尾にジャンプします。 |
- プレーヤーはラベル付きの領域です。すべてのボタンには状態に従う名前(Play、Pause、Replay)と、ショートカット付きの tooltip があります。
- シークバーと音量は slider です。シークバーは値を「3 minutes 中 1 minute 5 seconds」のように読み上げます。
- ショートカットや動画のクリックによるアクションは、「Paused」や「Volume 40%」のように控えめに読み上げられます。読み込みエラーは alert として読み上げられます。
- overlay バリアントでは、ポインターを動かさずに2.5秒再生するとコントロールがフェードアウトします。一時停止中、ホバー中、キーボードで操作中、メニューが開いている間は表示されたままです。
- タッチスクリーンでは、タップでコントロールの表示と非表示を切り替え、左または右の3分の1をダブルタップすると10秒戻る、または進みます。タップを続けるたびに10秒ずつ加算されます。
- 字幕ボタンは
aria-pressedを持つ toggle です。最後に使ったトラック、次にブラウザーの言語のトラック、それもなければ最初のトラックを選びます。 - 視差効果の軽減が有効な場合、コントロールとフィードバックは移動や拡大縮小をせずにフェードします。
シークバーと音量は Base UI の slider 上に、ボタンは HextaUI の Button、Tooltip、Dropdown menu 上に構築されています。
| プロパティ | 型 | デフォルト |
|---|---|---|
variantoverlay は、自動で隠れるコントロールを動画の上に浮かせます。bar は動画の下に置きます。 | "overlay" | "bar" | "overlay" |
shortcutsフォーカスがプレーヤー内にある間のキーボードショートカット。 | boolean | true |
globalShortcutsページ全体でもショートカットをリッスンします。 | boolean | false |
errorMessage | ReactNode | "This video can’t be played." |
| 属性 | 説明 |
|---|---|
data-slot="video-player" | CSSでルートを指定します。 |
data-variant | 現在のバリアント。 |
data-controls | "visible" または "hidden"。カーソルはコントロールとともに隠れます。 |
data-fullscreen | プレーヤーが全画面表示の間付きます。 |
aria-busy | 再生がデータを待っている間設定されます。 |
<video> 要素。すべての video 属性と、<source> または <track> の子要素を受け付けます。クリックで再生と一時停止、ダブルクリックで全画面の切り替え、タップでコントロールの表示と非表示、どちらかをダブルタップするとシークします。
| プロパティ | 型 | デフォルト |
|---|---|---|
autoPlayマウント時に再生を開始します。視差効果の軽減が有効な場合を除きます。 | boolean | false |
playsInline | boolean | true |
preload | "none" | "metadata" | "auto" | "metadata" |
doubleTapSeekタッチスクリーンで、どちら側かをダブルタップしたときにジャンプする秒数。false でオフになります。 | number | false | 10 |
renderHLS の video 要素など、別のメディア要素に差し替えます。 | ReactElement | (props, state) => ReactElement | <video> |
| 属性 | 説明 |
|---|---|
data-slot="video-player-content" | CSS で動画を指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
tooltipsホバー時に、各コントロールのラベルとショートカットを表示します。 | boolean | true |
| 属性 | 説明 |
|---|---|
data-slot="video-player-controls" | CSS でコントロールバーを指定します。 |
data-hidden | overlay のコントロールが非表示の間付きます。 |
常にボタンの上の専用の行を占めます。ホバーするとポインター位置の時刻が表示され、明るいトラックは読み込み済みの範囲を示します。
| プロパティ | 型 | デフォルト |
|---|---|---|
label | string | "Seek" |
onValueChange | (value: number, details) => void | – |
onValueCommitted | (value: number, details) => void | – |
disabled | boolean | false |
| 属性 | 説明 |
|---|---|
data-slot="video-player-seek-bar" | CSS でシークバーを指定します。 |
data-dragging | スクラブしている間付きます。 |
data-previewing | ホバー時刻が表示されている間、コントロールに付きます。 |
--video-player-buffered | 動画の読み込み済みの部分。0から1。 |
--video-player-hover | バーに沿ったポインターの位置。0から1。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
playLabel | string | "Play" |
pauseLabel | string | "Pause" |
replayLabel | string | "Replay" |
...propsvariant と size を含む、Button のすべての prop。 | ButtonProps | – |
| 属性 | 説明 |
|---|---|
data-slot="video-player-play-button" | CSS でボタンを指定します。 |
data-state | "paused"、"playing"、"ended"。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
offsetジャンプする秒数。負の値は戻ります。 | number | 10 |
label | string | "Forward 10 seconds" |
...propsvariant と size を含む、Button のすべての prop。 | ButtonProps | – |
| 属性 | 説明 |
|---|---|
data-slot="video-player-seek-button" | CSS でボタンを指定します。 |
data-direction | "backward" または "forward"。 |
ホバーまたはフォーカスで開くスライダー付きのミュートボタン。スマートフォンは本体のボタンで音量を調整するため、タッチスクリーンではミュートボタンだけが表示されます。
| プロパティ | 型 | デフォルト |
|---|---|---|
label | string | "Volume" |
muteLabel | string | "Mute" |
unmuteLabel | string | "Unmute" |
| 属性 | 説明 |
|---|---|
data-slot="video-player-volume" | CSSでグループを指定します。 |
data-slot="video-player-mute-button" | ミュートボタン。VideoPlayerMuteButton としてもエクスポートされています。 |
data-state | ミュートボタン上: "muted"、"low"、"high"。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
type | "both" | "elapsed" | "remaining" | "duration" | "both" |
| 属性 | 説明 |
|---|---|
data-slot="video-player-time" | CSS で時刻を指定します。 |
data-type | 現在のタイプ。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
rates | number[] | [0.5, 0.75, 1, 1.25, 1.5, 2] |
label | string | "Playback speed" |
normalLabel | string | "Normal" |
| 属性 | 説明 |
|---|---|
data-slot="video-player-playback-rate" | CSS でメニューのトリガーを指定します。 |
プレーヤー全体を全画面にします。iPhone では動画自体を全画面にします。全画面表示が使えない環境では何も描画しません。
| プロパティ | 型 | デフォルト |
|---|---|---|
enterLabel | string | "Full screen" |
exitLabel | string | "Exit full screen" |
| 属性 | 説明 |
|---|---|
data-slot="video-player-fullscreen-button" | CSS でボタンを指定します。 |
data-state | "on" または "off"。 |
動画に字幕トラックができるまで、何も描画しません。
| プロパティ | 型 | デフォルト |
|---|---|---|
label | string | "Captions" |
| 属性 | 説明 |
|---|---|
data-slot="video-player-captions-button" | CSS でボタンを指定します。 |
data-state | "on" または "off"。 |
data-slot="video-player-captions" | 動画上の字幕テキスト。コントロールの上に持ち上げられている間は data-lifted が付きます。 |
ピクチャーインピクチャーのないブラウザーでは何も描画しません。
| プロパティ | 型 | デフォルト |
|---|---|---|
enterLabel | string | "Picture in picture" |
exitLabel | string | "Exit picture in picture" |
| 属性 | 説明 |
|---|---|
data-slot="video-player-pip-button" | CSS でボタンを指定します。 |
data-state | "on" または "off"。 |
コントロール行の空き領域を埋め、後ろのコントロールを末尾に押しやります。
プレーヤーの状態とアクションを返します。単一の値を返すセレクターを渡してください。
| プロパティ | 型 | デフォルト |
|---|---|---|
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 | – |
- Buttonすべてのバリアントとサイズのボタンです。読み込み、成功、エラーのフローを内蔵し、高速なリクエストではスピナーを省略します。
- Dropdown menuボタンの背後に、操作とオプションをまとめたメニューです。グループ、サブメニュー、チェックボックス項目、ラジオ項目、ショートカットに対応します。
- Kbdショートカット用のキーキャップです。プラットフォームごとに正しい記号を表示し、正しく読み上げ、実際のキーと同じように押し込まれます。
- Motionすべてのコンポーネントがアニメーションに使うイージングカーブ、継続時間、モーション軽減のチェックと、サイズのモーフィングやスライドするハイライト用のフックです。
- SpinnerApple風の目盛りまたは呼吸するリングで表示する読み込みインジケーターです。表示までの待機と、ちらつかない最短表示時間を設定できます。
- Tooltipホバーまたはキーボードフォーカスで、少し待ってから開く短いヒントです。隣り合う要素の間では即座に切り替わり、ショートカットも表示できます。