@banou/media-player 0.6.0 → 0.6.2

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 (37) hide show
  1. package/README.md +6 -6
  2. package/package.json +51 -51
  3. package/src/assets/picture-in-picture.svg +5 -5
  4. package/src/components/chrome.tsx +95 -95
  5. package/src/components/control-bar.tsx +333 -333
  6. package/src/components/overlay.tsx +91 -91
  7. package/src/components/playback-slider.tsx +174 -174
  8. package/src/components/progress-bar.tsx +251 -251
  9. package/src/components/settings.tsx +321 -321
  10. package/src/components/sound.tsx +100 -100
  11. package/src/components/tooltip-display.tsx +83 -83
  12. package/src/components/volume-slider.tsx +156 -156
  13. package/src/index.tsx +195 -195
  14. package/src/main.tsx +169 -169
  15. package/src/state-machines/data-source.ts +84 -84
  16. package/src/state-machines/index.ts +5 -5
  17. package/src/state-machines/media-properties.ts +82 -82
  18. package/src/state-machines/media-source.ts +129 -129
  19. package/src/state-machines/media.ts +255 -255
  20. package/src/state-machines/subtitles.ts +285 -285
  21. package/src/state-machines/thumbnails.ts +123 -123
  22. package/src/state-machines/utils.ts +94 -94
  23. package/src/utils/actor-utils.ts +19 -19
  24. package/src/utils/colors.ts +8 -8
  25. package/src/utils/context.ts +23 -23
  26. package/src/utils/fonts.ts +159 -159
  27. package/src/utils/index.ts +229 -229
  28. package/src/utils/languages.ts +262 -262
  29. package/src/utils/mp4box.ts +74 -74
  30. package/src/utils/time.ts +15 -15
  31. package/src/utils/use-local-storage.ts +30 -30
  32. package/src/utils/use-scrub.ts +40 -40
  33. package/src/utils/volume-utils.ts +39 -39
  34. package/src/utils/window-height.ts +19 -19
  35. package/src/vite-env.d.ts +1 -1
  36. package/tsconfig.json +28 -28
  37. package/tsconfig.node.json +9 -9
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- ## Media Player
2
-
3
- A player that somehow manages to playback MKV files
4
-
5
-
6
- Todo: add support for multi audio tracks
1
+ ## Media Player
2
+
3
+ A player that somehow manages to playback MKV files
4
+
5
+
6
+ Todo: add support for multi audio tracks
package/package.json CHANGED
@@ -1,51 +1,51 @@
1
- {
2
- "name": "@banou/media-player",
3
- "version": "0.6.0",
4
- "description": "",
5
- "type": "module",
6
- "main": "build/index.js",
7
- "files": [
8
- "build",
9
- "tsconfig.json",
10
- "tsconfig.node.json",
11
- "src"
12
- ],
13
- "scripts": {
14
- "dev": "vite --port 4560",
15
- "build-dev": "vite build --watch",
16
- "build": "vite build && npm run types",
17
- "build-for-dev": "vite build && npm run copy-dependencies && npm run types",
18
- "copy-dependencies": "npm run copy-libass && npm run copy-worker && npm run copy-worker-wasm",
19
- "copy-worker": "shx cp node_modules/libav-wasm/build/worker.js build/libav.js",
20
- "copy-worker-wasm": "shx cp node_modules/libav-wasm/build/libav.wasm build/libav.wasm",
21
- "copy-libass": "copyfiles -u 3 ./node_modules/jassub/dist/* build",
22
- "types": "tsc"
23
- },
24
- "author": "Banou26",
25
- "devDependencies": {
26
- "@types/node": "^18.11.18",
27
- "@types/react": "^18.0.27",
28
- "@types/react-dom": "^18.0.10",
29
- "@vitejs/plugin-react": "^4.3.4",
30
- "concurrently": "^7.6.0",
31
- "copyfiles": "^2.4.1",
32
- "mime": "^3.0.0",
33
- "shx": "^0.3.4",
34
- "typescript": "^5.8.2",
35
- "vite": "^6.2.1"
36
- },
37
- "dependencies": {
38
- "@emotion/react": "^11.14.0",
39
- "@xstate/react": "^5.0.1",
40
- "ass-compiler": "^0.1.15",
41
- "jassub": "^1.7.18",
42
- "libav-wasm": "^0.6.0",
43
- "osra": "^0.1.2",
44
- "p-queue": "^7.3.4",
45
- "react": "^19.0.0",
46
- "react-dom": "^19.0.0",
47
- "react-feather": "^2.0.10",
48
- "react-tooltip": "^5.28.0",
49
- "xstate": "^5.19.1"
50
- }
51
- }
1
+ {
2
+ "name": "@banou/media-player",
3
+ "version": "0.6.2",
4
+ "description": "",
5
+ "type": "module",
6
+ "main": "build/index.js",
7
+ "files": [
8
+ "build",
9
+ "tsconfig.json",
10
+ "tsconfig.node.json",
11
+ "src"
12
+ ],
13
+ "scripts": {
14
+ "dev": "vite --port 4560",
15
+ "build-dev": "vite build --watch",
16
+ "build": "vite build && npm run types",
17
+ "build-for-dev": "vite build && npm run copy-dependencies && npm run types",
18
+ "copy-dependencies": "npm run copy-libass && npm run copy-worker && npm run copy-worker-wasm",
19
+ "copy-worker": "shx cp node_modules/libav-wasm/build/worker.js build/libav.js",
20
+ "copy-worker-wasm": "shx cp node_modules/libav-wasm/build/libav.wasm build/libav.wasm",
21
+ "copy-libass": "copyfiles -u 3 ./node_modules/jassub/dist/* build",
22
+ "types": "tsc"
23
+ },
24
+ "author": "Banou26",
25
+ "devDependencies": {
26
+ "@types/node": "^18.11.18",
27
+ "@types/react": "^18.0.27",
28
+ "@types/react-dom": "^18.0.10",
29
+ "@vitejs/plugin-react": "^4.3.4",
30
+ "concurrently": "^7.6.0",
31
+ "copyfiles": "^2.4.1",
32
+ "mime": "^3.0.0",
33
+ "shx": "^0.3.4",
34
+ "typescript": "^5.8.2",
35
+ "vite": "^6.2.1"
36
+ },
37
+ "dependencies": {
38
+ "@emotion/react": "^11.14.0",
39
+ "@xstate/react": "^5.0.1",
40
+ "ass-compiler": "^0.1.15",
41
+ "jassub": "^1.7.18",
42
+ "libav-wasm": "^0.6.2",
43
+ "osra": "^0.1.2",
44
+ "p-queue": "^7.3.4",
45
+ "react": "^19.0.0",
46
+ "react-dom": "^19.0.0",
47
+ "react-feather": "^2.0.10",
48
+ "react-tooltip": "^5.28.0",
49
+ "xstate": "^5.19.1"
50
+ }
51
+ }
@@ -1,5 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-picture-in-picture">
2
- <path stroke="none" d="M0 0h24v24H0z" fill="none" />
3
- <path d="M11 19h-6a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v4" />
4
- <path d="M14 14m0 1a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v3a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z" />
5
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-picture-in-picture">
2
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
3
+ <path d="M11 19h-6a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v4" />
4
+ <path d="M14 14m0 1a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v3a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z" />
5
+ </svg>
@@ -1,95 +1,95 @@
1
- /// <reference types="@emotion/react/types/css-prop" />
2
- import { MouseEventHandler, ReactNode, useContext, useRef, type HTMLAttributes } from 'react'
3
-
4
- import { css } from '@emotion/react'
5
-
6
- import { MediaMachineContext } from '../state-machines'
7
- import { MediaPlayerContext } from '../utils/context'
8
- import { togglePlay } from '../utils/actor-utils'
9
- import { Overlay } from './overlay'
10
- import ControlBar from './control-bar'
11
-
12
- const style = css`
13
- position: relative;
14
- background-color: black;
15
- display: flex;
16
- justify-content: center;
17
- align-items: center;
18
- height: 100%;
19
- width: 100%;
20
-
21
- & > div:not(:last-of-type) {
22
- position: absolute;
23
- z-index: 2;
24
- }
25
-
26
- canvas {
27
- height: 100%;
28
- width: 100%;
29
- pointer-events: none;
30
- position: absolute;
31
- z-index: 1;
32
- }
33
-
34
- .video, video {
35
- height: 100%;
36
- width: 100%;
37
- background-color: black;
38
- object-fit: contain;
39
- }
40
-
41
- &.hide {
42
- cursor: none;
43
- }
44
- `
45
-
46
- export type ChromeOptions = {
47
- mediaInformation?: ReactNode
48
- loadingInformation?: ReactNode
49
- } & HTMLAttributes<HTMLDivElement>
50
-
51
- export const Chrome = ({ children, mediaInformation, loadingInformation }: ChromeOptions) => {
52
- const mediaActor = MediaMachineContext.useActorRef()
53
- const mediaPlayerContext = useContext(MediaPlayerContext)
54
- const isPaused = MediaMachineContext.useSelector((state) => state.context.media.paused)
55
- const currentTime = MediaMachineContext.useSelector((state) => state.context.media.currentTime)
56
- const duration = MediaMachineContext.useSelector((state) => state.context.media.duration)
57
-
58
- const autoHide = useRef<number>()
59
- const containerRef = useRef<HTMLDivElement>(null)
60
-
61
- const mouseMove: MouseEventHandler<HTMLDivElement> = (ev) => {
62
- mediaPlayerContext.update(({ ...mediaPlayerContext, hideUI: false }))
63
- if (autoHide.current) clearInterval(autoHide.current)
64
- const timeout = setTimeout(() => {
65
- mediaPlayerContext.update(({ ...mediaPlayerContext, hideUI: true }))
66
- }, 3_000) as unknown as number
67
- autoHide.current = timeout
68
- }
69
-
70
- const mouseOut: React.DOMAttributes<HTMLDivElement>['onMouseOut'] = (ev) => {
71
- if (ev.currentTarget.parentElement !== ev.relatedTarget && ev.relatedTarget !== null) return
72
- mediaPlayerContext.update(({ ...mediaPlayerContext, hideUI: true }))
73
- }
74
-
75
- return (
76
- <div
77
- css={style}
78
- ref={containerRef}
79
- onMouseMove={mouseMove}
80
- onMouseOut={mouseOut}
81
- className={mediaPlayerContext.hideUI ? 'hide' : ''}
82
- >
83
- <Overlay loadingInformation={loadingInformation}/>
84
- <ControlBar mediaInformation={mediaInformation} containerRef={containerRef}/>
85
- <div
86
- className='video'
87
- onClick={() => togglePlay(mediaActor, isPaused, duration, currentTime)}
88
- >
89
- {children}
90
- </div>
91
- </div>
92
- )
93
- }
94
-
95
- export default Chrome
1
+ /// <reference types="@emotion/react/types/css-prop" />
2
+ import { MouseEventHandler, ReactNode, useContext, useRef, type HTMLAttributes } from 'react'
3
+
4
+ import { css } from '@emotion/react'
5
+
6
+ import { MediaMachineContext } from '../state-machines'
7
+ import { MediaPlayerContext } from '../utils/context'
8
+ import { togglePlay } from '../utils/actor-utils'
9
+ import { Overlay } from './overlay'
10
+ import ControlBar from './control-bar'
11
+
12
+ const style = css`
13
+ position: relative;
14
+ background-color: black;
15
+ display: flex;
16
+ justify-content: center;
17
+ align-items: center;
18
+ height: 100%;
19
+ width: 100%;
20
+
21
+ & > div:not(:last-of-type) {
22
+ position: absolute;
23
+ z-index: 2;
24
+ }
25
+
26
+ canvas {
27
+ height: 100%;
28
+ width: 100%;
29
+ pointer-events: none;
30
+ position: absolute;
31
+ z-index: 1;
32
+ }
33
+
34
+ .video, video {
35
+ height: 100%;
36
+ width: 100%;
37
+ background-color: black;
38
+ object-fit: contain;
39
+ }
40
+
41
+ &.hide {
42
+ cursor: none;
43
+ }
44
+ `
45
+
46
+ export type ChromeOptions = {
47
+ mediaInformation?: ReactNode
48
+ loadingInformation?: ReactNode
49
+ } & HTMLAttributes<HTMLDivElement>
50
+
51
+ export const Chrome = ({ children, mediaInformation, loadingInformation }: ChromeOptions) => {
52
+ const mediaActor = MediaMachineContext.useActorRef()
53
+ const mediaPlayerContext = useContext(MediaPlayerContext)
54
+ const isPaused = MediaMachineContext.useSelector((state) => state.context.media.paused)
55
+ const currentTime = MediaMachineContext.useSelector((state) => state.context.media.currentTime)
56
+ const duration = MediaMachineContext.useSelector((state) => state.context.media.duration)
57
+
58
+ const autoHide = useRef<number>()
59
+ const containerRef = useRef<HTMLDivElement>(null)
60
+
61
+ const mouseMove: MouseEventHandler<HTMLDivElement> = (ev) => {
62
+ mediaPlayerContext.update(({ ...mediaPlayerContext, hideUI: false }))
63
+ if (autoHide.current) clearInterval(autoHide.current)
64
+ const timeout = setTimeout(() => {
65
+ mediaPlayerContext.update(({ ...mediaPlayerContext, hideUI: true }))
66
+ }, 3_000) as unknown as number
67
+ autoHide.current = timeout
68
+ }
69
+
70
+ const mouseOut: React.DOMAttributes<HTMLDivElement>['onMouseOut'] = (ev) => {
71
+ if (ev.currentTarget.parentElement !== ev.relatedTarget && ev.relatedTarget !== null) return
72
+ mediaPlayerContext.update(({ ...mediaPlayerContext, hideUI: true }))
73
+ }
74
+
75
+ return (
76
+ <div
77
+ css={style}
78
+ ref={containerRef}
79
+ onMouseMove={mouseMove}
80
+ onMouseOut={mouseOut}
81
+ className={mediaPlayerContext.hideUI ? 'hide' : ''}
82
+ >
83
+ <Overlay loadingInformation={loadingInformation}/>
84
+ <ControlBar mediaInformation={mediaInformation} containerRef={containerRef}/>
85
+ <div
86
+ className='video'
87
+ onClick={() => togglePlay(mediaActor, isPaused, duration, currentTime)}
88
+ >
89
+ {children}
90
+ </div>
91
+ </div>
92
+ )
93
+ }
94
+
95
+ export default Chrome