@bvdmitri/gyroview 0.0.0-stage → 0.9.0-cutaway.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +402 -0
- package/LICENSE +21 -0
- package/README.md +313 -2
- package/dist/define.d.ts +3 -0
- package/dist/define.js +4 -0
- package/dist/index.d.ts +1204 -0
- package/dist/index.js +12 -0
- package/dist/packages/adapters/blob/src/BlobRandomAccessSource.js +36 -0
- package/dist/packages/adapters/fetch/src/HttpByteStream.js +173 -0
- package/dist/packages/adapters/fetch/src/HttpRangeSource.js +37 -0
- package/dist/packages/adapters/fetch/src/HttpResource.js +227 -0
- package/dist/packages/adapters/fetch/src/HttpResourceLocator.js +35 -0
- package/dist/packages/adapters/fetch/src/contentRange.js +15 -0
- package/dist/packages/adapters/fetch/src/httpRequest.js +136 -0
- package/dist/packages/adapters/fetch/src/passingFailures.js +23 -0
- package/dist/packages/adapters/fetch/src/rangeFailures.js +16 -0
- package/dist/packages/adapters/fetch/src/recordingVersion.js +37 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyAudioPackager.js +162 -0
- package/dist/packages/adapters/mediabunny/src/MediabunnyCodecReader.js +93 -0
- package/dist/packages/adapters/mediabunny/src/SegmentChannel.js +135 -0
- package/dist/packages/adapters/mediabunny/src/bufferSources.js +12 -0
- package/dist/packages/adapters/mediabunny/src/decoderConfigurations.js +43 -0
- package/dist/packages/adapters/mediabunny/src/trackColour.js +20 -0
- package/dist/packages/adapters/mse-audio/src/MediaSourceAudioClock.js +138 -0
- package/dist/packages/adapters/mse-audio/src/SourceBufferFeeder.js +263 -0
- package/dist/packages/adapters/mse-audio/src/events.js +26 -0
- package/dist/packages/adapters/mse-audio/src/mediaSourceSupport.js +81 -0
- package/dist/packages/adapters/three/src/ThreeFrameRenderer.js +215 -0
- package/dist/packages/adapters/three/src/compileAndProve.js +14 -0
- package/dist/packages/adapters/three/src/conversionUniforms.js +60 -0
- package/dist/packages/adapters/three/src/drawSchedules.js +13 -0
- package/dist/packages/adapters/three/src/fullscreenPass.js +52 -0
- package/dist/packages/adapters/three/src/glslLiterals.js +10 -0
- package/dist/packages/adapters/three/src/lensTextures.js +34 -0
- package/dist/packages/adapters/three/src/matrixCorrections.js +34 -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/rendererParts.js +108 -0
- package/dist/packages/adapters/three/src/rendererUniforms.js +176 -0
- package/dist/packages/adapters/three/src/samplingStrategies.js +26 -0
- package/dist/packages/adapters/three/src/scissorBox.js +20 -0
- package/dist/packages/adapters/three/src/seamMeter/SeamMeterPass.js +85 -0
- package/dist/packages/adapters/three/src/seamMeter/rowMeans.js +42 -0
- package/dist/packages/adapters/three/src/shaderPrograms.js +68 -0
- package/dist/packages/adapters/three/src/shaders/analysis.frag.js +4 -0
- package/dist/packages/adapters/three/src/shaders/displayConversion.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/threeMatrix.js +10 -0
- package/dist/packages/adapters/three/src/webglRenderer.js +37 -0
- package/dist/packages/adapters/webcodecs/src/WebCodecsVideoDecoderPort.js +152 -0
- package/dist/packages/adapters/webcodecs/src/colorSpaceOf.js +32 -0
- package/dist/packages/core/src/application/download/BlockStore.js +97 -0
- package/dist/packages/core/src/application/download/DownloadedAudioSamples.js +50 -0
- package/dist/packages/core/src/application/download/DownloadedVideoTrack.js +122 -0
- package/dist/packages/core/src/application/download/FileDownload.js +208 -0
- package/dist/packages/core/src/application/download/RecordingBuffer.js +22 -0
- package/dist/packages/core/src/application/download/SampleCursor.js +89 -0
- package/dist/packages/core/src/application/download/SourceByteStream.js +46 -0
- package/dist/packages/core/src/application/download/Transfers.js +82 -0
- package/dist/packages/core/src/application/download/startFileDownload.js +37 -0
- package/dist/packages/core/src/application/gainMatching/GainMatching.js +76 -0
- package/dist/packages/core/src/application/gainMatching/GainMatchingFrameSink.js +80 -0
- package/dist/packages/core/src/application/gainMatching/referenceLensOf.js +18 -0
- package/dist/packages/core/src/application/playback/Buffering.js +54 -0
- package/dist/packages/core/src/application/playback/ClockStart.js +55 -0
- package/dist/packages/core/src/application/playback/ClockWatch.js +76 -0
- package/dist/packages/core/src/application/playback/DecodePipeline.js +234 -0
- package/dist/packages/core/src/application/playback/DecodeRun.js +108 -0
- package/dist/packages/core/src/application/playback/FramePairQueue.js +93 -0
- package/dist/packages/core/src/application/playback/FramePairer.js +77 -0
- package/dist/packages/core/src/application/playback/PictureOnScreen.js +56 -0
- package/dist/packages/core/src/application/playback/PlaybackSession.js +410 -0
- package/dist/packages/core/src/application/playback/SeekOrder.js +35 -0
- package/dist/packages/core/src/application/playback/SessionLifecycle.js +42 -0
- package/dist/packages/core/src/application/playback/StartGate.js +69 -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 +182 -0
- package/dist/packages/core/src/application/recording/frameTimesOf.js +21 -0
- package/dist/packages/core/src/application/recording/inspectLayout.js +21 -0
- package/dist/packages/core/src/application/recording/inspectRecording.js +125 -0
- package/dist/packages/core/src/application/recording/locateOtherLensFile.js +18 -0
- package/dist/packages/core/src/application/recording/motionOf.js +43 -0
- package/dist/packages/core/src/application/recording/readRecording.js +31 -0
- package/dist/packages/core/src/application/recording/readRecordingFiles.js +130 -0
- package/dist/packages/core/src/application/recording/readSampleTable.js +27 -0
- package/dist/packages/core/src/application/recording/timeRecording.js +57 -0
- package/dist/packages/core/src/application/stabilization/StabilizingFrameSink.js +33 -0
- package/dist/packages/core/src/domain/colour/DisplayConversion.js +137 -0
- package/dist/packages/core/src/domain/colour/TrackColour.js +38 -0
- package/dist/packages/core/src/domain/colour/gainMatch.js +64 -0
- package/dist/packages/core/src/domain/colour/matrixCorrection.js +76 -0
- package/dist/packages/core/src/domain/container/KeyframeRule.js +7 -0
- package/dist/packages/core/src/domain/container/SampleTable.js +29 -0
- package/dist/packages/core/src/domain/container/TrackSampleTable.js +96 -0
- package/dist/packages/core/src/domain/container/presentationOrder.js +10 -0
- package/dist/packages/core/src/domain/download/DownloadPolicy.js +84 -0
- package/dist/packages/core/src/domain/download/isReadyToResume.js +27 -0
- package/dist/packages/core/src/domain/download/planDownloads.js +175 -0
- package/dist/packages/core/src/domain/download/trackNeeds.js +32 -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/boxHeader.js +44 -0
- package/dist/packages/core/src/domain/format/boxes/scanBoxes.js +32 -0
- package/dist/packages/core/src/domain/format/calibration/CalibrationVersion.js +16 -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 +46 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/MeiCalibrationLayout.js +121 -0
- package/dist/packages/core/src/domain/format/calibration/layouts/PolynomialCalibrationLayout.js +46 -0
- package/dist/packages/core/src/domain/format/calibration/offsetTokens.js +94 -0
- package/dist/packages/core/src/domain/format/calibration/parseOffsetString.js +77 -0
- package/dist/packages/core/src/domain/format/calibration/selectCalibration.js +59 -0
- package/dist/packages/core/src/domain/format/calibration/v6TermReading.js +20 -0
- package/dist/packages/core/src/domain/format/captureOrigin.js +34 -0
- package/dist/packages/core/src/domain/format/constants.js +35 -0
- package/dist/packages/core/src/domain/format/info/calibrationSources.js +27 -0
- package/dist/packages/core/src/domain/format/info/infoFields.js +116 -0
- package/dist/packages/core/src/domain/format/info/parseInfoRecord.js +107 -0
- package/dist/packages/core/src/domain/format/info/readInfoRecord.js +14 -0
- package/dist/packages/core/src/domain/format/layout/detectLensLayout.js +133 -0
- package/dist/packages/core/src/domain/format/mp4/hevcCodecString.js +161 -0
- package/dist/packages/core/src/domain/format/mp4/keyframeRules.js +81 -0
- package/dist/packages/core/src/domain/format/mp4/movieBoxes.js +52 -0
- package/dist/packages/core/src/domain/format/mp4/mp4BoxTypes.js +46 -0
- package/dist/packages/core/src/domain/format/mp4/mp4Layouts.js +183 -0
- package/dist/packages/core/src/domain/format/mp4/parseMovie.js +72 -0
- package/dist/packages/core/src/domain/format/mp4/readTable.js +31 -0
- package/dist/packages/core/src/domain/format/mp4/sampleLocations.js +76 -0
- package/dist/packages/core/src/domain/format/mp4/sampleTiming.js +120 -0
- package/dist/packages/core/src/domain/format/mp4/trackHeaders.js +88 -0
- package/dist/packages/core/src/domain/format/naming/RecordingFileName.js +70 -0
- package/dist/packages/core/src/domain/format/records/TrailerRecords.js +100 -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 +38 -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 +89 -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 +138 -0
- package/dist/packages/core/src/domain/format/records/trim/parseTrimRecord.js +24 -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 +60 -0
- package/dist/packages/core/src/domain/motion/exposure/ExposureRecord.js +48 -0
- package/dist/packages/core/src/domain/motion/gyro/GyroTrack.js +70 -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 +178 -0
- package/dist/packages/core/src/domain/motion/mounting/Mounting.js +131 -0
- package/dist/packages/core/src/domain/motion/orientation/OrientationTrack.js +142 -0
- package/dist/packages/core/src/domain/motion/orientation/estimateGyroBias.js +72 -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 +85 -0
- package/dist/packages/core/src/domain/motion/timing/frameTimeSources.js +58 -0
- package/dist/packages/core/src/domain/motion/timing/resolveFrameTimes.js +68 -0
- package/dist/packages/core/src/domain/optics/EquidistantModel.js +34 -0
- package/dist/packages/core/src/domain/optics/MeiDistortion.js +27 -0
- package/dist/packages/core/src/domain/optics/MeiModel.js +27 -0
- package/dist/packages/core/src/domain/optics/PolynomialModel.js +39 -0
- package/dist/packages/core/src/domain/optics/lensPose.js +49 -0
- package/dist/packages/core/src/domain/optics/opticsConstants.js +5 -0
- package/dist/packages/core/src/domain/optics/scaledProjection.js +30 -0
- package/dist/packages/core/src/domain/playback/PlayerState.js +83 -0
- package/dist/packages/core/src/domain/rendition/RenditionSpan.js +70 -0
- package/dist/packages/core/src/domain/stitching/LensLayout.js +21 -0
- package/dist/packages/core/src/domain/stitching/StitchingSetup.js +87 -0
- package/dist/packages/core/src/domain/stitching/seamRing.js +4 -0
- package/dist/packages/core/src/domain/view/Framing.js +37 -0
- package/dist/packages/core/src/domain/view/Picture.js +12 -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 +54 -0
- package/dist/packages/core/src/domain/view/lensTilesView.js +64 -0
- package/dist/packages/core/src/domain/view/magnification.js +103 -0
- package/dist/packages/core/src/domain/view/motionLookView.js +100 -0
- package/dist/packages/core/src/domain/view/normalView.js +37 -0
- package/dist/packages/core/src/domain/view/panoramaView.js +95 -0
- package/dist/packages/core/src/domain/view/rectilinear.js +53 -0
- package/dist/packages/core/src/domain/view/screenLayout.js +129 -0
- package/dist/packages/core/src/domain/view/screenLook.js +74 -0
- package/dist/packages/core/src/domain/view/viewGestures.js +104 -0
- package/dist/packages/core/src/domain/view/viewModes.js +31 -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/async/iteration.js +24 -0
- package/dist/packages/core/src/shared/binary/ByteRange.js +50 -0
- package/dist/packages/core/src/shared/binary/ByteRangeSet.js +85 -0
- package/dist/packages/core/src/shared/binary/ByteReader.js +104 -0
- package/dist/packages/core/src/shared/binary/concatenated.js +15 -0
- package/dist/packages/core/src/shared/errors/GyroViewError.js +140 -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/mapRecord.js +11 -0
- package/dist/packages/core/src/shared/math/Matrix3.js +121 -0
- package/dist/packages/core/src/shared/math/Quaternion.js +133 -0
- package/dist/packages/core/src/shared/math/Vector3.js +58 -0
- package/dist/packages/core/src/shared/math/clamp.js +9 -0
- package/dist/packages/core/src/shared/math/countAtOrBelow.js +31 -0
- package/dist/packages/core/src/shared/math/minimum.js +17 -0
- package/dist/packages/core/src/shared/protobuf/ProtobufMessage.js +143 -0
- package/dist/packages/core/src/shared/protobuf/wireFormat.js +16 -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 +14 -0
- package/dist/packages/player/src/browserPlayer.js +20 -0
- package/dist/packages/player/src/choices.js +24 -0
- package/dist/packages/player/src/composition/AnimationFrameDraws.js +38 -0
- package/dist/packages/player/src/composition/BrowserAttitudeSensor.js +191 -0
- package/dist/packages/player/src/composition/Disposables.js +31 -0
- package/dist/packages/player/src/composition/DrawingBufferFit.js +119 -0
- package/dist/packages/player/src/composition/animationFrames.js +9 -0
- package/dist/packages/player/src/composition/attitudeSensor.js +18 -0
- package/dist/packages/player/src/composition/browserPorts.js +80 -0
- package/dist/packages/player/src/composition/buildPipeline.js +186 -0
- package/dist/packages/player/src/composition/ensureDecodable.js +62 -0
- package/dist/packages/player/src/composition/openInputs.js +120 -0
- package/dist/packages/player/src/composition/openRecording.js +41 -0
- package/dist/packages/player/src/composition/readInputs.js +25 -0
- package/dist/packages/player/src/composition/renditionFrames.js +160 -0
- package/dist/packages/player/src/controls/ChoiceMenu.js +125 -0
- package/dist/packages/player/src/controls/FullscreenButton.js +29 -0
- package/dist/packages/player/src/controls/MotionLookButton.js +34 -0
- package/dist/packages/player/src/controls/PictureMenus.js +60 -0
- package/dist/packages/player/src/controls/SeekBar.js +126 -0
- package/dist/packages/player/src/controls/SoundControls.js +43 -0
- package/dist/packages/player/src/controls/TransportButtons.js +28 -0
- package/dist/packages/player/src/controls/ViewGestures.js +135 -0
- package/dist/packages/player/src/controls/Wording.js +79 -0
- package/dist/packages/player/src/controls/controlParts.js +38 -0
- package/dist/packages/player/src/controls/controls.js +4 -0
- package/dist/packages/player/src/controls/controlsBar.js +33 -0
- package/dist/packages/player/src/controls/controlsMarkup.js +100 -0
- package/dist/packages/player/src/controls/customControls.js +43 -0
- package/dist/packages/player/src/controls/formatTime.js +19 -0
- package/dist/packages/player/src/controls/icons.js +66 -0
- package/dist/packages/player/src/controls/keyboard.js +120 -0
- package/dist/packages/player/src/controls/messages.js +130 -0
- package/dist/packages/player/src/controls/nativeFullscreen.js +27 -0
- package/dist/packages/player/src/controls/parseMarkup.js +30 -0
- package/dist/packages/player/src/controls/resetViewButton.js +11 -0
- package/dist/packages/player/src/controls/sliderFill.js +15 -0
- package/dist/packages/player/src/element/ElementLoads.js +130 -0
- package/dist/packages/player/src/element/FullscreenToggle.js +93 -0
- package/dist/packages/player/src/element/GyroViewElement.js +358 -0
- package/dist/packages/player/src/element/IdleWatcher.js +71 -0
- package/dist/packages/player/src/element/PlayerCanvas.js +72 -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 +62 -0
- package/dist/packages/player/src/element/attributes.js +123 -0
- package/dist/packages/player/src/element/defineGyroView.js +20 -0
- package/dist/packages/player/src/element/earlyProperties.js +35 -0
- package/dist/packages/player/src/element/elementProperties.js +34 -0
- package/dist/packages/player/src/element/elementSource.js +39 -0
- package/dist/packages/player/src/element/fetchProperty.js +48 -0
- package/dist/packages/player/src/element/liveSettings.js +137 -0
- package/dist/packages/player/src/element/playbackAttributes.js +52 -0
- package/dist/packages/player/src/element/playerEventMirror.js +33 -0
- package/dist/packages/player/src/element/reflectedProperties.js +96 -0
- package/dist/packages/player/src/element/styles.js +4 -0
- package/dist/packages/player/src/element/template.js +46 -0
- package/dist/packages/player/src/inspectRecording.js +21 -0
- package/dist/packages/player/src/player/FrameLoop.js +35 -0
- package/dist/packages/player/src/player/MotionLook.js +150 -0
- package/dist/packages/player/src/player/PictureSettings.js +59 -0
- package/dist/packages/player/src/player/PlaybackStarts.js +38 -0
- package/dist/packages/player/src/player/Player.js +379 -0
- package/dist/packages/player/src/player/PlayerEvents.js +28 -0
- package/dist/packages/player/src/player/PlayerPhase.js +38 -0
- package/dist/packages/player/src/player/PlayerSound.js +60 -0
- package/dist/packages/player/src/player/PlayerView.js +143 -0
- package/dist/packages/player/src/player/SessionRelay.js +74 -0
- package/dist/packages/player/src/player/StatusAnnouncer.js +29 -0
- package/dist/packages/player/src/player/ensureFinite.js +26 -0
- package/dist/packages/player/src/player/loadRecording.js +47 -0
- package/dist/packages/player/src/player/transportEvents.js +30 -0
- package/dist/packages/player/src/player/viewAngles.js +17 -0
- package/dist/packages/player/src/rendition.js +52 -0
- package/dist/standalone.js +5633 -0
- package/package.json +70 -3
package/README.md
CHANGED
|
@@ -1,3 +1,314 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bubo-squared/gyroview
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Play raw `.insv` recordings of Insta360 cameras (X3, X4, X5, X6, ONE RS) and the Antigravity A1
|
|
4
|
+
in the browser. `<gyro-view>` reads the camera's dual-fisheye file directly, over HTTP byte
|
|
5
|
+
ranges or from a local file, decodes both lenses in hardware with WebCodecs, and stitches and
|
|
6
|
+
gyro-stabilizes them on the GPU. No Insta360 Studio export step.
|
|
7
|
+
|
|
8
|
+
**Try it first:** [insv-player.com](https://insv-player.com/) plays `.insv` files with this
|
|
9
|
+
package. Drop your own recording to check that your camera and browser work before you install.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @bubo-squared/gyroview
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
It brings Three.js 0.186 and mediabunny 1 along. A page that uses Three.js 0.186 itself shares
|
|
18
|
+
that copy; any other version means two copies in the bundle, about 128 KB gzipped. The package is
|
|
19
|
+
ES modules only: CommonJS code loads it with `import()`.
|
|
20
|
+
|
|
21
|
+
## Use
|
|
22
|
+
|
|
23
|
+
Register the element once, then use it like a video element:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import '@bubo-squared/gyroview/define';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<gyro-view
|
|
31
|
+
src="https://media.example/VID_20260814_132640_00_013.insv"
|
|
32
|
+
stabilization="lock"
|
|
33
|
+
controls
|
|
34
|
+
muted
|
|
35
|
+
></gyro-view>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
A relative `src` resolves against the document, as an image's does. `timeupdate` comes four
|
|
39
|
+
times a second while playing, as a media element's does; `frame` comes with every picture
|
|
40
|
+
drawn.
|
|
41
|
+
|
|
42
|
+
A page without a bundler loads the standalone file, which has Three.js and mediabunny inside
|
|
43
|
+
(about 260 KB compressed) and registers the element; it exports what the package does:
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<script
|
|
47
|
+
type="module"
|
|
48
|
+
src="https://cdn.jsdelivr.net/npm/@bubo-squared/gyroview@0.8/dist/standalone.js"
|
|
49
|
+
></script>
|
|
50
|
+
<script type="module">
|
|
51
|
+
import { inspectRecording } from 'https://cdn.jsdelivr.net/npm/@bubo-squared/gyroview@0.8/dist/standalone.js';
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Bundling it next to a Three.js of the page's own ships two copies; `@bubo-squared/gyroview`
|
|
56
|
+
and `@bubo-squared/gyroview/define` share the page's instead.
|
|
57
|
+
|
|
58
|
+
Play a file the visitor picks, without any server:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const player = document.querySelector('gyro-view');
|
|
62
|
+
const input = document.querySelector<HTMLInputElement>('input[type="file"]');
|
|
63
|
+
input?.addEventListener('change', () => {
|
|
64
|
+
const file = input.files?.[0];
|
|
65
|
+
if (file && player) player.loadFiles({ main: file });
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`@bubo-squared/gyroview/define` registers `<gyro-view>` when imported. To choose the moment
|
|
70
|
+
yourself, import `defineGyroView` from `@bubo-squared/gyroview` and call it. Both are safe to
|
|
71
|
+
import in a framework that renders on the server: there they register nothing, and the element
|
|
72
|
+
comes alive once the page runs in the browser.
|
|
73
|
+
|
|
74
|
+
The element's events are typed: each is a `CustomEvent` with its payload in `detail`, and
|
|
75
|
+
`document.querySelector('gyro-view')` is a `GyroViewElement`.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
player?.addEventListener('ready', (event) => console.log(event.detail.model));
|
|
79
|
+
player?.addEventListener('error', (event) => console.log(event.detail.code));
|
|
80
|
+
player?.addEventListener('warning', (event) => {
|
|
81
|
+
if (event.detail.code === 'autoplay-blocked') showTapToPlay();
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Its words are English until the page gives its own, and a failure shows visitors a plain
|
|
86
|
+
sentence while the `error` event carries the diagnostic:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
if (player) player.messages = { labels: { play: 'Lecture' }, errors: { cors: 'Introuvable.' } };
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Read what a recording holds without playing it: its trailer records, the info record (camera,
|
|
93
|
+
firmware, frame rate), the lens calibration and summaries of the gyro and exposure records.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { inspectRecording } from '@bubo-squared/gyroview';
|
|
97
|
+
|
|
98
|
+
const fromFile = await inspectRecording(file);
|
|
99
|
+
const fromUrl = await inspectRecording('https://media.example/VID_20260814_132640_00_013.insv');
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Render a recording into a stitched equirectangular video for an encoder, rather than playing
|
|
103
|
+
it: `openRendition` yields every frame of the span once, in order, as a `VideoFrame` `width`
|
|
104
|
+
pixels across and half as many down, whenever you ask for the next, so a slow encoder loses
|
|
105
|
+
nothing. It needs no page: it draws on an `OffscreenCanvas` of its own, so it runs in a worker.
|
|
106
|
+
The recording's sound is in its file as recorded, for the encoder to copy. With
|
|
107
|
+
[Mediabunny](https://mediabunny.dev):
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { openRendition } from '@bubo-squared/gyroview';
|
|
111
|
+
import {
|
|
112
|
+
BufferTarget,
|
|
113
|
+
Mp4OutputFormat,
|
|
114
|
+
Output,
|
|
115
|
+
Quality,
|
|
116
|
+
VideoSample,
|
|
117
|
+
VideoSampleSource,
|
|
118
|
+
} from 'mediabunny';
|
|
119
|
+
|
|
120
|
+
const rendition = await openRendition(
|
|
121
|
+
{ main: { blob: file, name: file.name } },
|
|
122
|
+
{ width: 3840, from: 12, to: 48, stabilization: 'horizon' },
|
|
123
|
+
);
|
|
124
|
+
const output = new Output({ format: new Mp4OutputFormat(), target: new BufferTarget() });
|
|
125
|
+
const video = new VideoSampleSource({ codec: 'avc', quality: new Quality('high') });
|
|
126
|
+
output.addVideoTrack(video, { frameRate: 30 });
|
|
127
|
+
await output.start();
|
|
128
|
+
for await (const frame of rendition.frames()) {
|
|
129
|
+
await video.add(new VideoSample(frame));
|
|
130
|
+
frame.close();
|
|
131
|
+
}
|
|
132
|
+
await output.finalize();
|
|
133
|
+
rendition.dispose();
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`width` is a multiple of four, so both sides are even as encoders take them; the other settings
|
|
137
|
+
are the player's defaults unless given. A split-lens recording names its other file as `second`.
|
|
138
|
+
|
|
139
|
+
For an interface of your own, `createBrowserPlayer` gives the player without the element: it
|
|
140
|
+
draws on your canvas, sounds through your audio element and has the same events, which
|
|
141
|
+
`player.events.on` listens to. `player.togglePlayback()` plays or pauses as the element's tap
|
|
142
|
+
does, a refused start reported as a `warning`.
|
|
143
|
+
`attachViewGestures` and `attachKeyboard` give your canvas the element's drags, pinches, wheel
|
|
144
|
+
zoom and taps, and its keyboard shortcuts; each returns what removes them.
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { createBrowserPlayer } from '@bubo-squared/gyroview';
|
|
148
|
+
|
|
149
|
+
const player = createBrowserPlayer({ canvas, audio });
|
|
150
|
+
player.events.on('timeupdate', (time) => console.log(time));
|
|
151
|
+
attachViewGestures(canvas, player);
|
|
152
|
+
attachKeyboard(canvas, player);
|
|
153
|
+
await player.load({ main: { url: 'https://media.example/VID_20260814_132640_00_013.insv' } });
|
|
154
|
+
await player.play();
|
|
155
|
+
player.seek(30);
|
|
156
|
+
player.lookAt(90, 0);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The canvas keeps no picture once the browser has shown it: a snapshot (`drawImage`, `toBlob`)
|
|
160
|
+
is taken in a `frame` listener, which runs right after each picture is drawn. There are no
|
|
161
|
+
buffered ranges to show yet, and no playback rates other than 1.
|
|
162
|
+
|
|
163
|
+
## How a recording is downloaded
|
|
164
|
+
|
|
165
|
+
A recording named by URL is read in byte ranges, in file order, as it plays: the lenses and
|
|
166
|
+
the sound come from the same bytes, each fetched about once. Until the first play the player
|
|
167
|
+
reads only what opening it and showing the first frame need (no frame with `preload="none"`).
|
|
168
|
+
Playing, it keeps up to 10 s or 128 MiB ahead, whichever is less, shared by the two files of a
|
|
169
|
+
split recording; paused, it reads on to that budget and stops. A seek ends the old position's
|
|
170
|
+
requests at once. When the network falls behind the recording, playback waits until the next
|
|
171
|
+
4 s are downloaded, and plays on in stretches rather than a frame at a time. A range that
|
|
172
|
+
breaks off or stalls for 10 s is asked for again from its next byte, and a recording replaced at
|
|
173
|
+
its URL while it plays fails with `source-changed`. A server slow to answer each request, such
|
|
174
|
+
as a cloud drive's download API, is asked in fewer, larger ranges, so its waits do not slow
|
|
175
|
+
playback.
|
|
176
|
+
|
|
177
|
+
`@bubo-squared/gyroview` also exports `GyroViewError`, the list of its codes
|
|
178
|
+
(`GYRO_VIEW_ERROR_CODES`, with `isGyroViewErrorCode` to check a string against it), and the
|
|
179
|
+
types of the element's settings, metadata, events and inspection.
|
|
180
|
+
|
|
181
|
+
## Frameworks
|
|
182
|
+
|
|
183
|
+
The element takes properties and attributes as any element does, and its events are DOM
|
|
184
|
+
events, so a framework needs only to know the tag.
|
|
185
|
+
|
|
186
|
+
**React 19** sets the attributes and hears events through a ref. For JSX to know the tag, a
|
|
187
|
+
declaration file of the project's own extends React's elements with the package's
|
|
188
|
+
`GyroViewAttributes`:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
// gyro-view.d.ts
|
|
192
|
+
import type { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
193
|
+
import type { GyroViewAttributes, GyroViewElement } from '@bubo-squared/gyroview';
|
|
194
|
+
|
|
195
|
+
declare module 'react' {
|
|
196
|
+
namespace JSX {
|
|
197
|
+
interface IntrinsicElements {
|
|
198
|
+
'gyro-view': DetailedHTMLProps<HTMLAttributes<GyroViewElement>, GyroViewElement> &
|
|
199
|
+
GyroViewAttributes;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
const player = useRef<GyroViewElement>(null);
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
const element = player.current;
|
|
209
|
+
const onReady = (event: CustomEvent<PlayerMetadata>): void => console.log(event.detail.model);
|
|
210
|
+
element?.addEventListener('ready', onReady);
|
|
211
|
+
return () => element?.removeEventListener('ready', onReady);
|
|
212
|
+
}, []);
|
|
213
|
+
return <gyro-view ref={player} src={url} stabilization="lock" controls muted />;
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
A `fetch` for recordings behind a token is a property only, with no attribute. Set it where
|
|
217
|
+
React commits `src`, in a ref callback or `useLayoutEffect`, not in `useEffect`, which runs after
|
|
218
|
+
the load has started without it; and keep the function stable (`useCallback`, or defined outside
|
|
219
|
+
the component), since only setting the same function again leaves the recording playing:
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
const withToken = useCallback<RecordingFetch>((url, init) => {
|
|
223
|
+
const headers = new Headers(init.headers);
|
|
224
|
+
headers.set('Authorization', `Bearer ${token.current}`);
|
|
225
|
+
return fetch(url, { ...init, headers });
|
|
226
|
+
}, []);
|
|
227
|
+
useLayoutEffect(() => {
|
|
228
|
+
if (player.current) player.current.fetch = withToken;
|
|
229
|
+
}, [withToken]);
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Vue 3** is told the tag is a custom element (`isCustomElement: (tag) => tag === 'gyro-view'`
|
|
233
|
+
in the template compiler options), then binds as usual: `<gyro-view :src="url" controls
|
|
234
|
+
@ready="onReady" />`.
|
|
235
|
+
|
|
236
|
+
**Svelte 5** needs nothing: `<gyro-view src={url} controls onready={onReady} />`.
|
|
237
|
+
|
|
238
|
+
In every case the element registers in the browser only: import `@bubo-squared/gyroview/define`
|
|
239
|
+
in code that runs there, or call `defineGyroView()` once mounted. Importing either while the
|
|
240
|
+
server renders is safe and registers nothing.
|
|
241
|
+
|
|
242
|
+
## Several players on one page
|
|
243
|
+
|
|
244
|
+
Each player holds a WebGL context and, while a recording is loaded, two hardware video
|
|
245
|
+
decoders. Browsers cap both (about sixteen WebGL contexts in Chrome, fewer decoders on phones),
|
|
246
|
+
so a gallery gives its players `preload="none"`, which keeps the decoders idle until play, and
|
|
247
|
+
loads a recording only for the player in view, removing `src` from the others. An element the
|
|
248
|
+
page removes gives its WebGL context up at once rather than when it is collected, and draws on a
|
|
249
|
+
fresh canvas if it is added again; one whose context the browser took away while it held no
|
|
250
|
+
recording draws on a fresh canvas at its next load.
|
|
251
|
+
|
|
252
|
+
## Requirements
|
|
253
|
+
|
|
254
|
+
- **A secure page.** WebCodecs exists only on `https://` pages, or `http://localhost`; elsewhere
|
|
255
|
+
the player fails with `webcodecs-unavailable`.
|
|
256
|
+
- **Recordings served in byte ranges.** The server answers `Range` requests with `206`, and
|
|
257
|
+
sends CORS headers when the recordings live on another origin than the page:
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
Access-Control-Allow-Origin: https://your-site.example
|
|
261
|
+
Access-Control-Allow-Methods: GET, HEAD
|
|
262
|
+
Access-Control-Allow-Headers: Range
|
|
263
|
+
Access-Control-Expose-Headers: Content-Range, Content-Length, Accept-Ranges, ETag
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Recordings kept behind the visitor's cookies take `crossorigin="use-credentials"` on the
|
|
267
|
+
element, or `credentials: 'include'` on a URL given to `createBrowserPlayer`'s `load`, and a
|
|
268
|
+
host that names the page's origin, never `*`, and adds
|
|
269
|
+
`Access-Control-Allow-Credentials: true`.
|
|
270
|
+
|
|
271
|
+
Recordings behind a token take the page's own function in the element's `fetch` property, or
|
|
272
|
+
in `fetch` on a URL given to `load`: it is called in place of `fetch` for every request, and
|
|
273
|
+
adds the header the host asks for.
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
player.fetch = (url, init) => {
|
|
277
|
+
const headers = new Headers(init.headers);
|
|
278
|
+
headers.set('Authorization', `Bearer ${token()}`);
|
|
279
|
+
return fetch(url, { ...init, headers });
|
|
280
|
+
};
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- **A hardware HEVC decoder.** 5.7K plays on recent laptops and phones; 8K needs a Level 6
|
|
284
|
+
decoder (Apple Silicon, recent NVIDIA and Intel). On Linux, Chrome reaches the decoder only
|
|
285
|
+
through VA-API: an Intel or AMD GPU whose driver offers HEVC, not NVIDIA's own driver or a
|
|
286
|
+
virtual machine (`chrome://gpu` lists `Decode hevc main` under Video Acceleration
|
|
287
|
+
Information when it can). H.264 recordings do not need it. A recording the browser cannot
|
|
288
|
+
decode fails with the `codec-unsupported` error.
|
|
289
|
+
|
|
290
|
+
The supported browsers, with the oldest versions that have what the player uses (WebCodecs,
|
|
291
|
+
WebGL 2, container queries, `color-mix()`, the ES2023 array methods, and on iPhone
|
|
292
|
+
`ManagedMediaSource` for the sound):
|
|
293
|
+
|
|
294
|
+
| Browser | From | Notes |
|
|
295
|
+
| --------------------- | ---- | ---------------------------------------------------------------------------------------- |
|
|
296
|
+
| Chrome, Edge desktop | 111 | The controls' colours need 111; HEVC is decoded in hardware from 107 on (Linux: VA-API). |
|
|
297
|
+
| Safari on macOS | 16.4 | |
|
|
298
|
+
| Safari on iPhone/iPad | 17.1 | 16.4 to 17.0 play without sound, with a `warning` event. |
|
|
299
|
+
|
|
300
|
+
Firefox and Chrome on Android are untested: they play what their decoders accept.
|
|
301
|
+
|
|
302
|
+
Until 1.0, a minor version may change the API; [CHANGELOG.md](./CHANGELOG.md) says what changed.
|
|
303
|
+
|
|
304
|
+
## Reference
|
|
305
|
+
|
|
306
|
+
Every attribute, method, event and keyboard shortcut is in the
|
|
307
|
+
[project README](https://github.com/bubo-squared/GyroView#using-the-player), and what a failure
|
|
308
|
+
tells a page, with what a `<video>` fallback can do, under
|
|
309
|
+
[When a recording cannot play](https://github.com/bubo-squared/GyroView#when-a-recording-cannot-play);
|
|
310
|
+
hosting and the error codes are in [docs/DEPLOYMENT.md](https://github.com/bubo-squared/GyroView/blob/main/docs/DEPLOYMENT.md).
|
|
311
|
+
|
|
312
|
+
## License
|
|
313
|
+
|
|
314
|
+
MIT
|
package/dist/define.d.ts
ADDED
package/dist/define.js
ADDED