@ericchen1990/pano-view 3.4.0 → 3.4.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.
- package/README.md +9 -5
- package/README.zh-CN.md +2 -2
- package/dist/index.cjs +78 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +79 -48
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -581,10 +581,12 @@ export function VideoExample() {
|
|
|
581
581
|
```
|
|
582
582
|
|
|
583
583
|
`muted` defaults to `true` so `autoPlay` has a chance under browser autoplay
|
|
584
|
-
rules. `playsInline` also defaults to true and writes
|
|
585
|
-
`webkit-playsinline`,
|
|
586
|
-
|
|
587
|
-
|
|
584
|
+
rules. `playsInline` also defaults to true and writes `playsinline`,
|
|
585
|
+
`webkit-playsinline`, and the X5 `h5-page` attributes, so the video stays in
|
|
586
|
+
the page on iPhone Safari and in WeChat, QQ, and UC. Picture-in-picture and
|
|
587
|
+
remote playback stay disabled so the element can keep feeding the sphere
|
|
588
|
+
texture. The element is mounted inside the viewer at 1×1px. Unmuted playback
|
|
589
|
+
still needs a user gesture; `onPlaybackStateChange` receives `"blocked"` when `play()` is
|
|
588
590
|
rejected. Remote videos and VTT files that are not same-origin should set
|
|
589
591
|
`crossOrigin` (usually `"anonymous"`). For mobile delivery, provide an H.264 +
|
|
590
592
|
AAC MP4 fallback, poster, CORS, and Range support.
|
|
@@ -1641,7 +1643,9 @@ handler, `onEnded`, or playback error.
|
|
|
1641
1643
|
`VideoHotspot` uses an `HTMLVideoElement` and `VideoTexture`. Its `playing`
|
|
1642
1644
|
prop is likewise controlled: toggle it from your click handler or application
|
|
1643
1645
|
state. On source change or unmount, the element is paused and its texture is
|
|
1644
|
-
released. `playsInline` defaults to `true
|
|
1646
|
+
released. `playsInline` defaults to `true` and uses the same inline-playback
|
|
1647
|
+
attributes as `PanoVideo`. The element is mounted inside the viewer, hidden,
|
|
1648
|
+
so mobile browsers keep it in the page. `muted` defaults to `true`, `loop` to
|
|
1645
1649
|
`false`, and `preload` to `"metadata"`.
|
|
1646
1650
|
|
|
1647
1651
|
```tsx
|
package/README.zh-CN.md
CHANGED
|
@@ -538,7 +538,7 @@ export function VideoExample() {
|
|
|
538
538
|
}
|
|
539
539
|
```
|
|
540
540
|
|
|
541
|
-
`muted` 默认为 `true
|
|
541
|
+
`muted` 默认为 `true`,以便在浏览器自动播放规则下有机会自动播放。`playsInline` 也默认开启,并写入 `playsinline`、`webkit-playsinline` 以及 X5 的 `h5-page` 属性,让视频在 iPhone Safari、微信、QQ 和 UC 中留在页面内。画中画和远程播放保持关闭,以便该元素持续作为球面纹理。元素会以 1×1 像素挂在查看器内。非静音播放仍需要用户手势;`play()` 被拒绝时 `onPlaybackStateChange` 会收到 `"blocked"`。非同源的远程视频与 VTT 文件应设置 `crossOrigin`(通常为 `"anonymous"`)。移动端请提供 H.264 + AAC 的 MP4 备选源、poster、CORS 与 Range 支持。
|
|
542
542
|
|
|
543
543
|
## Tile
|
|
544
544
|
|
|
@@ -1374,7 +1374,7 @@ import { SequenceHotspot } from "@ericchen1990/pano-view";
|
|
|
1374
1374
|
|
|
1375
1375
|
## VideoHotspot
|
|
1376
1376
|
|
|
1377
|
-
`VideoHotspot` 使用 `HTMLVideoElement` 与 `VideoTexture`。其 `playing` prop 同样受控:在点击处理或应用状态中切换。源变更或卸载时元素暂停并释放纹理。`playsInline` 默认 `true
|
|
1377
|
+
`VideoHotspot` 使用 `HTMLVideoElement` 与 `VideoTexture`。其 `playing` prop 同样受控:在点击处理或应用状态中切换。源变更或卸载时元素暂停并释放纹理。`playsInline` 默认 `true`,并使用与 `PanoVideo` 相同的内联播放属性。元素会隐藏挂在查看器内,以便移动端浏览器把它留在页面中。`muted` 默认 `true`,`loop` 默认 `false`,`preload` 默认 `"metadata"`。
|
|
1378
1378
|
|
|
1379
1379
|
```tsx
|
|
1380
1380
|
import { VideoHotspot } from "@ericchen1990/pano-view";
|
package/dist/index.cjs
CHANGED
|
@@ -3446,7 +3446,9 @@ function KeyboardControls({
|
|
|
3446
3446
|
return;
|
|
3447
3447
|
}
|
|
3448
3448
|
const previousTabIndex = element.getAttribute("tabindex");
|
|
3449
|
+
const previousOutline = element.style.outline;
|
|
3449
3450
|
element.tabIndex = 0;
|
|
3451
|
+
element.style.outline = "none";
|
|
3450
3452
|
const syncKeyboardActive = () => {
|
|
3451
3453
|
let continuous = false;
|
|
3452
3454
|
for (const action of pressedRef.current) {
|
|
@@ -3530,6 +3532,7 @@ function KeyboardControls({
|
|
|
3530
3532
|
} else {
|
|
3531
3533
|
element.setAttribute("tabindex", previousTabIndex);
|
|
3532
3534
|
}
|
|
3535
|
+
element.style.outline = previousOutline;
|
|
3533
3536
|
clearPressed();
|
|
3534
3537
|
};
|
|
3535
3538
|
}, [controlsRef, enabled, gl, keyMap]);
|
|
@@ -9093,6 +9096,56 @@ function useWebVRPointerLock(enabled, element) {
|
|
|
9093
9096
|
// src/webvr/wakelock.ts
|
|
9094
9097
|
var import_react33 = require("react");
|
|
9095
9098
|
|
|
9099
|
+
// src/video/inline-playback.ts
|
|
9100
|
+
var INLINE_VIDEO_ATTRIBUTES = [
|
|
9101
|
+
["playsinline", "true"],
|
|
9102
|
+
["webkit-playsinline", "true"],
|
|
9103
|
+
["x5-playsinline", "true"],
|
|
9104
|
+
["x5-video-player-type", "h5-page"],
|
|
9105
|
+
["x5-video-player-fullscreen", "false"]
|
|
9106
|
+
];
|
|
9107
|
+
function applyInlineVideoPlayback(video, inline) {
|
|
9108
|
+
video.controls = false;
|
|
9109
|
+
video.playsInline = inline;
|
|
9110
|
+
video.disablePictureInPicture = true;
|
|
9111
|
+
video.disableRemotePlayback = true;
|
|
9112
|
+
video.setAttribute("disablepictureinpicture", "");
|
|
9113
|
+
video.setAttribute("disableremoteplayback", "");
|
|
9114
|
+
video.setAttribute("x-webkit-airplay", "deny");
|
|
9115
|
+
video.setAttribute(
|
|
9116
|
+
"controlsList",
|
|
9117
|
+
"nodownload nofullscreen noremoteplayback"
|
|
9118
|
+
);
|
|
9119
|
+
if (inline) {
|
|
9120
|
+
for (const [name, value] of INLINE_VIDEO_ATTRIBUTES) {
|
|
9121
|
+
video.setAttribute(name, value);
|
|
9122
|
+
}
|
|
9123
|
+
return;
|
|
9124
|
+
}
|
|
9125
|
+
for (const [name] of INLINE_VIDEO_ATTRIBUTES) {
|
|
9126
|
+
video.removeAttribute(name);
|
|
9127
|
+
}
|
|
9128
|
+
}
|
|
9129
|
+
function mountTextureVideo(video, canvas) {
|
|
9130
|
+
const parent = canvas.closest("[data-pano-viewer]") ?? canvas.parentElement;
|
|
9131
|
+
if (!parent) {
|
|
9132
|
+
return;
|
|
9133
|
+
}
|
|
9134
|
+
video.tabIndex = -1;
|
|
9135
|
+
video.setAttribute("aria-hidden", "true");
|
|
9136
|
+
video.setAttribute("data-pano-texture-video", "");
|
|
9137
|
+
video.style.position = "absolute";
|
|
9138
|
+
video.style.top = "0";
|
|
9139
|
+
video.style.left = "0";
|
|
9140
|
+
video.style.width = "1px";
|
|
9141
|
+
video.style.height = "1px";
|
|
9142
|
+
video.style.opacity = "0";
|
|
9143
|
+
video.style.pointerEvents = "none";
|
|
9144
|
+
if (video.parentElement !== parent) {
|
|
9145
|
+
parent.appendChild(video);
|
|
9146
|
+
}
|
|
9147
|
+
}
|
|
9148
|
+
|
|
9096
9149
|
// src/webvr/wakelock-fallback.ts
|
|
9097
9150
|
var WEBVR_WAKELOCK_FALLBACK_VIDEO_BASE64 = "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";
|
|
9098
9151
|
|
|
@@ -9118,17 +9171,12 @@ function decodeBase64(value) {
|
|
|
9118
9171
|
function createFallbackVideo() {
|
|
9119
9172
|
const video = document.createElement("video");
|
|
9120
9173
|
video.autoplay = true;
|
|
9121
|
-
video.controls = false;
|
|
9122
9174
|
video.defaultMuted = true;
|
|
9123
9175
|
video.loop = true;
|
|
9124
9176
|
video.muted = true;
|
|
9125
|
-
video.playsInline = true;
|
|
9126
9177
|
video.tabIndex = -1;
|
|
9127
9178
|
video.ariaHidden = "true";
|
|
9128
|
-
video
|
|
9129
|
-
video.setAttribute("playsinline", "");
|
|
9130
|
-
video.setAttribute("webkit-playsinline", "");
|
|
9131
|
-
video.setAttribute("disablepictureinpicture", "");
|
|
9179
|
+
applyInlineVideoPlayback(video, true);
|
|
9132
9180
|
video.style.cssText = "pointer-events:none;position:fixed;bottom:0;left:0;width:1px;height:1px;opacity:0;";
|
|
9133
9181
|
const src = URL.createObjectURL(
|
|
9134
9182
|
new Blob([decodeBase64(WEBVR_WAKELOCK_FALLBACK_VIDEO_BASE64)], {
|
|
@@ -11063,7 +11111,6 @@ function PanoVideo({
|
|
|
11063
11111
|
usePanoMediaActivationIntent(autoPlay);
|
|
11064
11112
|
const gl = (0, import_fiber18.useThree)((state) => state.gl);
|
|
11065
11113
|
const host = (0, import_react42.useContext)(PanoVideoHostContext);
|
|
11066
|
-
const overlay = (0, import_react42.useContext)(PanoChromeOverlayContext);
|
|
11067
11114
|
const variants = (0, import_react42.useMemo)(
|
|
11068
11115
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
11069
11116
|
[poster, src, variantsProp]
|
|
@@ -11141,9 +11188,7 @@ function PanoVideo({
|
|
|
11141
11188
|
}
|
|
11142
11189
|
const video = document.createElement("video");
|
|
11143
11190
|
video.muted = true;
|
|
11144
|
-
video
|
|
11145
|
-
video.setAttribute("playsinline", "true");
|
|
11146
|
-
video.setAttribute("webkit-playsinline", "true");
|
|
11191
|
+
applyInlineVideoPlayback(video, true);
|
|
11147
11192
|
video.preload = "metadata";
|
|
11148
11193
|
const texture = new import_three16.VideoTexture(video);
|
|
11149
11194
|
applyEquirectangularLayout(texture, 1);
|
|
@@ -11173,22 +11218,15 @@ function PanoVideo({
|
|
|
11173
11218
|
}
|
|
11174
11219
|
resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
11175
11220
|
}, [gl, resource]);
|
|
11176
|
-
(0, import_react42.
|
|
11177
|
-
if (!resource
|
|
11221
|
+
(0, import_react42.useLayoutEffect)(() => {
|
|
11222
|
+
if (!resource) {
|
|
11178
11223
|
return;
|
|
11179
11224
|
}
|
|
11180
|
-
|
|
11181
|
-
video.setAttribute("data-pano-video", "");
|
|
11182
|
-
video.style.position = "absolute";
|
|
11183
|
-
video.style.width = "1px";
|
|
11184
|
-
video.style.height = "1px";
|
|
11185
|
-
video.style.opacity = "0";
|
|
11186
|
-
video.style.pointerEvents = "none";
|
|
11187
|
-
overlay.overlayElement.appendChild(video);
|
|
11225
|
+
mountTextureVideo(resource.video, gl.domElement);
|
|
11188
11226
|
return () => {
|
|
11189
|
-
video.remove();
|
|
11227
|
+
resource.video.remove();
|
|
11190
11228
|
};
|
|
11191
|
-
}, [
|
|
11229
|
+
}, [gl, resource]);
|
|
11192
11230
|
const resolvedVariantId = resolvePanoVideoVariantId(variants, variantId);
|
|
11193
11231
|
const activeVariant = variants.find((variant) => variant.id === resolvedVariantId) ?? variants[0];
|
|
11194
11232
|
const mediaKey = activeVariant ? `${activeVariant.id}:${activeVariant.sources.map((source) => source.src).join("|")}:${tracks.map((track) => `${panoVideoTrackId(track)}:${track.src}`).join("|")}:${crossOrigin ?? ""}` : "";
|
|
@@ -11478,7 +11516,7 @@ function PanoVideo({
|
|
|
11478
11516
|
}
|
|
11479
11517
|
};
|
|
11480
11518
|
}, [emitSnapshot, resource]);
|
|
11481
|
-
(0, import_react42.
|
|
11519
|
+
(0, import_react42.useLayoutEffect)(() => {
|
|
11482
11520
|
if (!resource) {
|
|
11483
11521
|
return;
|
|
11484
11522
|
}
|
|
@@ -11488,14 +11526,7 @@ function PanoVideo({
|
|
|
11488
11526
|
if (mediaCapabilitiesRef.current.volumeAdjustable) {
|
|
11489
11527
|
video.volume = clampVolume(volume);
|
|
11490
11528
|
}
|
|
11491
|
-
video
|
|
11492
|
-
if (playsInline) {
|
|
11493
|
-
video.setAttribute("playsinline", "true");
|
|
11494
|
-
video.setAttribute("webkit-playsinline", "true");
|
|
11495
|
-
} else {
|
|
11496
|
-
video.removeAttribute("playsinline");
|
|
11497
|
-
video.removeAttribute("webkit-playsinline");
|
|
11498
|
-
}
|
|
11529
|
+
applyInlineVideoPlayback(video, playsInline);
|
|
11499
11530
|
video.preload = preload;
|
|
11500
11531
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
11501
11532
|
(0, import_react42.useEffect)(() => {
|
|
@@ -15862,6 +15893,7 @@ function useVideoResource({
|
|
|
15862
15893
|
poster,
|
|
15863
15894
|
src
|
|
15864
15895
|
}) {
|
|
15896
|
+
const gl = (0, import_fiber29.useThree)((state) => state.gl);
|
|
15865
15897
|
const [resource, setResource] = (0, import_react57.useState)(null);
|
|
15866
15898
|
const onEndedRef = (0, import_react57.useRef)(onEnded);
|
|
15867
15899
|
const onErrorRef = (0, import_react57.useRef)(onError);
|
|
@@ -15879,12 +15911,7 @@ function useVideoResource({
|
|
|
15879
15911
|
if (crossOrigin !== void 0) {
|
|
15880
15912
|
video.crossOrigin = crossOrigin;
|
|
15881
15913
|
}
|
|
15882
|
-
|
|
15883
|
-
video.playsInline = inline;
|
|
15884
|
-
if (inline) {
|
|
15885
|
-
video.setAttribute("playsinline", "true");
|
|
15886
|
-
video.setAttribute("webkit-playsinline", "true");
|
|
15887
|
-
}
|
|
15914
|
+
applyInlineVideoPlayback(video, playsInline ?? true);
|
|
15888
15915
|
video.poster = poster ?? "";
|
|
15889
15916
|
const texture = new import_three35.VideoTexture(video);
|
|
15890
15917
|
texture.colorSpace = import_three35.SRGBColorSpace;
|
|
@@ -15926,6 +15953,7 @@ function useVideoResource({
|
|
|
15926
15953
|
video.addEventListener("error", reportError);
|
|
15927
15954
|
video.addEventListener("pause", handlePause);
|
|
15928
15955
|
video.addEventListener("play", handlePlay);
|
|
15956
|
+
mountTextureVideo(video, gl.domElement);
|
|
15929
15957
|
setResource({ video, texture, ready: false });
|
|
15930
15958
|
video.src = src;
|
|
15931
15959
|
video.load();
|
|
@@ -15939,9 +15967,19 @@ function useVideoResource({
|
|
|
15939
15967
|
video.pause();
|
|
15940
15968
|
video.removeAttribute("src");
|
|
15941
15969
|
video.load();
|
|
15970
|
+
video.remove();
|
|
15942
15971
|
texture.dispose();
|
|
15943
15972
|
};
|
|
15944
|
-
}, [crossOrigin, id, playsInline, poster, src]);
|
|
15973
|
+
}, [crossOrigin, gl, id, playsInline, poster, src]);
|
|
15974
|
+
(0, import_react57.useLayoutEffect)(() => {
|
|
15975
|
+
if (!resource) {
|
|
15976
|
+
return;
|
|
15977
|
+
}
|
|
15978
|
+
mountTextureVideo(resource.video, gl.domElement);
|
|
15979
|
+
return () => {
|
|
15980
|
+
resource.video.remove();
|
|
15981
|
+
};
|
|
15982
|
+
}, [gl, resource]);
|
|
15945
15983
|
return resource;
|
|
15946
15984
|
}
|
|
15947
15985
|
function VideoHotspot({
|
|
@@ -15980,21 +16018,14 @@ function VideoHotspot({
|
|
|
15980
16018
|
const onPlaybackStateChangeRef = (0, import_react57.useRef)(onPlaybackStateChange);
|
|
15981
16019
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15982
16020
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15983
|
-
(0, import_react57.
|
|
16021
|
+
(0, import_react57.useLayoutEffect)(() => {
|
|
15984
16022
|
if (!resource) {
|
|
15985
16023
|
return;
|
|
15986
16024
|
}
|
|
15987
16025
|
resource.video.loop = loop;
|
|
15988
16026
|
resource.video.muted = muted;
|
|
15989
16027
|
resource.video.volume = clampVolume2(volume);
|
|
15990
|
-
resource.video
|
|
15991
|
-
if (playsInline) {
|
|
15992
|
-
resource.video.setAttribute("playsinline", "true");
|
|
15993
|
-
resource.video.setAttribute("webkit-playsinline", "true");
|
|
15994
|
-
} else {
|
|
15995
|
-
resource.video.removeAttribute("playsinline");
|
|
15996
|
-
resource.video.removeAttribute("webkit-playsinline");
|
|
15997
|
-
}
|
|
16028
|
+
applyInlineVideoPlayback(resource.video, playsInline);
|
|
15998
16029
|
resource.video.preload = preload;
|
|
15999
16030
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
16000
16031
|
(0, import_react57.useEffect)(() => {
|