@banou/media-player 0.2.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +0 -10
  2. package/build/components/chrome.d.ts +4 -0
  3. package/build/components/control-bar.d.ts +5 -0
  4. package/build/components/overlay.d.ts +1 -0
  5. package/build/components/progress-bar.d.ts +1 -0
  6. package/build/components/settings.d.ts +2 -0
  7. package/build/components/sound.d.ts +4 -0
  8. package/build/components/tooltip-display.d.ts +20 -0
  9. package/build/components/volume-slider.d.ts +6 -0
  10. package/build/index.d.ts +23 -48
  11. package/build/index.js +2593 -2230
  12. package/build/main.d.ts +1 -1
  13. package/build/state-machines/data-source.d.ts +27 -0
  14. package/build/state-machines/index.d.ts +33185 -0
  15. package/build/state-machines/media-properties.d.ts +45 -0
  16. package/build/state-machines/media-source.d.ts +34 -0
  17. package/build/state-machines/media.d.ts +8344 -0
  18. package/build/state-machines/subtitles.d.ts +53 -0
  19. package/build/state-machines/thumbnails.d.ts +24 -0
  20. package/build/state-machines/utils.d.ts +26 -0
  21. package/build/utils/actor-utils.d.ts +2 -0
  22. package/build/utils/colors.d.ts +8 -0
  23. package/build/utils/context.d.ts +14 -0
  24. package/build/utils/fonts.d.ts +28 -0
  25. package/build/{utils.d.ts → utils/index.d.ts} +4 -12
  26. package/build/utils/languages.d.ts +260 -0
  27. package/build/{mp4box.d.ts → utils/mp4box.d.ts} +61 -61
  28. package/build/utils/time.d.ts +2 -0
  29. package/build/utils/use-local-storage.d.ts +3 -0
  30. package/build/{use-scrub.d.ts → utils/use-scrub.d.ts} +11 -10
  31. package/build/utils/volume-utils.d.ts +17 -0
  32. package/build/utils/window-height.d.ts +2 -0
  33. package/package.json +15 -12
  34. package/src/assets/picture-in-picture.svg +5 -0
  35. package/src/components/chrome.tsx +89 -0
  36. package/src/components/control-bar.tsx +330 -0
  37. package/src/components/overlay.tsx +28 -0
  38. package/src/components/progress-bar.tsx +252 -0
  39. package/src/components/settings.tsx +269 -0
  40. package/src/components/sound.tsx +101 -0
  41. package/src/components/tooltip-display.tsx +83 -0
  42. package/src/components/volume-slider.tsx +156 -0
  43. package/src/index.tsx +145 -434
  44. package/src/main.tsx +66 -39
  45. package/src/state-machines/data-source.ts +83 -0
  46. package/src/state-machines/index.ts +5 -0
  47. package/src/state-machines/media-properties.ts +78 -0
  48. package/src/state-machines/media-source.ts +129 -0
  49. package/src/state-machines/media.ts +245 -0
  50. package/src/state-machines/subtitles.ts +247 -0
  51. package/src/state-machines/thumbnails.ts +123 -0
  52. package/src/state-machines/utils.ts +94 -0
  53. package/src/utils/actor-utils.ts +19 -0
  54. package/src/utils/colors.ts +9 -0
  55. package/src/utils/context.ts +23 -0
  56. package/src/utils/fonts.ts +156 -0
  57. package/src/{utils.ts → utils/index.ts} +2 -26
  58. package/src/utils/time.ts +16 -0
  59. package/src/utils/use-local-storage.ts +30 -0
  60. package/src/{use-scrub.ts → utils/use-scrub.ts} +2 -1
  61. package/src/utils/volume-utils.ts +39 -0
  62. package/src/utils/window-height.ts +19 -0
  63. package/src/vite-env.d.ts +1 -1
  64. package/tsconfig.json +4 -2
  65. package/tsconfig.node.json +9 -9
  66. package/build/chrome/bottom.d.ts +0 -20
  67. package/build/chrome/index.d.ts +0 -27
  68. package/build/chrome/overlay.d.ts +0 -9
  69. package/build/languages.d.ts +0 -260
  70. package/build/use-local-storage.d.ts +0 -6
  71. package/src/chrome/bottom.tsx +0 -651
  72. package/src/chrome/index.tsx +0 -199
  73. package/src/chrome/overlay.tsx +0 -104
  74. package/src/use-local-storage.ts +0 -32
  75. /package/src/{languages.ts → utils/languages.ts} +0 -0
  76. /package/src/{mp4box.ts → utils/mp4box.ts} +0 -0
@@ -1,199 +0,0 @@
1
- /// <reference types="@emotion/react/types/css-prop" />
2
- import type { ClassAttributes, HTMLAttributes, MouseEventHandler, MutableRefObject, ReactNode } from 'react'
3
- import type { Attachment, FKNVideoControl, Subtitle, TransmuxError } from '..'
4
-
5
- import { useEffect, useMemo, useRef, useState } from 'react'
6
- import JASSUB from 'jassub'
7
- import { css } from '@emotion/react'
8
- import Overlay from './overlay'
9
- import Bottom from './bottom'
10
-
11
- const style = css`
12
- --background-padding: 2rem;
13
- display: grid;
14
- grid-template-rows: 1fr;
15
- overflow: hidden;
16
-
17
- &.hide {
18
- cursor: none;
19
-
20
- .bottom {
21
- opacity: 0;
22
- }
23
- }
24
-
25
- .bottom {
26
- &.hide {
27
- opacity: 0 !important;
28
- }
29
- }
30
- `
31
-
32
- export type ChromeOptions = {
33
- publicPath: string
34
- customOverlay?: ReactNode
35
- isPlaying?: boolean
36
- loading?: boolean
37
- duration?: number
38
- loadedTime?: [number, number]
39
- currentTime?: number
40
- pictureInPicture: () => void
41
- fullscreen: () => void
42
- play: () => void
43
- seek: (time: number) => void
44
- getVolume: () => number | undefined
45
- setVolume: (volume: number) => void
46
- attachments: Attachment[] | undefined
47
- tracks: Subtitle[]
48
- video: MutableRefObject<HTMLVideoElement | undefined>
49
- errors: TransmuxError[]
50
- customControls?: FKNVideoControl[]
51
- libassWorkerUrl: string
52
- wasmUrl: string
53
- needsInitialInteraction?: boolean
54
- } & HTMLAttributes<HTMLDivElement>
55
-
56
- export default ({
57
- customOverlay,
58
- publicPath,
59
- isPlaying,
60
- loading,
61
- duration,
62
- loadedTime,
63
- currentTime,
64
- pictureInPicture,
65
- fullscreen,
66
- play,
67
- seek,
68
- getVolume,
69
- setVolume,
70
- attachments,
71
- tracks,
72
- video,
73
- errors,
74
- customControls,
75
- libassWorkerUrl,
76
- wasmUrl,
77
- needsInitialInteraction,
78
- ...rest
79
- }: ChromeOptions) => {
80
- const [canvasElement, setCanvasElement] = useState<HTMLCanvasElement | undefined>()
81
- const [canvasInitialized, setCanvasInitialized] = useState(false)
82
- const [isFullscreen, setFullscreen] = useState(false)
83
- const [hidden, setHidden] = useState(false)
84
- const autoHide = useRef<number>()
85
- const [isSubtitleMenuHidden, setIsSubtitleMenuHidden] = useState(true)
86
- const [jassub, setJassub] = useState<JASSUB>()
87
- const [currentSubtitleTrack, setCurrentSubtitleTrack] = useState<number | undefined>()
88
- const subtitleTrack = useMemo(
89
- () => currentSubtitleTrack !== undefined ? tracks[currentSubtitleTrack] : undefined,
90
- [currentSubtitleTrack, currentSubtitleTrack !== undefined && tracks[currentSubtitleTrack]?.data]
91
- )
92
- const [isErrorMenuHidden, setIsErrorMenuHidden] = useState(true)
93
-
94
- const mouseMove: MouseEventHandler<HTMLDivElement> = (ev) => {
95
- setHidden(false)
96
- if (autoHide.current) clearInterval(autoHide.current)
97
- const timeout = setTimeout(() => {
98
- setHidden(true)
99
- }, 3_000) as unknown as number
100
- autoHide.current = timeout
101
- }
102
-
103
- // hide automatically after 3 seconds, in case the user doesn't move the mouse on init
104
- useEffect(() => {
105
- setTimeout(() => {
106
- setHidden(true)
107
- }, 3_000)
108
- }, [])
109
-
110
- const mouseOut: React.DOMAttributes<HTMLDivElement>['onMouseOut'] = (ev) => {
111
- const root = canvasElement?.parentElement?.parentElement
112
- if (!root?.contains(ev?.relatedTarget as Element)) {
113
- setHidden(true)
114
- return
115
- }
116
- if (ev.currentTarget.parentElement !== ev.relatedTarget && ev.relatedTarget !== null) return
117
- setHidden(true)
118
- }
119
-
120
- const togglePlay = () => {
121
- if (!isSubtitleMenuHidden) return
122
- play()
123
- }
124
-
125
- const toggleFullscreen = () => {
126
- if (!canvasElement || !jassub) return
127
- setFullscreen(value => !value)
128
- fullscreen()
129
- }
130
-
131
- useEffect(() => {
132
- if (!video.current || !canvasElement || jassub || !subtitleTrack?.data || !attachments) return
133
- const fonts = attachments.map(({ filename, data }) => [
134
- filename.toLowerCase().replaceAll('-', ' ').split('.').at(0),
135
- data
136
- ])
137
- const jassubInstance = new JASSUB({
138
- video: video.current,
139
- canvas: canvasElement,
140
- subContent: subtitleTrack.data,
141
- fonts: fonts.filter(Boolean).map(([,filename]) => filename as string),
142
- availableFonts: { ...Object.fromEntries(fonts), 'liberation sans': `${publicPath}default.woff2` },
143
- workerUrl: libassWorkerUrl, // Link to WebAssembly-based file "libassjs-worker.js",
144
- modernWasmUrl: wasmUrl
145
- })
146
- setJassub(jassubInstance)
147
- }, [canvasElement, attachments, subtitleTrack?.data])
148
-
149
- useEffect(() => {
150
- if (!tracks.length) return
151
- setCurrentSubtitleTrack(0)
152
- }, [tracks.length])
153
-
154
- useEffect(() => {
155
- if (!jassub) return
156
- if (!subtitleTrack) {
157
- jassub.freeTrack()
158
- return
159
- }
160
- jassub.setTrack(subtitleTrack.data)
161
- const parent = canvasElement?.parentElement
162
- if (!parent || canvasInitialized) return
163
- setCanvasInitialized(true)
164
- }, [jassub, subtitleTrack, canvasInitialized])
165
-
166
- const setCanvasRef: ClassAttributes<HTMLCanvasElement>['ref'] = (canvasElem) => {
167
- if (!canvasElem) return
168
- setCanvasElement(canvasElem)
169
- }
170
-
171
- return (
172
- <div {...rest} css={style} onMouseMove={mouseMove} onMouseOut={mouseOut} className={`chrome ${rest.className ?? ''} ${hidden ? 'hide' : ''}`}>
173
- <Overlay needsInitialInteraction={needsInitialInteraction} loading={loading} togglePlay={togglePlay} setCanvasRef={setCanvasRef}/>
174
- {customOverlay}
175
- <Bottom
176
- className={`bottom ${needsInitialInteraction ? 'hide' : ''}`}
177
- toggleFullscreen={toggleFullscreen}
178
- togglePlay={togglePlay}
179
- isFullscreen={isFullscreen}
180
- pictureInPicture={pictureInPicture}
181
- seek={seek}
182
- setCurrentSubtitleTrack={setCurrentSubtitleTrack}
183
- isSubtitleMenuHidden={isSubtitleMenuHidden}
184
- setIsSubtitleMenuHidden={setIsSubtitleMenuHidden}
185
- isErrorMenuHidden={isErrorMenuHidden}
186
- setIsErrorMenuHidden={setIsErrorMenuHidden}
187
- setVolume={setVolume}
188
- subtitleTrack={subtitleTrack}
189
- tracks={tracks}
190
- currentTime={currentTime}
191
- duration={duration}
192
- isPlaying={isPlaying}
193
- loadedTime={loadedTime}
194
- errors={errors}
195
- customControls={customControls}
196
- />
197
- </div>
198
- )
199
- }
@@ -1,104 +0,0 @@
1
- /// <reference types="@emotion/react/types/css-prop" />
2
- import type { ClassAttributes } from 'react'
3
-
4
- import { css } from '@emotion/react'
5
-
6
- const style = css`
7
- position: relative;
8
- display: grid;
9
- grid-column: 1;
10
- grid-row: 1;
11
- display: grid;
12
- height: 100%;
13
- width: 100%;
14
- justify-items: center;
15
- align-items: center;
16
-
17
- canvas {
18
- pointer-events: none;
19
- position: absolute;
20
- inset: 0;
21
- grid-column: 1;
22
- grid-row: 1;
23
- height: 100%;
24
- width: 100%;
25
- }
26
-
27
- .loading {
28
- grid-column: 1;
29
- grid-row: 1;
30
- }
31
- `
32
-
33
- export type OverlayOptions = {
34
- loading?: boolean
35
- togglePlay: (ev: any) => void
36
- setCanvasRef: ClassAttributes<HTMLCanvasElement>['ref'],
37
- needsInitialInteraction?: boolean
38
- }
39
-
40
- export default ({ loading, needsInitialInteraction, togglePlay, setCanvasRef }: OverlayOptions) => {
41
- return (
42
- <div css={style} onClick={togglePlay}>
43
- <canvas ref={setCanvasRef}/>
44
- {
45
- needsInitialInteraction
46
- ? (
47
- <svg
48
- xmlns="http://www.w3.org/2000/svg"
49
- width="60"
50
- height="60"
51
- viewBox="0 0 60 60"
52
- fill="black"
53
- stroke="currentColor"
54
- strokeWidth="3"
55
- strokeLinecap="round"
56
- strokeLinejoin="round"
57
- className="feather feather-play"
58
- >
59
- <polygon points="12 7 45 28 12 50 12 7"></polygon>
60
- </svg>
61
- )
62
- : (
63
- loading
64
- ? (
65
- <svg
66
- className="loading"
67
- xmlns="http://www.w3.org/2000/svg"
68
- style={{
69
- display: 'block',
70
- shapeRendering: 'auto',
71
- animationPlayState: 'running',
72
- animationDelay: '0s',
73
- }}
74
- width="100" height="100"
75
- viewBox="0 0 100 100"
76
- preserveAspectRatio="xMidYMid"
77
- >
78
- <circle
79
- cx="50"
80
- cy="50"
81
- fill="none"
82
- stroke="currentColor"
83
- strokeWidth="9"
84
- r="35"
85
- strokeDasharray="164.93361431346415 56.97787143782138"
86
- style={{ animationPlayState: 'running', animationDelay: '0s' }}>
87
- <animateTransform
88
- attributeName="transform"
89
- type="rotate"
90
- repeatCount="indefinite"
91
- dur="1s"
92
- values="0 50 50;360 50 50"
93
- keyTimes="0;1"
94
- style={{ animationPlayState: 'running', animationDelay: '0s' }}
95
- />
96
- </circle>
97
- </svg>
98
- )
99
- : null
100
- )
101
- }
102
- </div>
103
- )
104
- }
@@ -1,32 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
-
3
- const useNamespacedLocalStorage = <T extends { [key: PropertyKey]: string | boolean | number | undefined | null | object | any[] }>(namespace: string) => {
4
- const [state, setState] = useState<T>(() => {
5
- const storedValue = localStorage.getItem(namespace)
6
- return (
7
- storedValue
8
- ? JSON.parse(storedValue)
9
- : {}
10
- )
11
- })
12
-
13
- useEffect(() => {
14
- localStorage.setItem(namespace, JSON.stringify(state));
15
- }, [namespace, state])
16
-
17
- return <T2 extends keyof T, T3 extends T[T2]>(key: T2, value: T[T2]) => {
18
- useEffect(() => {
19
- setState(state => ({ ...state, [key]: value }))
20
- }, [])
21
- return [
22
- state[key],
23
- (newValue: T3 | ((oldValue: T3) => T3)) =>
24
- typeof newValue === 'function'
25
- // @ts-expect-error
26
- ? setState(state => ({ ...state, [key]: newValue(state[key]) }))
27
- : setState(state => ({ ...state, [key]: newValue }))
28
- ] as const
29
- }
30
- }
31
-
32
- export default useNamespacedLocalStorage
File without changes
File without changes