@banou/media-player 0.8.0 → 0.8.1

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.
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ var ee = {
18
18
  selectAudioTrack: () => {},
19
19
  hideUI: !1,
20
20
  setHideUI: () => {},
21
- togglePictureInPicture: () => {},
21
+ togglePictureInPicture: null,
22
22
  playbackError: null,
23
23
  ready: !1,
24
24
  setSourceState: () => {}
@@ -191,7 +191,7 @@ var ee = {
191
191
  }, [m]), u;
192
192
  }, B = (e, t) => {
193
193
  let n = P(), r = c(null);
194
- return o(() => {
194
+ o(() => {
195
195
  if (!e || !t) return;
196
196
  let a = i({
197
197
  video: e,
@@ -205,11 +205,13 @@ var ee = {
205
205
  e,
206
206
  t,
207
207
  n
208
- ]), a(() => {
208
+ ]);
209
+ let s = a(() => {
209
210
  r.current?.toggle().catch((e) => {
210
211
  console.warn("picture in picture was refused", e);
211
212
  });
212
213
  }, []);
214
+ return e && t ? s : null;
213
215
  }, V = {
214
216
  headings: {
215
217
  large: "\n font-weight: 600;\n font-size: calc(2.8 * var(--mp-unit));\n line-height: calc(3.4 * var(--mp-unit));\n @media (min-width: 960px) {\n font-size: calc(3.4 * var(--mp-unit));\n line-height: calc(4.1 * var(--mp-unit));\n }\n ",
@@ -1384,7 +1386,7 @@ position: relative;
1384
1386
  className: "right",
1385
1387
  children: [
1386
1388
  /* @__PURE__ */ v(ve, {}),
1387
- /* @__PURE__ */ v(q, {
1389
+ c ? /* @__PURE__ */ v(q, {
1388
1390
  id: "picture-in-picture",
1389
1391
  text: /* @__PURE__ */ v("button", {
1390
1392
  className: "picture-in-picture",
@@ -1393,7 +1395,7 @@ position: relative;
1393
1395
  children: /* @__PURE__ */ v("img", { src: me })
1394
1396
  }),
1395
1397
  toolTipText: /* @__PURE__ */ v("span", { children: "Picture in picture" })
1396
- }),
1398
+ }) : null,
1397
1399
  /* @__PURE__ */ v(q, {
1398
1400
  id: "full-screen",
1399
1401
  tooltipPlace: "top-end",
@@ -1,2 +1,2 @@
1
1
  /** Picture in picture with the subtitles composited in. */
2
- export declare const usePictureInPicture: (video: HTMLVideoElement | null, canvas: HTMLCanvasElement | null) => () => void;
2
+ export declare const usePictureInPicture: (video: HTMLVideoElement | null, canvas: HTMLCanvasElement | null) => (() => void) | null;
@@ -13,7 +13,7 @@ export declare const Player: import("@videojs/react").CreatePlayerResult<import(
13
13
  selectAudioTrack: (id: string | number) => void;
14
14
  hideUI: boolean;
15
15
  setHideUI: (hide: boolean) => void;
16
- togglePictureInPicture: () => void;
16
+ togglePictureInPicture: (() => void) | null;
17
17
  playbackError: unknown;
18
18
  ready: boolean;
19
19
  setSourceState: (partial: Partial<import("./source-feature").SourceState>) => void;
@@ -50,8 +50,16 @@ export type SourceState = {
50
50
  /** Chrome auto-hide. True means the controls, title and cursor are hidden. */
51
51
  hideUI: boolean;
52
52
  setHideUI: (hide: boolean) => void;
53
- /** Owned here, not by `pip`: that watches the media element, and the window holds a mirror. */
54
- togglePictureInPicture: () => void;
53
+ /**
54
+ * Owned here, not by `pip`: that watches the media element, and the window holds a mirror.
55
+ *
56
+ * null means the control is not offered at all. Locally that is "no element yet". For a media the
57
+ * player does not own it means the source cannot do it, and the difference matters: the compositing
58
+ * this does needs a local element to draw, and even a source that forwards the request cannot
59
+ * report the resulting STATE back, since `document.pictureInPictureElement` is never a proxy. A
60
+ * button that toggles nothing and never lights up is worse than no button.
61
+ */
62
+ togglePictureInPicture: (() => void) | null;
55
63
  /** Set when the pipeline fails. Cleared when it recovers. */
56
64
  playbackError: unknown;
57
65
  /** Whether the engine has produced its first media segment. */
@@ -89,8 +97,16 @@ export declare const sourceFeature: import("@videojs/react").PlayerFeature<{
89
97
  /** Chrome auto-hide. True means the controls, title and cursor are hidden. */
90
98
  hideUI: boolean;
91
99
  setHideUI: (hide: boolean) => void;
92
- /** Owned here, not by `pip`: that watches the media element, and the window holds a mirror. */
93
- togglePictureInPicture: () => void;
100
+ /**
101
+ * Owned here, not by `pip`: that watches the media element, and the window holds a mirror.
102
+ *
103
+ * null means the control is not offered at all. Locally that is "no element yet". For a media the
104
+ * player does not own it means the source cannot do it, and the difference matters: the compositing
105
+ * this does needs a local element to draw, and even a source that forwards the request cannot
106
+ * report the resulting STATE back, since `document.pictureInPictureElement` is never a proxy. A
107
+ * button that toggles nothing and never lights up is worse than no button.
108
+ */
109
+ togglePictureInPicture: (() => void) | null;
94
110
  /** Set when the pipeline fails. Cleared when it recovers. */
95
111
  playbackError: unknown;
96
112
  /** Whether the engine has produced its first media segment. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@banou/media-player",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "A video player for containers and codecs the browser cannot play natively, remuxed on the fly",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -259,23 +259,27 @@ export const ControlBar = () => {
259
259
  </div>
260
260
  <div className='right'>
261
261
  <SettingsAction />
262
- <TooltipDisplay
263
- id='picture-in-picture'
264
- text={
265
- <button
266
- className='picture-in-picture'
267
- type='button'
268
- onClick={togglePictureInPicture}
269
- >
270
- <img src={pictureInPicture} />
271
- </button>
272
- }
273
- toolTipText={
274
- <span>
275
- Picture in picture
276
- </span>
277
- }
278
- />
262
+ {togglePictureInPicture
263
+ ? (
264
+ <TooltipDisplay
265
+ id='picture-in-picture'
266
+ text={
267
+ <button
268
+ className='picture-in-picture'
269
+ type='button'
270
+ onClick={togglePictureInPicture}
271
+ >
272
+ <img src={pictureInPicture} />
273
+ </button>
274
+ }
275
+ toolTipText={
276
+ <span>
277
+ Picture in picture
278
+ </span>
279
+ }
280
+ />
281
+ )
282
+ : null}
279
283
  <TooltipDisplay
280
284
  id='full-screen'
281
285
  tooltipPlace='top-end'
@@ -28,9 +28,13 @@ export const usePictureInPicture = (
28
28
  }
29
29
  }, [video, canvas, player])
30
30
 
31
- return useCallback(() => {
31
+ const toggle = useCallback(() => {
32
32
  void controller.current?.toggle().catch((error) => {
33
33
  console.warn('picture in picture was refused', error)
34
34
  })
35
35
  }, [])
36
+
37
+ // null rather than a dead callback: the chrome hides the control instead of offering one that
38
+ // cannot work, and there is nothing to composite without both an element and a canvas.
39
+ return video && canvas ? toggle : null
36
40
  }
@@ -60,8 +60,16 @@ export type SourceState = {
60
60
  hideUI: boolean
61
61
  setHideUI: (hide: boolean) => void
62
62
 
63
- /** Owned here, not by `pip`: that watches the media element, and the window holds a mirror. */
64
- togglePictureInPicture: () => void
63
+ /**
64
+ * Owned here, not by `pip`: that watches the media element, and the window holds a mirror.
65
+ *
66
+ * null means the control is not offered at all. Locally that is "no element yet". For a media the
67
+ * player does not own it means the source cannot do it, and the difference matters: the compositing
68
+ * this does needs a local element to draw, and even a source that forwards the request cannot
69
+ * report the resulting STATE back, since `document.pictureInPictureElement` is never a proxy. A
70
+ * button that toggles nothing and never lights up is worse than no button.
71
+ */
72
+ togglePictureInPicture: (() => void) | null
65
73
 
66
74
  /** Set when the pipeline fails. Cleared when it recovers. */
67
75
  playbackError: unknown
@@ -89,7 +97,7 @@ const initialState: SourceState = {
89
97
  selectAudioTrack: () => {},
90
98
  hideUI: false,
91
99
  setHideUI: () => {},
92
- togglePictureInPicture: () => {},
100
+ togglePictureInPicture: null,
93
101
  playbackError: null,
94
102
  ready: false,
95
103
  setSourceState: () => {},