drop-player
A comprehensive, universal, open-source React media player powering drop.mov.
動画(HLS / プログレッシブ)、音声、画像、PDFに対応。 ひとつのコンポーネントで、ソースURLからメディア種別を自動判定します。
インストール
npm i drop-player lucide-react
必須 peer dependencies: react >=18, react-dom >=18, lucide-react >=0.300
オプション(必要な場合のみ):
| パッケージ | 用途 |
|---|---|
hls.js >=1.4 |
HLS動画 (.m3u8) |
pdfjs-dist >=4.0 |
PDFキャンバスレンダリング(ズーム、パン、ページ送り) |
waveform-data >=4.5 |
音声波形表示 |
クイックスタート
import { Player } from 'drop-player';
import 'drop-player/styles.css';
function App() {
return (
<div style={{ width: 640, height: 360 }}>
<Player sources="https://example.com/video.mp4" />
</div>
);
}
スタイルシートは必須です — drop-player プレフィックスのクラスとCSS変数が定義されています。
コンポーネント
| エクスポート | 用途 |
|---|---|
Player |
汎用 — URLからモードを自動判定 |
VideoPlayer |
動画 |
AudioPlayer |
音声 |
ImageViewer |
画像 |
PdfViewer |
VideoPlayer や AudioPlayer などは可読性のためのエイリアスです。すべて同じ PlayerProps / PlayerRef を共有し、メディアモードはソースURLから自動判定されます。種別が混在する場合や不明な場合は Player を使ってください。
対応メディア
| モード | フォーマット |
|---|---|
| 動画 | HLS (.m3u8), MP4, WebM |
| 音声 | MP3, WAV, Ogg, AAC, FLAC, M4A, WebM, Opus |
| 画像 | JPEG, PNG, GIF, WebP, AVIF, SVG |
pdf.jsによるキャンバスレンダリング(ズーム、パン、ページ送り)。pdfjs-dist 未インストール時はブラウザ標準の <object> にフォールバック |
ブラウザ専用のランタイムです。SSRフレームワーク(Next.js, Remix, Astro 等)での import は安全で、サーバー上では何も描画せず、クライアントで有効化されます。
ソース
// 文字列 — 拡張子からタイプを推定
<VideoPlayer sources="https://example.com/video.mp4" />
// オブジェクト — HLSとオリジナル画質のフォールバック
<VideoPlayer sources={{ url: 'stream.m3u8', originalUrl: 'original.mp4' }} />
// 配列 — ソースセレクターを表示
<VideoPlayer sources={[
{ url: 'stream.m3u8', label: 'HLS' },
{ url: 'original.mp4', label: 'Original' },
]} />
// 明示的なMIMEタイプ — URLに拡張子がない場合に便利(例: CDN、署名付きURL)
<Player sources={{ url: 'https://cdn.example.com/abc123', mimeType: 'video/mp4' }} />
// null — エラーUIを表示
<VideoPlayer sources={null} />
メディア種別はパスの拡張子(.mp4, .m3u8, .pdf, .jpg, …)または mimeType から判定されます。
Props
Propsは4つのグループに分かれています:
<VideoPlayer
sources="video.mp4"
className="rounded-lg"
crossOrigin="anonymous"
poster="poster.jpg"
playback={{ autoPlay: true, volume: 0.8 }}
ui={{ features: { saveCapture: true, copyCapture: true }, locale: 'ja' }}
slots={{ topRightOverlay: <Badge /> }}
events={{ onPlay: () => log('playing') }}
/>
トップレベル
| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
sources |
string | MediaSource | MediaSource[] | null |
— | メディアソース |
className |
string |
— | ルートコンテナのCSSクラス |
crossOrigin |
'anonymous' | 'use-credentials' |
'anonymous' |
メディア要素のCORS設定 |
poster |
string |
— | ポスター画像(動画用) |
storageKey |
string |
— | localStorageキーのプレフィックス(デフォルト: drop_player_、指定時: <storageKey>_)。ミュート状態は自動保存されます。 |
storage |
StorageAdapter |
— | 独自のストレージバックエンド(getItem, setItem, removeItem を実装)。デフォルトは localStorage(SSRセーフ)。 |
hlsConfig |
Partial<HlsConfig> |
— | hls.js の設定を上書き |
playback — PlayerPlaybackConfig
| キー | 型 | デフォルト | 説明 |
|---|---|---|---|
autoPlay |
boolean |
false |
即座に再生を開始 |
loop |
boolean |
false |
ループ再生 |
muted |
boolean |
false |
ミュート状態で開始 |
volume |
number |
1 |
初期音量 (0–1) |
initialTime |
number |
0 |
開始位置(秒) |
seekStep |
number |
10 |
左右キーでスキップする秒数 |
ui — PlayerUiConfig
| キー | 型 | デフォルト | 説明 |
|---|---|---|---|
showControls |
boolean |
true |
下部コントロールバーを表示 |
showTitle |
boolean |
auto | ソースタイトル/セレクターを表示 |
showStatusOverlay |
boolean |
false |
操作時にステータスPillオーバーレイを表示(再生、シーク、音量など) |
features |
PlayerFeatures |
defaultFeatures |
個別コントロールの切り替え |
locale |
string |
'en' |
表示言語(組み込み: 'en', 'ja') |
translations |
Partial<Translations> |
— | 翻訳の部分上書き。ロケールの組み込み文字列に対して差分を指定 |
frameRate |
number |
auto / 30 |
タイムコード/フレーム表示用のフレームレート。HLSマニフェストから自動検出(利用可能な場合)、フォールバック: 30 |
timeDisplayFormats |
TimeDisplayFormat[] |
defaultTimeDisplayFormats |
クリックで切り替える時間表示形式 |
filmGauge |
number |
16 |
'feet-frames' 表示のフィート当たりフレーム数(例: 35mm=16, 16mm=40) |
bpm |
number |
120 |
'bars-beats' 表示のBPM |
timeSignature |
string |
'4/4' |
'bars-beats' 表示の拍子記号(例: '3/4', '6/8') |
markers |
Marker[] |
[] |
シークバーマーカー — マーカータイプを参照 |
マーカータイプ
Marker は判別ユニオン型です。type によってシークバートラック上の表示形状が変わります:
type |
形状 | 追加フィールド |
|---|---|---|
'circle'(デフォルト) |
塗りつぶし円 | — |
'line' |
縦線 | — |
'square' |
塗りつぶし正方形 | — |
'custom' |
任意のReactNode | content: ReactNode(必須) |
共通フィールド:
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
time |
number |
— | 位置(秒) |
color |
string |
CSS変数 | CSS色値 |
snap |
boolean |
false |
シーク時にスナップを有効化 |
snapThreshold |
number |
12 |
スナップ距離(px)snap: true のときのみ使用 |
import type { Marker } from 'drop-player';
const markers: Marker[] = [
{ time: 10, type: 'circle', snap: true },
{ time: 30, type: 'line' },
{ time: 60, type: 'square', color: 'red' },
{
time: 90,
type: 'custom',
content: <div style={{ ... }}>ラベル</div>,
},
];
<VideoPlayer sources={url} ui={{ markers }} />
slots — PlayerSlots
| スロット | 型 | 配置位置 |
|---|---|---|
overlay |
ReactNode |
メディアとコントロールの間の全面オーバーレイ |
controlsStart |
ReactNode |
コントロールバーの左側 |
controlsEnd |
ReactNode |
コントロールバーの右側(フルスクリーンボタンの前) |
topLeftOverlay |
ReactNode |
左上隅 |
topRightOverlay |
ReactNode |
右上隅 |
loadingIndicator |
ReactNode |
中央(読み込み中) |
errorDisplay |
(error: Error) => ReactNode |
中央(エラー時) |
Note:
overlayはデフォルトでpointer-events: noneです。操作可能にしたい子要素にはpointer-events: autoを指定してください。
events — PlayerEvents
| イベント | ペイロード | タイミング |
|---|---|---|
onStateChange |
PlayerState |
状態変更(まとめてスナップショット) |
onPlay |
— | 再生開始 |
onPause |
— | 一時停止 |
onEnded |
— | 再生終了 |
onTimeUpdate |
time |
再生位置の更新 |
onDurationChange |
duration |
長さの確定/変更 |
onVolumeChange |
volume, muted |
音量/ミュート変更 |
onPlaybackRateChange |
rate |
再生速度変更 |
onError |
Error |
エラー発生 |
onLoadedMetadata |
VideoMetadata |
メタデータ取得 |
onLoadStart |
— | 読み込み開始 |
onProgress |
TimeRanges |
バッファリング進行 |
onWaiting |
— | データ待ち |
onCanPlay |
— | 再生可能 |
onPlaying |
— | 実際に再生中 |
onSeekStart |
time |
シーク開始 |
onSeeking |
time |
シーク中 |
onSeekEnd |
time |
シーク完了 |
onFullscreenChange |
boolean |
フルスクリーン切り替え |
onFrameCapture |
FrameCapture |
フレームキャプチャ |
onActiveSourceChange |
index |
アクティブソース変更 |
onQualityLevelChange |
QualityLevel |
画質レベル変更 |
onFallback |
FallbackEvent |
オリジナルURLへフォールバック |
onTimeDisplayFormatChange |
TimeDisplayFormat |
時間表示形式の変更 |
Features
ui.features で個別のコントロールをON/OFFできます。省略したキーは defaultFeatures を引き継ぎます。
2つのプリセットをエクスポートしています:
| エクスポート | 説明 |
|---|---|
defaultFeatures |
主要コントロールON、オプトイン機能はOFF |
noFeatures |
すべてOFF — 最小構成のベースに |
import { noFeatures } from 'drop-player';
// Default — most controls on
<VideoPlayer sources={url} />
// Add capture buttons to defaults
<VideoPlayer sources={url} ui={{ features: { saveCapture: true, copyCapture: true } }} />
// Remove loop from defaults
<VideoPlayer sources={url} ui={{ features: { loop: false } }} />
// Build from scratch
<VideoPlayer sources={url} ui={{ features: { ...noFeatures, playButton: true, fullscreen: true } }} />
| フラグ | デフォルト | 適用対象 |
|---|---|---|
playButton |
true |
動画, 音声 |
loop |
true |
動画, 音声 |
timeDisplay |
true |
動画, 音声 |
seekBar |
true |
動画, 音声 |
volume |
true |
動画, 音声 |
saveCapture |
false |
動画, 画像 |
copyCapture |
false |
動画, 画像 |
qualitySelector |
true |
動画 (HLS) |
fullscreen |
true |
すべて |
zoom |
true |
画像, PDF |
playbackSpeed |
true |
動画, 音声 |
pip |
true |
動画(ブラウザPiP APIが必要) |
keyboardShortcuts |
true |
動画, 音声 |
時間表示形式
ui.timeDisplayFormats で、時間表示をクリックした際に切り替わる形式を制御します。2つのプリセットをエクスポートしています:
| エクスポート | 形式 |
|---|---|
defaultTimeDisplayFormats |
['elapsed-total', 'remaining'] |
allTimeDisplayFormats |
['elapsed-total', 'remaining', 'timecode', 'frames', 'seconds-frames', 'feet-frames', 'bars-beats'] |
import { defaultTimeDisplayFormats, allTimeDisplayFormats } from 'drop-player';
// デフォルト — 経過/合計と残り時間
<VideoPlayer sources={url} />
// タイムコードとフレームを追加
<VideoPlayer sources={url} ui={{ timeDisplayFormats: allTimeDisplayFormats }} />
// 映像制作向け — フィート+フレーム(35mm)を追加
<VideoPlayer sources={url} ui={{
timeDisplayFormats: [...defaultTimeDisplayFormats, 'timecode', 'feet-frames'],
filmGauge: 16,
}} />
// 音楽向け — 小節:拍を追加
<AudioPlayer sources={url} ui={{
timeDisplayFormats: [...defaultTimeDisplayFormats, 'bars-beats'],
bpm: 92,
timeSignature: '4/4',
}} />
// 単一形式に固定(クリックしても変わらない)
<VideoPlayer sources={url} ui={{ timeDisplayFormats: ['timecode'] }} />
| 形式 | 表示例 | 追加props |
|---|---|---|
'elapsed-total' |
1:23 / 5:00 |
— |
'remaining' |
-3:37 |
— |
'timecode' |
00:01:23:15 |
frameRate |
'frames' |
2475 / 9000 |
frameRate |
'seconds-frames' |
83+15 / 300+00 |
frameRate |
'feet-frames' |
154+11 / 562+08 |
frameRate, filmGauge |
'bars-beats' |
47:4 / 192:1 |
bpm, timeSignature |
フレームレートはHLSマニフェストから自動検出されます。プログレッシブソースの場合は ui.frameRate を明示的に設定してください。
テーマ
.drop-player のCSS変数を上書きできます:
@import 'drop-player/styles.css';
.drop-player {
--drop-player-blue: oklch(70.7% 0.165 254.624);
--drop-player-yellow: oklch(85.2% 0.199 91.936);
--drop-player-green: oklch(79.2% 0.209 151.711);
--drop-player-red: oklch(70.4% 0.191 22.216);
--drop-player-muted: oklch(55.2% 0.016 285.938);
--drop-player-marker-circle: var(--drop-player-yellow);
--drop-player-border-radius: 8px;
}
| 変数 | デフォルト | 説明 |
|---|---|---|
--drop-player-blue |
oklch(70.7% 0.165 254.624) |
アクセントカラー(アクティブ状態、フォーカスリング) |
--drop-player-yellow |
oklch(85.2% 0.199 91.936) |
ハイライトカラー |
--drop-player-green |
oklch(79.2% 0.209 151.711) |
ポジティブカラー(チェックマーク、最高画質) |
--drop-player-red |
oklch(70.4% 0.191 22.216) |
ネガティブカラー(エラー) |
--drop-player-muted |
oklch(55.2% 0.016 285.938) |
ミュート / 非アクティブカラー |
--drop-player-marker-circle |
var(--drop-player-yellow) |
マーカーの色(circle・line・square) |
--drop-player-border-radius |
0 |
コンテナの角丸 |
--drop-player-aspect-ratio |
可変 | アスペクト比(動画: 16/9, 音声: 32/9, 画像: 4/3, PDF: 1/1.414) |
Ref API
PlayerRef 経由でメソッドを呼び出せます:
const ref = useRef<PlayerRef>(null);
<VideoPlayer ref={ref} sources={url} />
// Later:
ref.current?.play();
ref.current?.seek(30);
| メソッド | 戻り値 | 備考 |
|---|---|---|
play() |
Promise<void> |
|
pause() |
void |
|
toggle() |
void |
|
seek(time) |
void |
|
seekRelative(delta) |
void |
|
seekToFrame(frame) |
void |
動画のみ |
getCurrentTime() |
number |
|
getDuration() |
number |
|
getVolume() |
number |
|
isMuted() |
boolean |
|
isPaused() |
boolean |
|
isFullscreen() |
boolean |
|
getPlaybackRate() |
number |
|
setVolume(n) |
void |
|
setMuted(bool) |
void |
|
setPlaybackRate(rate) |
void |
|
getTimeDisplayFormat() |
TimeDisplayFormat |
|
setTimeDisplayFormat(format) |
void |
|
captureFrame(opts?) |
Promise<FrameCapture> |
動画/画像のみ。音声/PDFではエラーをスロー |
requestFullscreen() |
Promise<void> |
|
exitFullscreen() |
Promise<void> |
|
toggleFullscreen() |
void |
|
getVideoElement() |
HTMLVideoElement | null |
|
getContainerElement() |
HTMLDivElement | null |
エラーハンドリング
events.onError と slots.errorDisplay は name で種別を判別できる Error を受け取ります:
error.name |
意味 |
|---|---|
errorNoSources |
sourcesがnullまたは空 |
errorAborted |
再生が中断された |
errorNetwork |
ネットワークエラー |
errorDecode |
デコード失敗 |
errorNotSupported |
フォーマットがサポートされていない |
errorUnknown |
不明なエラー |
組み込みUIは ui.locale に従ってエラーメッセージをローカライズします。独自の表示にするには slots.errorDisplay を使ってください。
翻訳
組み込みロケール: 'en' と 'ja'。ui.locale で切り替えます。
ロケールの追加や文字列の部分上書きには ui.translations を使います:
<VideoPlayer
sources="video.mp4"
ui={{
locale: 'en',
translations: {
play: 'Reproducir',
pause: 'Pausar',
mute: 'Silenciar',
unmute: 'Activar sonido',
fullscreen: 'Pantalla completa',
exitFullscreen: 'Salir de pantalla completa',
},
}}
/>
ベースロケールの文字列に対して差分だけ指定すればOKです。
カスタムストレージ
プレーヤーの設定(ミュート状態など)はデフォルトで localStorage に保存されます。storageKey でキーのプレフィックスを変えたり、storage でバックエンド自体を差し替えられます。
// Custom namespace
<VideoPlayer sources="video.mp4" storageKey="my_app" />
// Keys stored as: my_app_muted, my_app_volume, etc.
// Custom backend (e.g. Supabase)
const supabaseStorage = {
getItem: (key: string) => {
// Read from Supabase cache or return null
return localStorage.getItem(key);
},
setItem: (key: string, value: string) => {
localStorage.setItem(key, value);
supabase.from('preferences').upsert({ key, value });
},
removeItem: (key: string) => {
localStorage.removeItem(key);
supabase.from('preferences').delete().eq('key', key);
},
};
<VideoPlayer sources="video.mp4" storage={supabaseStorage} />
StorageAdapter は getItem・setItem・removeItem の3メソッドを実装します。戻り値は同期的に返す必要があるため、リモートバックエンドの場合はローカルキャッシュ経由で非同期に同期してください。
ユーティリティ
プレーヤー外でも使えるヘルパー関数:
import {
formatTime, formatTimecode, secondsToFrames, parseFrameRate,
formatFeetFrames, formatSecondsFrames, formatBarsBeats,
} from 'drop-player';
formatTime(125); // "02:05"
formatTime(3661); // "01:01:01"
formatTimecode(125.5, 30); // "00:02:05:15"
formatTimecode(125.5, '30000/1001');// "00:02:05:14" (29.97fps)
secondsToFrames(10, 24); // 240
parseFrameRate('30000/1001'); // 29.97...
formatSecondsFrames(83.5, 30); // "83+15"
formatFeetFrames(10, 24, 16); // "15+00"
formatBarsBeats(10, 120, '4/4'); // "5:1"
| 関数 | シグネチャ | 説明 |
|---|---|---|
formatTime |
(seconds?) => string |
MM:SSまたはHH:MM:SS形式にフォーマット |
formatTimecode |
(seconds?, frameRate?) => string |
SMPTEタイムコードHH:MM:SS:FF形式にフォーマット |
secondsToFrames |
(seconds?, frameRate?) => number |
秒をフレーム番号に変換 |
parseFrameRate |
(frameRate?) => number |
フレームレート文字列(例: "30000/1001")を数値にパース |
formatSecondsFrames |
(seconds?, frameRate?) => string |
秒+フレーム S+FF 形式にフォーマット |
formatFeetFrames |
(seconds?, frameRate?, filmGauge?) => string |
フィート+フレーム FFF+FF 形式にフォーマット |
formatBarsBeats |
(seconds?, bpm?, timeSignature?) => string |
小節:拍 B:b 形式にフォーマット |
ライセンス
MIT
Changelog
1.5.5
Features
- Add
drop-player/utilssub-path export — pure formatter functions (formatTime,formatTimecode,secondsToFrames,parseFrameRate,formatSecondsFrames,formatFeetFrames,formatBarsBeats) importable without React, safe for Server Components
1.5.4
Features
- Add
overlayslot — full-area overlay layer between media and controls (pointer-events: noneby default)
1.5.2
Bug Fixes
- Fix SSR safety: guard
ResizeObserverusage inuseElementWidthshook withtypeofcheck to preventReferenceErrorin server-side rendering environments
1.5.0
Breaking Changes
- Remove ambient light feature —
ambientLighthas been removed fromPlayerFeatures,VideoState,VideoCoreRef, and all related UI/CSS. If you were usingfeatures={{ ambientLight: true }}, remove it.
1.4.0
Features
- Add responsive controls bar — controls dynamically collapse into an overflow menu based on available width
- Add overflow menu (⋯) that groups secondary controls (ambient light, PiP, playback speed, capture) when space is limited
- Split capture button into separate
CopyCaptureButtonandSaveCaptureButtoncontrols - Add
useFeedbackhook for transient action feedback (e.g. "Copied!") - Add
useMediaQueryanduseElementWidthshooks for responsive layout
Bug Fixes
- Fix marker positions not rendering correctly on the seekbar
- Fix SEO: add prerender script for demo site, update
llms.txt/llms-ja.txt
1.3.0
Breaking Changes
- Marker API redesigned —
Markeris now a discriminated union. Replacetype: 'scene'withtype: 'circle'. The oldtype: 'custom'(no-op) now requirescontent: ReactNode. slots.seekbarOverlayremoved — usetype: 'custom'markers instead.- CSS variable
--drop-player-marker-scenerenamed to--drop-player-marker-circle.--drop-player-marker-customremoved. - Snap is now opt-in per marker — add
snap: trueto each marker that should snap. Previously snap was always active when markers were present.
Features
- New marker types:
'circle'(renamed from'scene'),'line','square','custom' snap?: boolean— enable snap-to per marker (default:false)snapThreshold?: number— per-marker snap distance in px (default:12, only used whensnap: true)content: ReactNode— render arbitrary content on the seekbar track at a specific time (type: 'custom')- Named marker types (
CircleMarker,LineMarker,SquareMarker,CustomMarker) exported from package root
1.2.5
- Revert 1.2.4
1.2.4 (deprecated)
Fix Webpack/Turbopack build error (— reverted,Module not found) when optional peer dependencies are not installedwebpackIgnoreprevents bundlers from resolving installed packages at runtime
1.2.3
Bug Fixes
- Fix controls overlay not recoverable on mobile for Image, PDF, and Audio modes — tapping the content area now toggles controls visibility, matching Video behavior
- Fix player blocking page scroll on mobile — allow vertical scrolling (
pan-y) for all media types; only block scroll when Image/PDF is zoomed in
1.2.2
Bug Fixes
- Fix controls UI not showing on tap for Image, PDF, and Audio modes
1.2.1
Bug Fixes
- Fix PDF cleanup on unmount (add
destroyWorkercall) - Improve
StatusOverlayaccessibility and translation handling - Fix re-exported types from package root
1.2.0
Features
- Add pdf.js integration as optional peer dependency for canvas-based PDF rendering with real zoom, pan, and page navigation
- Add
PageNavigationcontrol (prev/next page withChevronUp/ChevronDownicons) - Add
PdfCoreRefimperative handle (zoomIn,zoomOut,resetZoom,nextPage,prevPage,goToPage) - Add keyboard shortcuts for PDF mode (
ArrowUp/ArrowDownfor pages,+/-/0for zoom) - Add swipe gesture for PDF page navigation (disabled when zoomed)
- Fallback to browser-native
<object>rendering whenpdfjs-distis not installed
Improvements
- PDF pages fit container at 100% zoom (no excess margins)
- Zoom re-renders via pdf.js for crisp vector text (debounced 150ms with immediate CSS feedback)
- Page change resets zoom to 1x
- Controls and title auto-hide after 3 seconds for image and PDF modes (consistent with video/audio)
- Source change resets readiness state so loading overlay covers stale content
- Add
tabular-numsto zoom level display - Controls overlay now has proper z-index to remain visible during loading
1.1.7
Features
- Add
seekStepplayback option to configure arrow key skip duration in seconds (default: 10) - Add
seekStepButtonsfeature flag for skip forward/backward buttons - Add
showStatusOverlayUI option — pill-style overlay showing player actions (play/pause, seek, volume, speed, quality, zoom, loop)
1.1.6
Features
- Add multi-source navigation (prev/next buttons, swipe gesture, keyboard navigation)
- Add
sourceNavigationfeature flag to show/hide prev/next buttons - Add time display formats:
seconds-frames,feet-frames,bars-beats - Auto-detect frame rate from HLS level metadata
- Add CSS color variables for easier theme customization
Improvements
- Expand touch/click target for seekbar and volume slider thumbs without changing visual appearance
- Style dropdown scrollbar to match player theme
1.1.5
Improvements
- Add drag-to-seek on audio waveform (click to seek, drag to scrub)
- Add accessibility attributes on audio waveform area (
role="slider",aria-valuemin/max/now) - Improve PDF error handling: pre-validate URL reachability, fire
onErrorwitherrorNetworkon failure - Suppress
AbortErrorfrom play/pause races
Bug Fixes
- Fix audio player not showing error state when loading fails
Documentation
- Add CSS variables reference table, feature presets, Translations, Custom storage, Utilities sections to README
1.1.4
Improvements
VideoPlayer,AudioPlayer,ImageViewer,PdfViewernow set media mode directly, skipping source type inference- Add default
aspect-ratioper media mode (video: 16/9, audio: 32/9, image: 4/3, pdf: 1/1.414), overridable via--drop-player-aspect-ratio - Warn when URL has no recognizable extension and
mimeTypeis not provided
Bug Fixes
- Fix
min-width: 100%redundancy on player container
1.1.3
Bug Fixes
- Fix hydration mismatch caused by PiP support detection running during SSR
1.1.2
Bug Fixes
- Unify mouse/touch handling with Pointer Events for consistent drag-to-seek and controls toggle
- Improve HLS fatal error handling: network errors now trigger fallback, media error recovery limited to one attempt
- Type
hlsConfigasPartial<HlsConfig>instead ofRecord<string, unknown> - Add
network-errortoFallbackReasontype - Rename legacy
@dropmov/playerreferences todrop-playerin console warnings
Styles
- Responsive timestamp position in controls bar
1.1.1
Features
- Add
storageprop for customStorageAdapter(replaces default localStorage) - Add
translationsprop for custom i18n string overrides - Widen
localetype from'en' | 'ja'tostringfor custom locales - Stabilize React hooks to avoid unnecessary re-renders with object props
Styles
- Fix ambient light mode rendering
- Reposition timestamp display
1.1.0
Features
- Add
storageKeyprop to customize localStorage key prefix (default:drop_player_, custom:<storageKey>_) - Persist and restore muted state across sessions via localStorage
Breaking Changes
- Remove
persistenceKeyprop and playback position persistence feature - Remove
onPositionSave/onPositionRestoreevent callbacks
1.0.7
Bug Fixes
- Fix tooltip not dismissing on Safari and touch devices
- Fix multiple tooltips displaying simultaneously
- Auto-dismiss tooltips after timeout on touch interactions
- Fix muted state behavior
1.0.6
Features
- Add playback speed selector control
- Add Picture-in-Picture (PiP) button control
Bug Fixes
- Fix tooltip position not recalculating when content changes
1.0.5
Features
- Support
hlsConfigprop for custom hls.js configuration - Tune ABR settings for smoother adaptive bitrate switching
Bug Fixes
- Dynamically import
waveform-datato reduce initial bundle size - Fix tooltip position
1.0.4
Maintenance
- Disable sourcemap output and enable minification in build
- Remove unnecessary documentation files
1.0.3
Breaking Changes
- Remove Tailwind CSS dependency from library output; all styles are now plain CSS with
drop-player-*BEM classes - Consumers no longer need Tailwind — just import
drop-player/styles.css
Bug Fixes
- Fix controls and seekbar not rendering (Tailwind utility classes missing from build output)
1.0.2
Bug Fixes
- Fix player and controls not spanning full width in flex/aspect-ratio layouts
1.0.1
Maintenance
- Update dependency packages
1.0.0
Initial Release
- Video and audio player component with custom controls
- Keyboard shortcuts support
- Marker/chapter support (scene markers, custom markers)
- Playback speed control
- Volume control with mute toggle
- Fullscreen support
- Ambient light effect
- Multiple source selector
- Customizable theming via CSS variables
- Error handling with retry