@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
@@ -0,0 +1,313 @@
1
+ import { defineBooleanProperties, defineKeywordProperties, defineStringProperties, propertyNameOf } from "./reflectedProperties.js";
2
+ import { ensureFinite } from "../player/ensureFinite.js";
3
+ import { bindKeyboard } from "../controls/keyboard.js";
4
+ import { ViewGestures } from "../controls/ViewGestures.js";
5
+ import { togglePlayback } from "../controls/customControls.js";
6
+ import { createBrowserPlayer } from "../browserPlayer.js";
7
+ import { OBSERVED_ATTRIBUTES, PlaybackAttribute, SourceAttribute, ViewAttribute } from "./attributeNames.js";
8
+ import { GAIN_MATCH, PRELOAD, unreadableAngleWarning, viewAfterAttribute } from "./attributes.js";
9
+ import { ElementLoads } from "./ElementLoads.js";
10
+ import { FullscreenToggle } from "./FullscreenToggle.js";
11
+ import { IdleWatcher } from "./IdleWatcher.js";
12
+ import { applyPlaybackAttribute } from "./playbackAttributes.js";
13
+ import { describeUnlessTheAuthorDid, renameUnlessTheAuthorDid } from "./accessibleRegion.js";
14
+ import { applyEarlyProperties, takeEarlyProperties } from "./earlyProperties.js";
15
+ import { LIVE_SETTING_NAMES, defineLiveSettings, pictureQualityFrom, stabilizationModeFrom, viewModeFrom } from "./liveSettings.js";
16
+ import { queryShadow } from "../controls/controlParts.js";
17
+ import { mirrorPlayerEvents } from "./playerEventMirror.js";
18
+ import { renderShadowTree } from "./template.js";
19
+ import { TypedEventElement } from "./TypedEventElement.js";
20
+ import { bindControlsBar } from "../controls/controlsBar.js";
21
+ import { Wording } from "../controls/Wording.js";
22
+ //#region ../../packages/player/src/element/GyroViewElement.ts
23
+ /**
24
+ * Attributes whose properties mirror them, as `img.src` does: what to play and how to present
25
+ * it. The live settings (stabilization, view mode, view angles, sound, loop) have properties of
26
+ * their own that report the player's current state.
27
+ */
28
+ var STRING_ATTRIBUTES = [...Object.values(SourceAttribute), PlaybackAttribute.Poster];
29
+ var KEYWORD_ATTRIBUTES = [PRELOAD, GAIN_MATCH];
30
+ var BOOLEAN_ATTRIBUTES = [PlaybackAttribute.Autoplay, PlaybackAttribute.Controls];
31
+ var SOURCE_ATTRIBUTES = Object.values(SourceAttribute);
32
+ /**
33
+ * The properties a page may set before the element is defined, all kept for it.
34
+ */
35
+ var PUBLIC_PROPERTIES = [
36
+ ...[
37
+ ...STRING_ATTRIBUTES,
38
+ ...KEYWORD_ATTRIBUTES.map(({ name }) => name),
39
+ ...BOOLEAN_ATTRIBUTES
40
+ ].map((name) => propertyNameOf(name)),
41
+ ...LIVE_SETTING_NAMES,
42
+ "currentTime",
43
+ "messages"
44
+ ];
45
+ var VIEW_ATTRIBUTES = Object.values(ViewAttribute);
46
+ /**
47
+ * `<gyro-view>`: the player as an element. Attributes name what to play and configure the
48
+ * settings; the settings' properties report what is in effect now, as a media element's `muted`
49
+ * does; the player's events are dispatched as `CustomEvent`s of the same name with the payload
50
+ * in `detail`. Facade over {@link Player}, the controls and the gestures (ADR 0016).
51
+ */
52
+ var GyroViewElement = class extends TypedEventElement {
53
+ static observedAttributes = OBSERVED_ATTRIBUTES;
54
+ /**
55
+ * Properties the page set before the element was defined, kept until it is connected.
56
+ */
57
+ earlyProperties;
58
+ player;
59
+ loads;
60
+ wording = new Wording();
61
+ fullscreen = new FullscreenToggle(this);
62
+ idle;
63
+ posterImage;
64
+ constructor() {
65
+ super();
66
+ this.earlyProperties = takeEarlyProperties(this, PUBLIC_PROPERTIES);
67
+ defineStringProperties(this, STRING_ATTRIBUTES);
68
+ defineKeywordProperties(this, KEYWORD_ATTRIBUTES);
69
+ defineBooleanProperties(this, BOOLEAN_ATTRIBUTES);
70
+ const shadow = this.attachShadow({ mode: "open" });
71
+ renderShadowTree(shadow);
72
+ this.wording.write(shadow);
73
+ const canvas = queryShadow(shadow, "canvas", HTMLCanvasElement);
74
+ const audio = queryShadow(shadow, "audio", HTMLAudioElement);
75
+ this.posterImage = queryShadow(shadow, ".poster", HTMLImageElement);
76
+ this.player = createBrowserPlayer({
77
+ canvas,
78
+ audio
79
+ });
80
+ this.loads = new ElementLoads(this, this.player);
81
+ defineLiveSettings(this, this.player);
82
+ const host = this.controlsHost();
83
+ bindControlsBar(shadow, host);
84
+ new ViewGestures(canvas, this.player, this.onPictureTap);
85
+ bindKeyboard(this, host);
86
+ this.idle = new IdleWatcher(this, () => this.player.status === "playing");
87
+ const { idle, wording } = this;
88
+ mirrorPlayerEvents(this.player, {
89
+ element: this,
90
+ shadow,
91
+ idle,
92
+ wording
93
+ });
94
+ }
95
+ /**
96
+ * Where the player is: `idle` or `loading`, then the loaded recording's playback state.
97
+ */
98
+ get status() {
99
+ return this.player.status;
100
+ }
101
+ /**
102
+ * What the player learned about the loaded recording; undefined until it is ready.
103
+ */
104
+ get metadata() {
105
+ return this.player.metadata;
106
+ }
107
+ /**
108
+ * The media time shown, in seconds; setting it seeks there exactly.
109
+ */
110
+ get currentTime() {
111
+ return this.player.currentTime;
112
+ }
113
+ set currentTime(time) {
114
+ this.seek(time);
115
+ }
116
+ /**
117
+ * The loaded recording's length in seconds; 0 without one.
118
+ */
119
+ get duration() {
120
+ return this.player.duration;
121
+ }
122
+ /**
123
+ * True unless playback is under way or waiting for data to go on, as a media element's.
124
+ */
125
+ get paused() {
126
+ return this.player.isPaused;
127
+ }
128
+ /**
129
+ * Where the normal view looks: yaw and pitch in degrees, and the horizontal field of view.
130
+ */
131
+ get view() {
132
+ return this.player.view;
133
+ }
134
+ /**
135
+ * Every word the element shows or says to assistive technology. Setting it replaces any of
136
+ * them, table by table (`labels`, `stabilizationModes`, `viewModes`, `errors`); the others keep
137
+ * their English defaults, and `null` brings them all back.
138
+ */
139
+ get messages() {
140
+ return this.wording.current;
141
+ }
142
+ set messages(overrides) {
143
+ const previousName = this.wording.current.labels.player;
144
+ this.wording.replace(overrides);
145
+ if (this.shadowRoot) this.wording.write(this.shadowRoot);
146
+ renameUnlessTheAuthorDid(this, previousName, this.wording.current.labels.player);
147
+ }
148
+ connectedCallback() {
149
+ describeUnlessTheAuthorDid(this, this.wording.current.labels.player);
150
+ applyEarlyProperties(this, this.earlyProperties, this.warn);
151
+ this.dataset["status"] = this.player.status;
152
+ this.idle.start();
153
+ this.loads.connected();
154
+ }
155
+ disconnectedCallback() {
156
+ this.idle.stop();
157
+ this.loads.disconnected();
158
+ }
159
+ attributeChangedCallback(name, _previous, value) {
160
+ if (SOURCE_ATTRIBUTES.includes(name)) this.loads.sourceChanged();
161
+ else if (VIEW_ATTRIBUTES.includes(name)) {
162
+ this.player.setView(viewAfterAttribute(this.player.view, name, value));
163
+ const warning = unreadableAngleWarning(name, value);
164
+ if (warning !== void 0) this.warn(warning);
165
+ } else {
166
+ const targets = {
167
+ player: this.player,
168
+ posterImage: this.posterImage,
169
+ warn: this.warn
170
+ };
171
+ applyPlaybackAttribute(targets, name, value);
172
+ }
173
+ }
174
+ /**
175
+ * Starts playing, waiting for a load in progress, or one the attributes set just now asked
176
+ * for; rejects when the browser refuses to start.
177
+ */
178
+ async play() {
179
+ await this.loads.settled();
180
+ await this.player.play();
181
+ }
182
+ /**
183
+ * Pauses, keeping the frame on screen.
184
+ */
185
+ pause() {
186
+ this.player.pause();
187
+ }
188
+ /**
189
+ * Pauses and goes back to the start.
190
+ */
191
+ stop() {
192
+ this.player.stop();
193
+ }
194
+ /**
195
+ * Seeks exactly to `time` seconds; right after a new `src`, the new recording starts there.
196
+ */
197
+ seek(time) {
198
+ ensureFinite(time, "time");
199
+ this.loads.seek(time);
200
+ }
201
+ /**
202
+ * Seeks to the key frame at or before `time`: quick to show while a seek bar is dragged.
203
+ */
204
+ scrub(time) {
205
+ return this.player.scrub(time);
206
+ }
207
+ /**
208
+ * Points the normal view at `yaw` and `pitch`, in degrees: yaw positive to the right, pitch
209
+ * positive up.
210
+ */
211
+ lookAt(yaw, pitch) {
212
+ this.player.lookAt(yaw, pitch);
213
+ }
214
+ /**
215
+ * Brings the current view mode back to how it starts, the others keeping their framing.
216
+ */
217
+ resetView() {
218
+ this.player.resetView();
219
+ }
220
+ /**
221
+ * Zooms by `steps` (positive zooms in, each step by a factor of 1.1, within each view mode's
222
+ * limits) toward `focus`, a point of the picture as fractions of its size; about the centre
223
+ * when none is given.
224
+ */
225
+ zoom(steps, focus) {
226
+ this.player.zoom(steps, focus);
227
+ }
228
+ /**
229
+ * Stabilizes the picture in `mode` (`off`, `lock`, `horizon`, `follow`); any other value,
230
+ * an unset one included, is refused.
231
+ */
232
+ setStabilization(mode) {
233
+ this.player.setStabilization(stabilizationModeFrom(mode));
234
+ }
235
+ /**
236
+ * Shows the picture in `mode` (`raw-lenses`, `equirectangular`, `normal`); any other value,
237
+ * an unset one included, is refused.
238
+ */
239
+ setViewMode(mode) {
240
+ this.player.setViewMode(viewModeFrom(mode));
241
+ }
242
+ /**
243
+ * Reads the lens images as `quality` says (`fast`, `balanced`, `high`); any other value, an
244
+ * unset one included, is refused.
245
+ */
246
+ setQuality(quality) {
247
+ this.player.setQuality(pictureQualityFrom(quality));
248
+ }
249
+ /**
250
+ * Fills the screen with the player, through the Fullscreen API or pinned over the page, or
251
+ * leaves it.
252
+ */
253
+ toggleFullscreen() {
254
+ return this.fullscreen.toggle();
255
+ }
256
+ /**
257
+ * Loads what the attributes (or the files handed in) name: the change already waiting to be
258
+ * read, or else now; out of the document, once connected. Resolves once the recording is
259
+ * ready; rejects with the failure, which is dispatched as an `error` event too.
260
+ */
261
+ load() {
262
+ return this.loads.load();
263
+ }
264
+ /**
265
+ * Plays local files instead of the `src` attributes, until `src` or `src2` change.
266
+ */
267
+ loadFiles(files) {
268
+ this.loads.loadFiles(files);
269
+ }
270
+ /**
271
+ * What the controls and the keyboard ask of the element. They live as long as the element:
272
+ * their listeners sit on its own shadow tree and host, and on its player.
273
+ */
274
+ controlsHost() {
275
+ return {
276
+ player: this.player,
277
+ wording: this.wording,
278
+ togglePlay: this.togglePlayback,
279
+ toggleFullscreen: () => {
280
+ this.toggleFullscreen();
281
+ },
282
+ warn: this.warn,
283
+ isFullscreen: () => this.fullscreen.isActive,
284
+ exitFullscreen: () => {
285
+ this.fullscreen.exit();
286
+ }
287
+ };
288
+ }
289
+ /**
290
+ * A tap on the picture toggles playback, except a touch that brought hidden controls back:
291
+ * touch has no hover to reveal them, so that tap is the viewer asking to see them. Without
292
+ * controls there is nothing to reveal, and every tap toggles.
293
+ */
294
+ onPictureTap = (pointerType) => {
295
+ const isRevealingControls = this.controls && this.idle.wasIdleAtLastPress;
296
+ if (pointerType !== "mouse" && isRevealingControls) return;
297
+ this.togglePlayback();
298
+ };
299
+ /**
300
+ * Pauses, or starts playing and reports a refused start as a warning.
301
+ */
302
+ togglePlayback = () => {
303
+ togglePlayback(this.player);
304
+ };
305
+ warn = (warning) => {
306
+ this.dispatchEvent(new CustomEvent("warning", {
307
+ detail: warning,
308
+ composed: true
309
+ }));
310
+ };
311
+ };
312
+ //#endregion
313
+ export { GyroViewElement };
@@ -0,0 +1,71 @@
1
+ //#region ../../packages/player/src/element/IdleWatcher.ts
2
+ var IDLE_ATTRIBUTE = "data-idle";
3
+ var IDLE_DELAY_MS = 2500;
4
+ var ACTIVITY_EVENTS = [
5
+ "pointermove",
6
+ "pointerdown",
7
+ "keydown",
8
+ "focusin"
9
+ ];
10
+ /**
11
+ * Activity is heard on its way in, before any control inside can keep it to itself.
12
+ */
13
+ var ON_THE_WAY_IN = { capture: true };
14
+ /**
15
+ * Marks the element idle when the viewer has left it alone for a while and `shouldHide` agrees
16
+ * (playing, not paused), so the controls can fade; any activity brings them back.
17
+ */
18
+ var IdleWatcher = class {
19
+ element;
20
+ shouldHide;
21
+ timer;
22
+ wasIdleAtPress = false;
23
+ constructor(element, shouldHide) {
24
+ this.element = element;
25
+ this.shouldHide = shouldHide;
26
+ }
27
+ /**
28
+ * Whether the controls were hidden when the last press began: on touch, which has no hover,
29
+ * such a press is how the viewer brings them back.
30
+ */
31
+ get wasIdleAtLastPress() {
32
+ return this.wasIdleAtPress;
33
+ }
34
+ start() {
35
+ this.element.addEventListener("pointerdown", this.onPress, ON_THE_WAY_IN);
36
+ for (const name of ACTIVITY_EVENTS) this.element.addEventListener(name, this.onActivity, ON_THE_WAY_IN);
37
+ this.onActivity();
38
+ }
39
+ stop() {
40
+ for (const name of ACTIVITY_EVENTS) this.element.removeEventListener(name, this.onActivity, ON_THE_WAY_IN);
41
+ this.element.removeEventListener("pointerdown", this.onPress, ON_THE_WAY_IN);
42
+ this.clearTimer();
43
+ this.element.removeAttribute(IDLE_ATTRIBUTE);
44
+ }
45
+ /**
46
+ * Re-evaluates after a state change, so pausing shows the controls at once.
47
+ */
48
+ refresh() {
49
+ if (!this.shouldHide()) this.element.removeAttribute(IDLE_ATTRIBUTE);
50
+ this.restart();
51
+ }
52
+ onPress = () => {
53
+ this.wasIdleAtPress = this.element.hasAttribute(IDLE_ATTRIBUTE);
54
+ };
55
+ onActivity = () => {
56
+ this.element.removeAttribute(IDLE_ATTRIBUTE);
57
+ this.restart();
58
+ };
59
+ restart() {
60
+ this.clearTimer();
61
+ this.timer = setTimeout(() => {
62
+ if (this.shouldHide()) this.element.setAttribute(IDLE_ATTRIBUTE, "");
63
+ }, IDLE_DELAY_MS);
64
+ }
65
+ clearTimer() {
66
+ if (this.timer !== void 0) clearTimeout(this.timer);
67
+ this.timer = void 0;
68
+ }
69
+ };
70
+ //#endregion
71
+ export { IdleWatcher };
@@ -0,0 +1,22 @@
1
+ //#region ../../packages/player/src/element/TypedEventElement.ts
2
+ /**
3
+ * `HTMLElement` in a browser; elsewhere a stand-in, so that a server rendering the page, or a
4
+ * script importing the package for `inspectRecording`, can evaluate this module. The element is
5
+ * only ever constructed where `customElements` defined it: in a browser.
6
+ */
7
+ var ElementBase = typeof HTMLElement === "function" ? HTMLElement : Object;
8
+ /**
9
+ * The HTMLElement `<gyro-view>` builds on, whose `addEventListener` and `removeEventListener`
10
+ * know the events it fires, where the DOM's own map would name other types. The overrides only
11
+ * pass through.
12
+ */
13
+ var TypedEventElement = class extends ElementBase {
14
+ addEventListener(type, listener, options) {
15
+ super.addEventListener(type, listener, options);
16
+ }
17
+ removeEventListener(type, listener, options) {
18
+ super.removeEventListener(type, listener, options);
19
+ }
20
+ };
21
+ //#endregion
22
+ export { TypedEventElement };
@@ -0,0 +1,19 @@
1
+ //#region ../../packages/player/src/element/accessibleRegion.ts
2
+ /**
3
+ * The element takes focus and keys, so assistive technology needs to know what it is: a region
4
+ * called `name`, unless the page gave it a role, a name or a tab order of its own.
5
+ */
6
+ function describeUnlessTheAuthorDid(element, name) {
7
+ if (!element.hasAttribute("tabindex")) element.tabIndex = 0;
8
+ if (!element.hasAttribute("role")) element.setAttribute("role", "region");
9
+ if (!(element.hasAttribute("aria-label") || element.hasAttribute("aria-labelledby"))) element.setAttribute("aria-label", name);
10
+ }
11
+ /**
12
+ * The element's name after a change of words: the new one where it bore its own name, the
13
+ * page's where the page named it.
14
+ */
15
+ function renameUnlessTheAuthorDid(element, previousName, name) {
16
+ if (element.getAttribute("aria-label") === previousName) element.setAttribute("aria-label", name);
17
+ }
18
+ //#endregion
19
+ export { describeUnlessTheAuthorDid, renameUnlessTheAuthorDid };
@@ -0,0 +1,51 @@
1
+ //#region ../../packages/player/src/element/attributeNames.ts
2
+ /**
3
+ * The names of `<gyro-view>`'s attributes, with no dependencies, so an embedding page's snippet can
4
+ * spell them without carrying the player. Published as `@gyroview/player/attributes`.
5
+ */
6
+ /**
7
+ * The attributes `<gyro-view>` understands. `Source` ones name what to play; changing any of
8
+ * them reloads. `View` ones move the picture without reloading.
9
+ */
10
+ var SourceAttribute = {
11
+ Src: "src",
12
+ Src2: "src2"
13
+ };
14
+ var ViewAttribute = {
15
+ FieldOfView: "fov",
16
+ Yaw: "yaw",
17
+ Pitch: "pitch"
18
+ };
19
+ var PlaybackAttribute = {
20
+ Autoplay: "autoplay",
21
+ /**
22
+ * `none` keeps the decoders idle until play; anything else (the default) shows the first frame.
23
+ */
24
+ Preload: "preload",
25
+ /**
26
+ * `off` leaves the lenses' exposure as recorded; anything else (the default) matches them.
27
+ */
28
+ GainMatch: "gain-match",
29
+ Muted: "muted",
30
+ Loop: "loop",
31
+ Stabilization: "stabilization",
32
+ /**
33
+ * `raw-lenses`, `equirectangular` or `normal`: what the picture shows (ADR 0015); the raw
34
+ * lenses until set (ADR 0022).
35
+ */
36
+ ViewMode: "view-mode",
37
+ /**
38
+ * `fast`, `balanced` or `high`: how finely the lens images are read and how many device
39
+ * pixels are drawn; `balanced` until set.
40
+ */
41
+ Quality: "quality",
42
+ Controls: "controls",
43
+ Poster: "poster"
44
+ };
45
+ var OBSERVED_ATTRIBUTES = [
46
+ ...Object.values(SourceAttribute),
47
+ ...Object.values(ViewAttribute),
48
+ ...Object.values(PlaybackAttribute)
49
+ ];
50
+ //#endregion
51
+ export { OBSERVED_ATTRIBUTES, PlaybackAttribute, SourceAttribute, ViewAttribute };
@@ -0,0 +1,101 @@
1
+ import { keywordOf } from "./reflectedProperties.js";
2
+ import { PlaybackAttribute, SourceAttribute, ViewAttribute } from "./attributeNames.js";
3
+ //#region ../../packages/player/src/element/attributes.ts
4
+ /**
5
+ * The source the attributes describe, or nothing when `src` is absent. URLs resolve against
6
+ * the document, as an image's would.
7
+ */
8
+ function sourceFromAttributes(read, baseUrl) {
9
+ const main = urlInputOf(read(SourceAttribute.Src), baseUrl);
10
+ return main && {
11
+ main,
12
+ second: urlInputOf(read(SourceAttribute.Src2), baseUrl)
13
+ };
14
+ }
15
+ function urlInputOf(value, baseUrl) {
16
+ const trimmed = value?.trim() ?? "";
17
+ return trimmed === "" ? void 0 : { url: resolvedOrAsWritten(trimmed, baseUrl) };
18
+ }
19
+ /**
20
+ * The URL resolved against the document; one that does not parse goes on as written, so the
21
+ * load fails on it and reports it as an `error`, like any source it cannot reach.
22
+ */
23
+ function resolvedOrAsWritten(url, baseUrl) {
24
+ try {
25
+ return new URL(url, baseUrl).href;
26
+ } catch {
27
+ return url;
28
+ }
29
+ }
30
+ var VIEW_ANGLES = {
31
+ [ViewAttribute.FieldOfView]: "fieldOfView",
32
+ [ViewAttribute.Yaw]: "yaw",
33
+ [ViewAttribute.Pitch]: "pitch"
34
+ };
35
+ /**
36
+ * The view after one view attribute changed: the angle it names replaces the view's; an absent
37
+ * or unreadable value leaves the view as it is. The other angles are not read again, so what the
38
+ * viewer changed since is kept. The player clamps the view it is given.
39
+ */
40
+ function viewAfterAttribute(view, name, value) {
41
+ const angle = VIEW_ANGLES[name];
42
+ const parsed = parseNumber(value);
43
+ return angle === void 0 || parsed === void 0 ? view : {
44
+ ...view,
45
+ [angle]: parsed
46
+ };
47
+ }
48
+ /**
49
+ * HTML boolean attributes are true by presence, whatever their value.
50
+ */
51
+ function isBooleanAttributeSet(value) {
52
+ return value !== null;
53
+ }
54
+ function parseNumber(value) {
55
+ if (value === null || value.trim() === "") return void 0;
56
+ const parsed = Number(value);
57
+ return Number.isFinite(parsed) ? parsed : void 0;
58
+ }
59
+ /**
60
+ * The `warning` for an attribute naming a choice the element does not know.
61
+ */
62
+ function ignoredChoiceWarning(attribute, value, choices) {
63
+ return {
64
+ code: "ignored-attribute",
65
+ message: `ignoring ${attribute}="${value}"; expected one of ${choices.join(", ")}`
66
+ };
67
+ }
68
+ /**
69
+ * The `warning` for a view attribute whose value is no number of degrees; none for one that is,
70
+ * or for an absent attribute, which leaves the view as it is.
71
+ */
72
+ function unreadableAngleWarning(attribute, value) {
73
+ return value === null || parseNumber(value) !== void 0 ? void 0 : {
74
+ code: "ignored-attribute",
75
+ message: `ignoring ${attribute}="${value}"; expected a number of degrees`
76
+ };
77
+ }
78
+ /**
79
+ * `none` keeps the decoders idle until play; `auto`, the default, shows the first frame at once.
80
+ */
81
+ var PRELOAD = {
82
+ name: PlaybackAttribute.Preload,
83
+ keywords: ["none", "auto"],
84
+ fallback: "auto"
85
+ };
86
+ /**
87
+ * `off` leaves the lenses' exposure as recorded; `on`, the default, matches it along the seam.
88
+ */
89
+ var GAIN_MATCH = {
90
+ name: PlaybackAttribute.GainMatch,
91
+ keywords: ["on", "off"],
92
+ fallback: "on"
93
+ };
94
+ function shouldPreload(value) {
95
+ return keywordOf(PRELOAD, value) === "auto";
96
+ }
97
+ function shouldMatchGains(value) {
98
+ return keywordOf(GAIN_MATCH, value) === "on";
99
+ }
100
+ //#endregion
101
+ export { GAIN_MATCH, PRELOAD, ignoredChoiceWarning, isBooleanAttributeSet, parseNumber, shouldMatchGains, shouldPreload, sourceFromAttributes, unreadableAngleWarning, viewAfterAttribute };
@@ -0,0 +1,21 @@
1
+ import { lazy } from "../../../core/src/shared/lazy.js";
2
+ import "../../../core/src/index.js";
3
+ import { GyroViewElement } from "./GyroViewElement.js";
4
+ //#region ../../packages/player/src/element/defineGyroView.ts
5
+ var GYRO_VIEW_TAG = "gyro-view";
6
+ /**
7
+ * Registers `<gyro-view>` once. A page that loads the package twice keeps the first definition,
8
+ * and hears once that another copy was there first, which may be another version. Without a
9
+ * custom element registry (a server rendering the page) there is nothing to register.
10
+ */
11
+ function defineGyroView() {
12
+ if (typeof customElements === "undefined") return;
13
+ const defined = customElements.get(GYRO_VIEW_TAG);
14
+ if (defined === void 0) customElements.define(GYRO_VIEW_TAG, GyroViewElement);
15
+ else if (defined !== GyroViewElement) warnOfAnotherCopy();
16
+ }
17
+ var warnOfAnotherCopy = lazy(() => {
18
+ console.warn(`<${GYRO_VIEW_TAG}> was defined by another copy of gyroview; that copy's element is used`);
19
+ });
20
+ //#endregion
21
+ export { GYRO_VIEW_TAG, defineGyroView };
@@ -0,0 +1,36 @@
1
+ import { messageOf } from "../../../core/src/shared/errors/GyroViewError.js";
2
+ import "../../../core/src/index.js";
3
+ //#region ../../packages/player/src/element/earlyProperties.ts
4
+ /**
5
+ * Properties a page set on the element before its definition ran (a classic script ahead of the
6
+ * module, a framework's property binding) sit on the plain element as its own; the element's
7
+ * accessors would replace or shadow them. They are taken off as the element is built, to be set
8
+ * again through the accessors once it is connected.
9
+ */
10
+ function takeEarlyProperties(element, names) {
11
+ const early = /* @__PURE__ */ new Map();
12
+ for (const name of names) {
13
+ if (!Object.hasOwn(element, name)) continue;
14
+ early.set(name, Reflect.get(element, name));
15
+ Reflect.deleteProperty(element, name);
16
+ }
17
+ return early;
18
+ }
19
+ /**
20
+ * Sets the properties taken off again, now through the element's accessors, and forgets them. A
21
+ * value its setter refuses is a warning: the rest still apply and the element still starts.
22
+ */
23
+ function applyEarlyProperties(element, early, warn) {
24
+ const entries = [...early];
25
+ early.clear();
26
+ for (const [name, value] of entries) try {
27
+ Reflect.set(element, name, value);
28
+ } catch (error) {
29
+ warn({
30
+ code: "refused-property",
31
+ message: `${name} set before the element was defined was refused: ${messageOf(error)}`
32
+ });
33
+ }
34
+ }
35
+ //#endregion
36
+ export { applyEarlyProperties, takeEarlyProperties };
@@ -0,0 +1,23 @@
1
+ import { sourceFromAttributes } from "./attributes.js";
2
+ //#region ../../packages/player/src/element/elementSource.ts
3
+ /**
4
+ * What the element should play: the files handed to it, if any, otherwise what its attributes
5
+ * name.
6
+ */
7
+ function elementSourceOf(read, baseUrl, files) {
8
+ return files ? fileSourceOf(files) : sourceFromAttributes(read, baseUrl);
9
+ }
10
+ function fileSourceOf(files) {
11
+ return {
12
+ main: {
13
+ blob: files.main,
14
+ name: files.main.name
15
+ },
16
+ second: files.second && {
17
+ blob: files.second,
18
+ name: files.second.name
19
+ }
20
+ };
21
+ }
22
+ //#endregion
23
+ export { elementSourceOf };