@bubo-squared/gyroview 0.1.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.
- package/CHANGELOG.md +32 -0
- package/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/define.d.ts +3 -0
- package/dist/define.js +4 -0
- package/dist/index.d.ts +959 -0
- package/dist/index.js +13 -0
- package/dist/packages/adapters/blob/src/BlobRandomAccessSource.js +37 -0
- package/dist/packages/adapters/blob/src/index.js +2 -0
- package/dist/packages/adapters/fetch/src/HttpRangeSource.js +194 -0
- package/dist/packages/adapters/fetch/src/HttpResourceLocator.js +35 -0
- package/dist/packages/adapters/fetch/src/httpRequest.js +126 -0
- package/dist/packages/adapters/fetch/src/index.js +3 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyAudioSegments.js +133 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyDemuxer.js +63 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyVideoTrackReader.js +84 -0
- package/dist/packages/adapters/mediabunny/src/SegmentChannel.js +84 -0
- package/dist/packages/adapters/mediabunny/src/bufferSources.js +12 -0
- package/dist/packages/adapters/mediabunny/src/index.js +2 -0
- package/dist/packages/adapters/mse-audio/src/MediaSourceAudioClock.js +139 -0
- package/dist/packages/adapters/mse-audio/src/SourceBufferFeeder.js +174 -0
- package/dist/packages/adapters/mse-audio/src/events.js +26 -0
- package/dist/packages/adapters/mse-audio/src/index.js +2 -0
- package/dist/packages/adapters/mse-audio/src/mediaSourceSupport.js +82 -0
- package/dist/packages/adapters/three/src/ThreeFrameRenderer.js +274 -0
- package/dist/packages/adapters/three/src/compileAndProve.js +14 -0
- package/dist/packages/adapters/three/src/fullscreenPass.js +52 -0
- package/dist/packages/adapters/three/src/index.js +2 -0
- package/dist/packages/adapters/three/src/lensTextures.js +25 -0
- package/dist/packages/adapters/three/src/pictureMaterials.js +44 -0
- package/dist/packages/adapters/three/src/renderInto.js +15 -0
- package/dist/packages/adapters/three/src/rendererUniforms.js +157 -0
- package/dist/packages/adapters/three/src/samplingStrategies.js +26 -0
- package/dist/packages/adapters/three/src/seamMeter/SeamMeterPass.js +79 -0
- package/dist/packages/adapters/three/src/seamMeter/rowMeans.js +38 -0
- package/dist/packages/adapters/three/src/shaderPrograms.js +66 -0
- package/dist/packages/adapters/three/src/shaders/analysis.frag.js +4 -0
- package/dist/packages/adapters/three/src/shaders/equirectangularRays.js +4 -0
- package/dist/packages/adapters/three/src/shaders/fixedJoin.js +4 -0
- package/dist/packages/adapters/three/src/shaders/fullscreen.vert.js +4 -0
- package/dist/packages/adapters/three/src/shaders/header.js +4 -0
- package/dist/packages/adapters/three/src/shaders/lensModels.js +4 -0
- package/dist/packages/adapters/three/src/shaders/lensSampling.js +4 -0
- package/dist/packages/adapters/three/src/shaders/lensTextures.js +4 -0
- package/dist/packages/adapters/three/src/shaders/rawLenses.frag.js +4 -0
- package/dist/packages/adapters/three/src/shaders/rectilinearRays.js +4 -0
- package/dist/packages/adapters/three/src/shaders/screenAreas.js +4 -0
- package/dist/packages/adapters/three/src/shaders/stitch.frag.js +4 -0
- package/dist/packages/adapters/three/src/webglRenderer.js +37 -0
- package/dist/packages/adapters/webcodecs/src/WebCodecsVideoDecoderPort.js +135 -0
- package/dist/packages/adapters/webcodecs/src/index.js +2 -0
- package/dist/packages/core/src/application/gainMatching/GainMatching.js +66 -0
- package/dist/packages/core/src/application/gainMatching/GainMatchingFrameSink.js +62 -0
- package/dist/packages/core/src/application/playback/ClockWatch.js +76 -0
- package/dist/packages/core/src/application/playback/DecodePipeline.js +188 -0
- package/dist/packages/core/src/application/playback/DecodeRun.js +93 -0
- package/dist/packages/core/src/application/playback/FramePairQueue.js +93 -0
- package/dist/packages/core/src/application/playback/FramePairer.js +60 -0
- package/dist/packages/core/src/application/playback/PlaybackSession.js +417 -0
- package/dist/packages/core/src/application/playback/SeekOrder.js +36 -0
- package/dist/packages/core/src/application/playback/SessionLifecycle.js +42 -0
- package/dist/packages/core/src/application/playback/StartGate.js +55 -0
- package/dist/packages/core/src/application/playback/TimeUpdates.js +31 -0
- package/dist/packages/core/src/application/playback/WallClock.js +46 -0
- package/dist/packages/core/src/application/playback/keyframeTimeAt.js +15 -0
- package/dist/packages/core/src/application/playback/probeDecoding.js +168 -0
- package/dist/packages/core/src/application/recording/frameTimesOf.js +22 -0
- package/dist/packages/core/src/application/recording/inspectLayout.js +21 -0
- package/dist/packages/core/src/application/recording/inspectRecording.js +124 -0
- package/dist/packages/core/src/application/recording/locateOtherLensFile.js +18 -0
- package/dist/packages/core/src/application/recording/motionOf.js +39 -0
- package/dist/packages/core/src/application/recording/readRecording.js +31 -0
- package/dist/packages/core/src/application/recording/timeRecording.js +57 -0
- package/dist/packages/core/src/application/stabilization/StabilizingFrameSink.js +31 -0
- package/dist/packages/core/src/domain/format/boxes/BoxLayout.js +7 -0
- package/dist/packages/core/src/domain/format/boxes/boxConstants.js +16 -0
- package/dist/packages/core/src/domain/format/boxes/scanBoxes.js +59 -0
- package/dist/packages/core/src/domain/format/calibration/CalibrationVersion.js +13 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/CalibrationStringLayout.js +34 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/LegacyCalibrationLayout.js +44 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/MeiCalibrationLayout.js +45 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/PolynomialCalibrationLayout.js +44 -0
- package/dist/packages/core/src/domain/format/calibration/offsetTokens.js +65 -0
- package/dist/packages/core/src/domain/format/calibration/parseOffsetString.js +52 -0
- package/dist/packages/core/src/domain/format/calibration/selectCalibration.js +46 -0
- package/dist/packages/core/src/domain/format/captureOrigin.js +20 -0
- package/dist/packages/core/src/domain/format/constants.js +33 -0
- package/dist/packages/core/src/domain/format/info/infoFields.js +110 -0
- package/dist/packages/core/src/domain/format/info/parseInfoRecord.js +90 -0
- package/dist/packages/core/src/domain/format/info/readInfoRecord.js +14 -0
- package/dist/packages/core/src/domain/format/layout/detectLensLayout.js +122 -0
- package/dist/packages/core/src/domain/format/naming/RecordingFileName.js +67 -0
- package/dist/packages/core/src/domain/format/records/TrailerRecords.js +83 -0
- package/dist/packages/core/src/domain/format/records/exposure/parseExposureRecord.js +48 -0
- package/dist/packages/core/src/domain/format/records/gyro/FloatGyroSampleLayout.js +39 -0
- package/dist/packages/core/src/domain/format/records/gyro/RawGyroSampleLayout.js +55 -0
- package/dist/packages/core/src/domain/format/records/gyro/SampleColumns.js +82 -0
- package/dist/packages/core/src/domain/format/records/gyro/gyroLayouts.js +12 -0
- package/dist/packages/core/src/domain/format/records/gyro/parseGyroRecord.js +129 -0
- package/dist/packages/core/src/domain/format/trailer/RecordHeader.js +23 -0
- package/dist/packages/core/src/domain/format/trailer/Trailer.js +23 -0
- package/dist/packages/core/src/domain/format/trailer/TrailerFooter.js +27 -0
- package/dist/packages/core/src/domain/format/trailer/locateRecords.js +80 -0
- package/dist/packages/core/src/domain/format/trailer/parseRecordIndex.js +28 -0
- package/dist/packages/core/src/domain/format/trailer/readTrailer.js +32 -0
- package/dist/packages/core/src/domain/motion/exposure/ExposureRecord.js +53 -0
- package/dist/packages/core/src/domain/motion/gyro/GyroTrack.js +60 -0
- package/dist/packages/core/src/domain/motion/gyro/medianStep.js +11 -0
- package/dist/packages/core/src/domain/motion/gyro/repairedTimeline.js +101 -0
- package/dist/packages/core/src/domain/motion/imu/ImuFrame.js +112 -0
- package/dist/packages/core/src/domain/motion/orientation/OrientationTrack.js +146 -0
- package/dist/packages/core/src/domain/motion/orientation/estimateGyroBias.js +64 -0
- package/dist/packages/core/src/domain/motion/orientation/gravity.js +97 -0
- package/dist/packages/core/src/domain/motion/stabilization/Stabilizer.js +13 -0
- package/dist/packages/core/src/domain/motion/stabilization/stabilizers.js +86 -0
- package/dist/packages/core/src/domain/motion/timing/CaptureClock.js +41 -0
- package/dist/packages/core/src/domain/motion/timing/FrameTimes.js +92 -0
- package/dist/packages/core/src/domain/motion/timing/frameTimeSources.js +61 -0
- package/dist/packages/core/src/domain/motion/timing/resolveFrameTimes.js +68 -0
- package/dist/packages/core/src/domain/optics/EquidistantModel.js +39 -0
- package/dist/packages/core/src/domain/optics/MeiModel.js +45 -0
- package/dist/packages/core/src/domain/optics/PolynomialModel.js +44 -0
- package/dist/packages/core/src/domain/optics/gainMatch.js +62 -0
- package/dist/packages/core/src/domain/optics/lensGeometry.js +18 -0
- package/dist/packages/core/src/domain/optics/lensPose.js +35 -0
- package/dist/packages/core/src/domain/optics/opticsConstants.js +5 -0
- package/dist/packages/core/src/domain/playback/PlayerState.js +83 -0
- package/dist/packages/core/src/domain/stitching/LensLayout.js +21 -0
- package/dist/packages/core/src/domain/stitching/StitchingSetup.js +78 -0
- package/dist/packages/core/src/domain/stitching/seamDisparity.js +4 -0
- package/dist/packages/core/src/domain/stitching/seamDisparityField.js +5 -0
- package/dist/packages/core/src/domain/stitching/seamJoin.js +16 -0
- package/dist/packages/core/src/domain/stitching/seamMismatch.js +1 -0
- package/dist/packages/core/src/domain/stitching/seamRing.js +4 -0
- package/dist/packages/core/src/domain/stitching/seamStrip.js +26 -0
- package/dist/packages/core/src/domain/view/Framing.js +31 -0
- package/dist/packages/core/src/domain/view/PictureQuality.js +26 -0
- package/dist/packages/core/src/domain/view/ViewMode.js +9 -0
- package/dist/packages/core/src/domain/view/ViewState.js +48 -0
- package/dist/packages/core/src/domain/view/lensTilesView.js +63 -0
- package/dist/packages/core/src/domain/view/magnification.js +103 -0
- package/dist/packages/core/src/domain/view/normalView.js +29 -0
- package/dist/packages/core/src/domain/view/panoramaView.js +99 -0
- package/dist/packages/core/src/domain/view/rectilinear.js +40 -0
- package/dist/packages/core/src/domain/view/screenLayout.js +113 -0
- package/dist/packages/core/src/domain/view/viewGestures.js +98 -0
- package/dist/packages/core/src/domain/view/viewModes.js +14 -0
- package/dist/packages/core/src/index.js +59 -0
- package/dist/packages/core/src/ports/FramePair.js +6 -0
- package/dist/packages/core/src/shared/async/Deferred.js +42 -0
- package/dist/packages/core/src/shared/async/RunStop.js +40 -0
- package/dist/packages/core/src/shared/binary/ByteRange.js +38 -0
- package/dist/packages/core/src/shared/binary/ByteReader.js +77 -0
- package/dist/packages/core/src/shared/errors/GyroViewError.js +81 -0
- package/dist/packages/core/src/shared/errors/reportLater.js +11 -0
- package/dist/packages/core/src/shared/events/Outbox.js +68 -0
- package/dist/packages/core/src/shared/events/TypedEmitter.js +55 -0
- package/dist/packages/core/src/shared/keysOf.js +10 -0
- package/dist/packages/core/src/shared/lazy.js +11 -0
- package/dist/packages/core/src/shared/math/Matrix3.js +93 -0
- package/dist/packages/core/src/shared/math/Quaternion.js +133 -0
- package/dist/packages/core/src/shared/math/Vector3.js +54 -0
- package/dist/packages/core/src/shared/math/clamp.js +9 -0
- package/dist/packages/core/src/shared/protobuf/ProtobufMessage.js +157 -0
- package/dist/packages/core/src/shared/text/urlPath.js +31 -0
- package/dist/packages/core/src/shared/text/utf8.js +12 -0
- package/dist/packages/core/src/shared/units/angle.js +22 -0
- package/dist/packages/core/src/shared/units/time.js +13 -0
- package/dist/packages/player/src/PlayerSource.js +15 -0
- package/dist/packages/player/src/browserPlayer.js +18 -0
- package/dist/packages/player/src/choices.js +25 -0
- package/dist/packages/player/src/composition/Disposables.js +31 -0
- package/dist/packages/player/src/composition/browserPorts.js +46 -0
- package/dist/packages/player/src/composition/buildPipeline.js +153 -0
- package/dist/packages/player/src/composition/ensureDecodable.js +63 -0
- package/dist/packages/player/src/composition/openInputs.js +179 -0
- package/dist/packages/player/src/composition/openRecording.js +42 -0
- package/dist/packages/player/src/controls/ChoiceMenu.js +113 -0
- package/dist/packages/player/src/controls/PictureMenus.js +47 -0
- package/dist/packages/player/src/controls/SeekBar.js +125 -0
- package/dist/packages/player/src/controls/SoundControls.js +41 -0
- package/dist/packages/player/src/controls/TransportButtons.js +31 -0
- package/dist/packages/player/src/controls/ViewGestures.js +136 -0
- package/dist/packages/player/src/controls/Wording.js +78 -0
- package/dist/packages/player/src/controls/controlParts.js +36 -0
- package/dist/packages/player/src/controls/controls.js +4 -0
- package/dist/packages/player/src/controls/controlsBar.js +23 -0
- package/dist/packages/player/src/controls/controlsMarkup.js +85 -0
- package/dist/packages/player/src/controls/customControls.js +59 -0
- package/dist/packages/player/src/controls/formatTime.js +19 -0
- package/dist/packages/player/src/controls/icons.js +40 -0
- package/dist/packages/player/src/controls/keyboard.js +118 -0
- package/dist/packages/player/src/controls/messages.js +94 -0
- package/dist/packages/player/src/controls/parseMarkup.js +31 -0
- package/dist/packages/player/src/controls/viewButtons.js +14 -0
- package/dist/packages/player/src/element/ElementLoads.js +119 -0
- package/dist/packages/player/src/element/FullscreenToggle.js +39 -0
- package/dist/packages/player/src/element/GyroViewElement.js +313 -0
- package/dist/packages/player/src/element/IdleWatcher.js +71 -0
- package/dist/packages/player/src/element/TypedEventElement.js +22 -0
- package/dist/packages/player/src/element/accessibleRegion.js +19 -0
- package/dist/packages/player/src/element/attributeNames.js +51 -0
- package/dist/packages/player/src/element/attributes.js +101 -0
- package/dist/packages/player/src/element/defineGyroView.js +21 -0
- package/dist/packages/player/src/element/earlyProperties.js +36 -0
- package/dist/packages/player/src/element/elementSource.js +23 -0
- package/dist/packages/player/src/element/liveSettings.js +138 -0
- package/dist/packages/player/src/element/playbackAttributes.js +53 -0
- package/dist/packages/player/src/element/playerEventMirror.js +33 -0
- package/dist/packages/player/src/element/reflectedProperties.js +78 -0
- package/dist/packages/player/src/element/styles.js +4 -0
- package/dist/packages/player/src/element/template.js +47 -0
- package/dist/packages/player/src/index.js +10 -0
- package/dist/packages/player/src/inspectRecording.js +22 -0
- package/dist/packages/player/src/player/DrawingBufferFit.js +77 -0
- package/dist/packages/player/src/player/FrameLoop.js +40 -0
- package/dist/packages/player/src/player/PictureSettings.js +60 -0
- package/dist/packages/player/src/player/Player.js +377 -0
- package/dist/packages/player/src/player/PlayerEvents.js +28 -0
- package/dist/packages/player/src/player/PlayerPhase.js +21 -0
- package/dist/packages/player/src/player/PlayerSound.js +61 -0
- package/dist/packages/player/src/player/PlayerView.js +113 -0
- package/dist/packages/player/src/player/SessionRelay.js +66 -0
- package/dist/packages/player/src/player/ensureFinite.js +26 -0
- package/dist/packages/player/src/player/loadRecording.js +65 -0
- package/dist/packages/player/src/player/transportEvents.js +29 -0
- package/dist/standalone.js +4919 -0
- package/package.json +73 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
What changed for a page using the package, newest first. Until 1.0, a minor version may change
|
|
4
|
+
the API.
|
|
5
|
+
|
|
6
|
+
## 0.1.0 (2026-09-29)
|
|
7
|
+
|
|
8
|
+
The first release:
|
|
9
|
+
|
|
10
|
+
- `<gyro-view>`, registered by `@bubo-squared/gyroview/define` or `defineGyroView()`, safe to
|
|
11
|
+
import while a server renders the page. It runs under a strict CSP (`trusted-types gyroview`,
|
|
12
|
+
no inline styles), speaks the page's language through `messages`, shows visitors plain failure
|
|
13
|
+
texts and names its overlays as parts. It opens on the raw lenses; the view menu offers them
|
|
14
|
+
first, then the equirectangular panorama and the normal view. The stitch reads the legacy
|
|
15
|
+
calibration string's radius as 96 degrees from the lens axis, where Insta360 Studio's own stitch
|
|
16
|
+
puts the far field; `ready` reports `offset` as the calibration version. The lens pose reads
|
|
17
|
+
the calibration's roll mirrored and turns both lenses alike by their yaw and pitch, which
|
|
18
|
+
removes the step at the side seams of the X5 recordings. The `quality`
|
|
19
|
+
attribute (`fast`, `balanced`, `high`, listed in `PICTURE_QUALITIES`, with `setQuality` and
|
|
20
|
+
`qualitychange`) sets how finely
|
|
21
|
+
the lens images are read and how many device pixels are drawn; `balanced` reads them through a
|
|
22
|
+
mip chain along each pixel's footprint, so fine detail no longer shimmers.
|
|
23
|
+
- `createBrowserPlayer`, the player without the element, for an interface of your own, with
|
|
24
|
+
`attachViewGestures` and `attachKeyboard` for the element's gestures and shortcuts.
|
|
25
|
+
- `inspectRecording`, which reads what a recording holds from a file or a URL.
|
|
26
|
+
- `@bubo-squared/gyroview/standalone`, one file with Three.js and mediabunny inside, for a page
|
|
27
|
+
without a bundler.
|
|
28
|
+
- Events in media-element terms, each `warning` with a `code` a page can act on beside its
|
|
29
|
+
message; times, durations and views in plain seconds and degrees.
|
|
30
|
+
- `GyroViewError` and its codes (`GYRO_VIEW_ERROR_CODES`), and the types of the settings,
|
|
31
|
+
metadata, events and inspection, with `GyroViewAttributes` for a framework's JSX declaration
|
|
32
|
+
of the element.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bubo²
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# @bubo-squared/gyroview
|
|
2
|
+
|
|
3
|
+
Play raw Insta360 `.insv` recordings (X3, X4, X5) in the browser. `<gyro-view>` reads the
|
|
4
|
+
camera's dual-fisheye file directly, over HTTP byte ranges or from a local file, decodes both
|
|
5
|
+
lenses in hardware with WebCodecs, and stitches and gyro-stabilizes them on the GPU. No Insta360
|
|
6
|
+
Studio export step.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @bubo-squared/gyroview
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
It brings Three.js 0.186 and mediabunny 1 along. A page that uses Three.js 0.186 itself shares
|
|
15
|
+
that copy; any other version means two copies in the bundle, about 128 KB gzipped. The package is
|
|
16
|
+
ES modules only: CommonJS code loads it with `import()`.
|
|
17
|
+
|
|
18
|
+
## Use
|
|
19
|
+
|
|
20
|
+
Register the element once, then use it like a video element:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import '@bubo-squared/gyroview/define';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<gyro-view
|
|
28
|
+
src="https://media.example/VID_20260814_132640_00_013.insv"
|
|
29
|
+
stabilization="lock"
|
|
30
|
+
controls
|
|
31
|
+
muted
|
|
32
|
+
></gyro-view>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
A relative `src` resolves against the document, as an image's does. `timeupdate` comes four
|
|
36
|
+
times a second while playing, as a media element's does; `frame` comes with every picture
|
|
37
|
+
drawn.
|
|
38
|
+
|
|
39
|
+
A page without a bundler loads the standalone file, which has Three.js and mediabunny inside
|
|
40
|
+
(about 280 KB compressed) and registers the element; it exports what the package does:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<script
|
|
44
|
+
type="module"
|
|
45
|
+
src="https://cdn.jsdelivr.net/npm/@bubo-squared/gyroview@0.1/dist/standalone.js"
|
|
46
|
+
></script>
|
|
47
|
+
<script type="module">
|
|
48
|
+
import { inspectRecording } from 'https://cdn.jsdelivr.net/npm/@bubo-squared/gyroview@0.1/dist/standalone.js';
|
|
49
|
+
</script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Bundling it next to a Three.js of the page's own ships two copies; `@bubo-squared/gyroview`
|
|
53
|
+
and `@bubo-squared/gyroview/define` share the page's instead.
|
|
54
|
+
|
|
55
|
+
Play a file the visitor picks, without any server:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const player = document.querySelector('gyro-view');
|
|
59
|
+
const input = document.querySelector<HTMLInputElement>('input[type="file"]');
|
|
60
|
+
input?.addEventListener('change', () => {
|
|
61
|
+
const file = input.files?.[0];
|
|
62
|
+
if (file && player) player.loadFiles({ main: file });
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`@bubo-squared/gyroview/define` registers `<gyro-view>` when imported. To choose the moment
|
|
67
|
+
yourself, import `defineGyroView` from `@bubo-squared/gyroview` and call it. Both are safe to
|
|
68
|
+
import in a framework that renders on the server: there they register nothing, and the element
|
|
69
|
+
comes alive once the page runs in the browser.
|
|
70
|
+
|
|
71
|
+
The element's events are typed: each is a `CustomEvent` with its payload in `detail`, and
|
|
72
|
+
`document.querySelector('gyro-view')` is a `GyroViewElement`.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
player?.addEventListener('ready', (event) => console.log(event.detail.model));
|
|
76
|
+
player?.addEventListener('error', (event) => console.log(event.detail.code));
|
|
77
|
+
player?.addEventListener('warning', (event) => {
|
|
78
|
+
if (event.detail.code === 'autoplay-blocked') showTapToPlay();
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Its words are English until the page gives its own, and a failure shows visitors a plain
|
|
83
|
+
sentence while the `error` event carries the diagnostic:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
if (player) player.messages = { labels: { play: 'Lecture' }, errors: { cors: 'Introuvable.' } };
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Read what a recording holds without playing it: its trailer records, the info record (camera,
|
|
90
|
+
firmware, frame rate), the lens calibration and summaries of the gyro and exposure records.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { inspectRecording } from '@bubo-squared/gyroview';
|
|
94
|
+
|
|
95
|
+
const fromFile = await inspectRecording(file);
|
|
96
|
+
const fromUrl = await inspectRecording('https://media.example/VID_20260814_132640_00_013.insv');
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For an interface of your own, `createBrowserPlayer` gives the player without the element: it
|
|
100
|
+
draws on your canvas, sounds through your audio element and has the same events.
|
|
101
|
+
`attachViewGestures` and `attachKeyboard` give your canvas the element's drags, pinches, wheel
|
|
102
|
+
zoom and taps, and its keyboard shortcuts; each returns what removes them.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { createBrowserPlayer } from '@bubo-squared/gyroview';
|
|
106
|
+
|
|
107
|
+
const player = createBrowserPlayer({ canvas, audio });
|
|
108
|
+
player.events.on('timeupdate', (time) => console.log(time));
|
|
109
|
+
attachViewGestures(canvas, player);
|
|
110
|
+
attachKeyboard(canvas, player);
|
|
111
|
+
await player.load({ main: { url: 'https://media.example/VID_20260814_132640_00_013.insv' } });
|
|
112
|
+
await player.play();
|
|
113
|
+
player.seek(30);
|
|
114
|
+
player.lookAt(90, 0);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The canvas keeps no picture once the browser has shown it: a snapshot (`drawImage`, `toBlob`)
|
|
118
|
+
is taken in a `frame` listener, which runs right after each picture is drawn. There are no
|
|
119
|
+
buffered ranges to show, since the player reads the recording as it plays, and no playback
|
|
120
|
+
rates other than 1.
|
|
121
|
+
|
|
122
|
+
`@bubo-squared/gyroview` also exports `GyroViewError`, the list of its codes
|
|
123
|
+
(`GYRO_VIEW_ERROR_CODES`, with `isGyroViewErrorCode` to check a string against it), and the
|
|
124
|
+
types of the element's settings, metadata, events and inspection.
|
|
125
|
+
|
|
126
|
+
## Frameworks
|
|
127
|
+
|
|
128
|
+
The element takes properties and attributes as any element does, and its events are DOM
|
|
129
|
+
events, so a framework needs only to know the tag.
|
|
130
|
+
|
|
131
|
+
**React 19** sets the attributes and hears events through a ref. For JSX to know the tag, a
|
|
132
|
+
declaration file of the project's own extends React's elements with the package's
|
|
133
|
+
`GyroViewAttributes`:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
// gyro-view.d.ts
|
|
137
|
+
import type { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
138
|
+
import type { GyroViewAttributes, GyroViewElement } from '@bubo-squared/gyroview';
|
|
139
|
+
|
|
140
|
+
declare module 'react' {
|
|
141
|
+
namespace JSX {
|
|
142
|
+
interface IntrinsicElements {
|
|
143
|
+
'gyro-view': DetailedHTMLProps<HTMLAttributes<GyroViewElement>, GyroViewElement> &
|
|
144
|
+
GyroViewAttributes;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
const player = useRef<GyroViewElement>(null);
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
const element = player.current;
|
|
154
|
+
const onReady = (event: CustomEvent<PlayerMetadata>): void => console.log(event.detail.model);
|
|
155
|
+
element?.addEventListener('ready', onReady);
|
|
156
|
+
return () => element?.removeEventListener('ready', onReady);
|
|
157
|
+
}, []);
|
|
158
|
+
return <gyro-view ref={player} src={url} stabilization="lock" controls muted />;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Vue 3** is told the tag is a custom element (`isCustomElement: (tag) => tag === 'gyro-view'`
|
|
162
|
+
in the template compiler options), then binds as usual: `<gyro-view :src="url" controls
|
|
163
|
+
@ready="onReady" />`.
|
|
164
|
+
|
|
165
|
+
**Svelte 5** needs nothing: `<gyro-view src={url} controls onready={onReady} />`.
|
|
166
|
+
|
|
167
|
+
In every case the element registers in the browser only: import `@bubo-squared/gyroview/define`
|
|
168
|
+
in code that runs there, or call `defineGyroView()` once mounted. Importing either while the
|
|
169
|
+
server renders is safe and registers nothing.
|
|
170
|
+
|
|
171
|
+
## Several players on one page
|
|
172
|
+
|
|
173
|
+
Each player holds a WebGL context and, while a recording is loaded, two hardware video
|
|
174
|
+
decoders. Browsers cap both (about sixteen WebGL contexts in Chrome, fewer decoders on phones),
|
|
175
|
+
so a gallery gives its players `preload="none"`, which keeps the decoders idle until play, and
|
|
176
|
+
loads a recording only for the player in view, removing `src` from the others.
|
|
177
|
+
|
|
178
|
+
## Requirements
|
|
179
|
+
|
|
180
|
+
- **A secure page.** WebCodecs exists only on `https://` pages, or `http://localhost`.
|
|
181
|
+
- **Recordings served in byte ranges.** The server answers `Range` requests with `206`, and
|
|
182
|
+
sends CORS headers when the recordings live on another origin than the page:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
Access-Control-Allow-Origin: https://your-site.example
|
|
186
|
+
Access-Control-Allow-Methods: GET, HEAD
|
|
187
|
+
Access-Control-Allow-Headers: Range
|
|
188
|
+
Access-Control-Expose-Headers: Content-Range, Content-Length, Accept-Ranges
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- **A hardware HEVC decoder.** 5.7K plays on recent laptops and phones; 8K needs a Level 6
|
|
192
|
+
decoder (Apple Silicon, recent NVIDIA and Intel). A recording the browser cannot decode fails
|
|
193
|
+
with the `codec-unsupported` error.
|
|
194
|
+
|
|
195
|
+
The supported browsers, with the oldest versions that have what the player uses (WebCodecs,
|
|
196
|
+
WebGL 2, container queries, and on iPhone `ManagedMediaSource` for the sound):
|
|
197
|
+
|
|
198
|
+
| Browser | From | Notes |
|
|
199
|
+
| --------------------- | ---- | -------------------------------------------------------- |
|
|
200
|
+
| Chrome, Edge desktop | 107 | HEVC is decoded in hardware from this version on. |
|
|
201
|
+
| Safari on macOS | 16.4 | |
|
|
202
|
+
| Safari on iPhone/iPad | 17.1 | 16.4 to 17.0 play without sound, with a `warning` event. |
|
|
203
|
+
|
|
204
|
+
Firefox and Chrome on Android are untested: they play what their decoders accept.
|
|
205
|
+
|
|
206
|
+
Until 1.0, a minor version may change the API; [CHANGELOG.md](./CHANGELOG.md) says what changed.
|
|
207
|
+
|
|
208
|
+
## Reference
|
|
209
|
+
|
|
210
|
+
Every attribute, method, event and keyboard shortcut is in the
|
|
211
|
+
[project README](https://github.com/bubo-squared/GyroView#using-the-player); hosting and the
|
|
212
|
+
error codes are in [docs/DEPLOYMENT.md](https://github.com/bubo-squared/GyroView/blob/main/docs/DEPLOYMENT.md).
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT
|
package/dist/define.d.ts
ADDED
package/dist/define.js
ADDED