@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.
Files changed (228) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +21 -0
  3. package/README.md +216 -0
  4. package/dist/define.d.ts +3 -0
  5. package/dist/define.js +4 -0
  6. package/dist/index.d.ts +959 -0
  7. package/dist/index.js +13 -0
  8. package/dist/packages/adapters/blob/src/BlobRandomAccessSource.js +37 -0
  9. package/dist/packages/adapters/blob/src/index.js +2 -0
  10. package/dist/packages/adapters/fetch/src/HttpRangeSource.js +194 -0
  11. package/dist/packages/adapters/fetch/src/HttpResourceLocator.js +35 -0
  12. package/dist/packages/adapters/fetch/src/httpRequest.js +126 -0
  13. package/dist/packages/adapters/fetch/src/index.js +3 -0
  14. package/dist/packages/adapters/mediabunny/src/MediabunnyAudioSegments.js +133 -0
  15. package/dist/packages/adapters/mediabunny/src/MediabunnyDemuxer.js +63 -0
  16. package/dist/packages/adapters/mediabunny/src/MediabunnyVideoTrackReader.js +84 -0
  17. package/dist/packages/adapters/mediabunny/src/SegmentChannel.js +84 -0
  18. package/dist/packages/adapters/mediabunny/src/bufferSources.js +12 -0
  19. package/dist/packages/adapters/mediabunny/src/index.js +2 -0
  20. package/dist/packages/adapters/mse-audio/src/MediaSourceAudioClock.js +139 -0
  21. package/dist/packages/adapters/mse-audio/src/SourceBufferFeeder.js +174 -0
  22. package/dist/packages/adapters/mse-audio/src/events.js +26 -0
  23. package/dist/packages/adapters/mse-audio/src/index.js +2 -0
  24. package/dist/packages/adapters/mse-audio/src/mediaSourceSupport.js +82 -0
  25. package/dist/packages/adapters/three/src/ThreeFrameRenderer.js +274 -0
  26. package/dist/packages/adapters/three/src/compileAndProve.js +14 -0
  27. package/dist/packages/adapters/three/src/fullscreenPass.js +52 -0
  28. package/dist/packages/adapters/three/src/index.js +2 -0
  29. package/dist/packages/adapters/three/src/lensTextures.js +25 -0
  30. package/dist/packages/adapters/three/src/pictureMaterials.js +44 -0
  31. package/dist/packages/adapters/three/src/renderInto.js +15 -0
  32. package/dist/packages/adapters/three/src/rendererUniforms.js +157 -0
  33. package/dist/packages/adapters/three/src/samplingStrategies.js +26 -0
  34. package/dist/packages/adapters/three/src/seamMeter/SeamMeterPass.js +79 -0
  35. package/dist/packages/adapters/three/src/seamMeter/rowMeans.js +38 -0
  36. package/dist/packages/adapters/three/src/shaderPrograms.js +66 -0
  37. package/dist/packages/adapters/three/src/shaders/analysis.frag.js +4 -0
  38. package/dist/packages/adapters/three/src/shaders/equirectangularRays.js +4 -0
  39. package/dist/packages/adapters/three/src/shaders/fixedJoin.js +4 -0
  40. package/dist/packages/adapters/three/src/shaders/fullscreen.vert.js +4 -0
  41. package/dist/packages/adapters/three/src/shaders/header.js +4 -0
  42. package/dist/packages/adapters/three/src/shaders/lensModels.js +4 -0
  43. package/dist/packages/adapters/three/src/shaders/lensSampling.js +4 -0
  44. package/dist/packages/adapters/three/src/shaders/lensTextures.js +4 -0
  45. package/dist/packages/adapters/three/src/shaders/rawLenses.frag.js +4 -0
  46. package/dist/packages/adapters/three/src/shaders/rectilinearRays.js +4 -0
  47. package/dist/packages/adapters/three/src/shaders/screenAreas.js +4 -0
  48. package/dist/packages/adapters/three/src/shaders/stitch.frag.js +4 -0
  49. package/dist/packages/adapters/three/src/webglRenderer.js +37 -0
  50. package/dist/packages/adapters/webcodecs/src/WebCodecsVideoDecoderPort.js +135 -0
  51. package/dist/packages/adapters/webcodecs/src/index.js +2 -0
  52. package/dist/packages/core/src/application/gainMatching/GainMatching.js +66 -0
  53. package/dist/packages/core/src/application/gainMatching/GainMatchingFrameSink.js +62 -0
  54. package/dist/packages/core/src/application/playback/ClockWatch.js +76 -0
  55. package/dist/packages/core/src/application/playback/DecodePipeline.js +188 -0
  56. package/dist/packages/core/src/application/playback/DecodeRun.js +93 -0
  57. package/dist/packages/core/src/application/playback/FramePairQueue.js +93 -0
  58. package/dist/packages/core/src/application/playback/FramePairer.js +60 -0
  59. package/dist/packages/core/src/application/playback/PlaybackSession.js +417 -0
  60. package/dist/packages/core/src/application/playback/SeekOrder.js +36 -0
  61. package/dist/packages/core/src/application/playback/SessionLifecycle.js +42 -0
  62. package/dist/packages/core/src/application/playback/StartGate.js +55 -0
  63. package/dist/packages/core/src/application/playback/TimeUpdates.js +31 -0
  64. package/dist/packages/core/src/application/playback/WallClock.js +46 -0
  65. package/dist/packages/core/src/application/playback/keyframeTimeAt.js +15 -0
  66. package/dist/packages/core/src/application/playback/probeDecoding.js +168 -0
  67. package/dist/packages/core/src/application/recording/frameTimesOf.js +22 -0
  68. package/dist/packages/core/src/application/recording/inspectLayout.js +21 -0
  69. package/dist/packages/core/src/application/recording/inspectRecording.js +124 -0
  70. package/dist/packages/core/src/application/recording/locateOtherLensFile.js +18 -0
  71. package/dist/packages/core/src/application/recording/motionOf.js +39 -0
  72. package/dist/packages/core/src/application/recording/readRecording.js +31 -0
  73. package/dist/packages/core/src/application/recording/timeRecording.js +57 -0
  74. package/dist/packages/core/src/application/stabilization/StabilizingFrameSink.js +31 -0
  75. package/dist/packages/core/src/domain/format/boxes/BoxLayout.js +7 -0
  76. package/dist/packages/core/src/domain/format/boxes/boxConstants.js +16 -0
  77. package/dist/packages/core/src/domain/format/boxes/scanBoxes.js +59 -0
  78. package/dist/packages/core/src/domain/format/calibration/CalibrationVersion.js +13 -0
  79. package/dist/packages/core/src/domain/format/calibration/layouts/CalibrationStringLayout.js +34 -0
  80. package/dist/packages/core/src/domain/format/calibration/layouts/LegacyCalibrationLayout.js +44 -0
  81. package/dist/packages/core/src/domain/format/calibration/layouts/MeiCalibrationLayout.js +45 -0
  82. package/dist/packages/core/src/domain/format/calibration/layouts/PolynomialCalibrationLayout.js +44 -0
  83. package/dist/packages/core/src/domain/format/calibration/offsetTokens.js +65 -0
  84. package/dist/packages/core/src/domain/format/calibration/parseOffsetString.js +52 -0
  85. package/dist/packages/core/src/domain/format/calibration/selectCalibration.js +46 -0
  86. package/dist/packages/core/src/domain/format/captureOrigin.js +20 -0
  87. package/dist/packages/core/src/domain/format/constants.js +33 -0
  88. package/dist/packages/core/src/domain/format/info/infoFields.js +110 -0
  89. package/dist/packages/core/src/domain/format/info/parseInfoRecord.js +90 -0
  90. package/dist/packages/core/src/domain/format/info/readInfoRecord.js +14 -0
  91. package/dist/packages/core/src/domain/format/layout/detectLensLayout.js +122 -0
  92. package/dist/packages/core/src/domain/format/naming/RecordingFileName.js +67 -0
  93. package/dist/packages/core/src/domain/format/records/TrailerRecords.js +83 -0
  94. package/dist/packages/core/src/domain/format/records/exposure/parseExposureRecord.js +48 -0
  95. package/dist/packages/core/src/domain/format/records/gyro/FloatGyroSampleLayout.js +39 -0
  96. package/dist/packages/core/src/domain/format/records/gyro/RawGyroSampleLayout.js +55 -0
  97. package/dist/packages/core/src/domain/format/records/gyro/SampleColumns.js +82 -0
  98. package/dist/packages/core/src/domain/format/records/gyro/gyroLayouts.js +12 -0
  99. package/dist/packages/core/src/domain/format/records/gyro/parseGyroRecord.js +129 -0
  100. package/dist/packages/core/src/domain/format/trailer/RecordHeader.js +23 -0
  101. package/dist/packages/core/src/domain/format/trailer/Trailer.js +23 -0
  102. package/dist/packages/core/src/domain/format/trailer/TrailerFooter.js +27 -0
  103. package/dist/packages/core/src/domain/format/trailer/locateRecords.js +80 -0
  104. package/dist/packages/core/src/domain/format/trailer/parseRecordIndex.js +28 -0
  105. package/dist/packages/core/src/domain/format/trailer/readTrailer.js +32 -0
  106. package/dist/packages/core/src/domain/motion/exposure/ExposureRecord.js +53 -0
  107. package/dist/packages/core/src/domain/motion/gyro/GyroTrack.js +60 -0
  108. package/dist/packages/core/src/domain/motion/gyro/medianStep.js +11 -0
  109. package/dist/packages/core/src/domain/motion/gyro/repairedTimeline.js +101 -0
  110. package/dist/packages/core/src/domain/motion/imu/ImuFrame.js +112 -0
  111. package/dist/packages/core/src/domain/motion/orientation/OrientationTrack.js +146 -0
  112. package/dist/packages/core/src/domain/motion/orientation/estimateGyroBias.js +64 -0
  113. package/dist/packages/core/src/domain/motion/orientation/gravity.js +97 -0
  114. package/dist/packages/core/src/domain/motion/stabilization/Stabilizer.js +13 -0
  115. package/dist/packages/core/src/domain/motion/stabilization/stabilizers.js +86 -0
  116. package/dist/packages/core/src/domain/motion/timing/CaptureClock.js +41 -0
  117. package/dist/packages/core/src/domain/motion/timing/FrameTimes.js +92 -0
  118. package/dist/packages/core/src/domain/motion/timing/frameTimeSources.js +61 -0
  119. package/dist/packages/core/src/domain/motion/timing/resolveFrameTimes.js +68 -0
  120. package/dist/packages/core/src/domain/optics/EquidistantModel.js +39 -0
  121. package/dist/packages/core/src/domain/optics/MeiModel.js +45 -0
  122. package/dist/packages/core/src/domain/optics/PolynomialModel.js +44 -0
  123. package/dist/packages/core/src/domain/optics/gainMatch.js +62 -0
  124. package/dist/packages/core/src/domain/optics/lensGeometry.js +18 -0
  125. package/dist/packages/core/src/domain/optics/lensPose.js +35 -0
  126. package/dist/packages/core/src/domain/optics/opticsConstants.js +5 -0
  127. package/dist/packages/core/src/domain/playback/PlayerState.js +83 -0
  128. package/dist/packages/core/src/domain/stitching/LensLayout.js +21 -0
  129. package/dist/packages/core/src/domain/stitching/StitchingSetup.js +78 -0
  130. package/dist/packages/core/src/domain/stitching/seamDisparity.js +4 -0
  131. package/dist/packages/core/src/domain/stitching/seamDisparityField.js +5 -0
  132. package/dist/packages/core/src/domain/stitching/seamJoin.js +16 -0
  133. package/dist/packages/core/src/domain/stitching/seamMismatch.js +1 -0
  134. package/dist/packages/core/src/domain/stitching/seamRing.js +4 -0
  135. package/dist/packages/core/src/domain/stitching/seamStrip.js +26 -0
  136. package/dist/packages/core/src/domain/view/Framing.js +31 -0
  137. package/dist/packages/core/src/domain/view/PictureQuality.js +26 -0
  138. package/dist/packages/core/src/domain/view/ViewMode.js +9 -0
  139. package/dist/packages/core/src/domain/view/ViewState.js +48 -0
  140. package/dist/packages/core/src/domain/view/lensTilesView.js +63 -0
  141. package/dist/packages/core/src/domain/view/magnification.js +103 -0
  142. package/dist/packages/core/src/domain/view/normalView.js +29 -0
  143. package/dist/packages/core/src/domain/view/panoramaView.js +99 -0
  144. package/dist/packages/core/src/domain/view/rectilinear.js +40 -0
  145. package/dist/packages/core/src/domain/view/screenLayout.js +113 -0
  146. package/dist/packages/core/src/domain/view/viewGestures.js +98 -0
  147. package/dist/packages/core/src/domain/view/viewModes.js +14 -0
  148. package/dist/packages/core/src/index.js +59 -0
  149. package/dist/packages/core/src/ports/FramePair.js +6 -0
  150. package/dist/packages/core/src/shared/async/Deferred.js +42 -0
  151. package/dist/packages/core/src/shared/async/RunStop.js +40 -0
  152. package/dist/packages/core/src/shared/binary/ByteRange.js +38 -0
  153. package/dist/packages/core/src/shared/binary/ByteReader.js +77 -0
  154. package/dist/packages/core/src/shared/errors/GyroViewError.js +81 -0
  155. package/dist/packages/core/src/shared/errors/reportLater.js +11 -0
  156. package/dist/packages/core/src/shared/events/Outbox.js +68 -0
  157. package/dist/packages/core/src/shared/events/TypedEmitter.js +55 -0
  158. package/dist/packages/core/src/shared/keysOf.js +10 -0
  159. package/dist/packages/core/src/shared/lazy.js +11 -0
  160. package/dist/packages/core/src/shared/math/Matrix3.js +93 -0
  161. package/dist/packages/core/src/shared/math/Quaternion.js +133 -0
  162. package/dist/packages/core/src/shared/math/Vector3.js +54 -0
  163. package/dist/packages/core/src/shared/math/clamp.js +9 -0
  164. package/dist/packages/core/src/shared/protobuf/ProtobufMessage.js +157 -0
  165. package/dist/packages/core/src/shared/text/urlPath.js +31 -0
  166. package/dist/packages/core/src/shared/text/utf8.js +12 -0
  167. package/dist/packages/core/src/shared/units/angle.js +22 -0
  168. package/dist/packages/core/src/shared/units/time.js +13 -0
  169. package/dist/packages/player/src/PlayerSource.js +15 -0
  170. package/dist/packages/player/src/browserPlayer.js +18 -0
  171. package/dist/packages/player/src/choices.js +25 -0
  172. package/dist/packages/player/src/composition/Disposables.js +31 -0
  173. package/dist/packages/player/src/composition/browserPorts.js +46 -0
  174. package/dist/packages/player/src/composition/buildPipeline.js +153 -0
  175. package/dist/packages/player/src/composition/ensureDecodable.js +63 -0
  176. package/dist/packages/player/src/composition/openInputs.js +179 -0
  177. package/dist/packages/player/src/composition/openRecording.js +42 -0
  178. package/dist/packages/player/src/controls/ChoiceMenu.js +113 -0
  179. package/dist/packages/player/src/controls/PictureMenus.js +47 -0
  180. package/dist/packages/player/src/controls/SeekBar.js +125 -0
  181. package/dist/packages/player/src/controls/SoundControls.js +41 -0
  182. package/dist/packages/player/src/controls/TransportButtons.js +31 -0
  183. package/dist/packages/player/src/controls/ViewGestures.js +136 -0
  184. package/dist/packages/player/src/controls/Wording.js +78 -0
  185. package/dist/packages/player/src/controls/controlParts.js +36 -0
  186. package/dist/packages/player/src/controls/controls.js +4 -0
  187. package/dist/packages/player/src/controls/controlsBar.js +23 -0
  188. package/dist/packages/player/src/controls/controlsMarkup.js +85 -0
  189. package/dist/packages/player/src/controls/customControls.js +59 -0
  190. package/dist/packages/player/src/controls/formatTime.js +19 -0
  191. package/dist/packages/player/src/controls/icons.js +40 -0
  192. package/dist/packages/player/src/controls/keyboard.js +118 -0
  193. package/dist/packages/player/src/controls/messages.js +94 -0
  194. package/dist/packages/player/src/controls/parseMarkup.js +31 -0
  195. package/dist/packages/player/src/controls/viewButtons.js +14 -0
  196. package/dist/packages/player/src/element/ElementLoads.js +119 -0
  197. package/dist/packages/player/src/element/FullscreenToggle.js +39 -0
  198. package/dist/packages/player/src/element/GyroViewElement.js +313 -0
  199. package/dist/packages/player/src/element/IdleWatcher.js +71 -0
  200. package/dist/packages/player/src/element/TypedEventElement.js +22 -0
  201. package/dist/packages/player/src/element/accessibleRegion.js +19 -0
  202. package/dist/packages/player/src/element/attributeNames.js +51 -0
  203. package/dist/packages/player/src/element/attributes.js +101 -0
  204. package/dist/packages/player/src/element/defineGyroView.js +21 -0
  205. package/dist/packages/player/src/element/earlyProperties.js +36 -0
  206. package/dist/packages/player/src/element/elementSource.js +23 -0
  207. package/dist/packages/player/src/element/liveSettings.js +138 -0
  208. package/dist/packages/player/src/element/playbackAttributes.js +53 -0
  209. package/dist/packages/player/src/element/playerEventMirror.js +33 -0
  210. package/dist/packages/player/src/element/reflectedProperties.js +78 -0
  211. package/dist/packages/player/src/element/styles.js +4 -0
  212. package/dist/packages/player/src/element/template.js +47 -0
  213. package/dist/packages/player/src/index.js +10 -0
  214. package/dist/packages/player/src/inspectRecording.js +22 -0
  215. package/dist/packages/player/src/player/DrawingBufferFit.js +77 -0
  216. package/dist/packages/player/src/player/FrameLoop.js +40 -0
  217. package/dist/packages/player/src/player/PictureSettings.js +60 -0
  218. package/dist/packages/player/src/player/Player.js +377 -0
  219. package/dist/packages/player/src/player/PlayerEvents.js +28 -0
  220. package/dist/packages/player/src/player/PlayerPhase.js +21 -0
  221. package/dist/packages/player/src/player/PlayerSound.js +61 -0
  222. package/dist/packages/player/src/player/PlayerView.js +113 -0
  223. package/dist/packages/player/src/player/SessionRelay.js +66 -0
  224. package/dist/packages/player/src/player/ensureFinite.js +26 -0
  225. package/dist/packages/player/src/player/loadRecording.js +65 -0
  226. package/dist/packages/player/src/player/transportEvents.js +29 -0
  227. package/dist/standalone.js +4919 -0
  228. 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
@@ -0,0 +1,3 @@
1
+ // @bubo-squared/gyroview/define only registers <gyro-view>; its types are the package's,
2
+ // `document`'s knowledge of the element included.
3
+ import './index.js';
package/dist/define.js ADDED
@@ -0,0 +1,4 @@
1
+ import { defineGyroView } from "./packages/player/src/element/defineGyroView.js";
2
+ //#region src/define.ts
3
+ defineGyroView();
4
+ //#endregion