@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
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { degrees } from "../../../core/src/shared/units/angle.js";
|
|
2
|
+
import { asGyroViewError } from "../../../core/src/shared/errors/GyroViewError.js";
|
|
3
|
+
import { seconds } from "../../../core/src/shared/units/time.js";
|
|
4
|
+
import { Outbox } from "../../../core/src/shared/events/Outbox.js";
|
|
5
|
+
import { isFlowing } from "../../../core/src/domain/playback/PlayerState.js";
|
|
6
|
+
import { TypedEmitter } from "../../../core/src/shared/events/TypedEmitter.js";
|
|
7
|
+
import { ensureFinite, viewStateOf } from "./ensureFinite.js";
|
|
8
|
+
import { NO_ATTITUDE_SENSOR } from "../composition/attitudeSensor.js";
|
|
9
|
+
import { cssSizeOf } from "../composition/DrawingBufferFit.js";
|
|
10
|
+
import { FrameLoop } from "./FrameLoop.js";
|
|
11
|
+
import { loadRecording } from "./loadRecording.js";
|
|
12
|
+
import { MotionLook } from "./MotionLook.js";
|
|
13
|
+
import { IDLE, loadingPhase, sessionToPlay, statusOf } from "./PlayerPhase.js";
|
|
14
|
+
import { PictureSettings } from "./PictureSettings.js";
|
|
15
|
+
import { PlaybackStarts } from "./PlaybackStarts.js";
|
|
16
|
+
import { PlayerSound } from "./PlayerSound.js";
|
|
17
|
+
import { anglesOf } from "./viewAngles.js";
|
|
18
|
+
import { PlayerView } from "./PlayerView.js";
|
|
19
|
+
import { SessionRelay } from "./SessionRelay.js";
|
|
20
|
+
import { StatusAnnouncer } from "./StatusAnnouncer.js";
|
|
21
|
+
//#region ../../packages/player/src/player/Player.ts
|
|
22
|
+
/**
|
|
23
|
+
* The player without the element, which `createBrowserPlayer` gives: it plays one recording at a
|
|
24
|
+
* time on the canvas and audio element it was handed, reports in media-element events, and keeps
|
|
25
|
+
* its settings (view, view mode, motion look, stabilization, gain matching, sound, loop) from
|
|
26
|
+
* load to load. `<gyro-view>` is a facade over it.
|
|
27
|
+
*/
|
|
28
|
+
var Player = class {
|
|
29
|
+
parts;
|
|
30
|
+
/**
|
|
31
|
+
* What the player announces, to listen to: only the player and its parts emit.
|
|
32
|
+
*/
|
|
33
|
+
events;
|
|
34
|
+
emitter = new TypedEmitter();
|
|
35
|
+
/**
|
|
36
|
+
* What the player and its parts announce, heard once each change is whole (ADR 0021).
|
|
37
|
+
*/
|
|
38
|
+
outbox = new Outbox(this.emitter);
|
|
39
|
+
statuses = new StatusAnnouncer(this.outbox, this.emitter);
|
|
40
|
+
loop;
|
|
41
|
+
phase = IDLE;
|
|
42
|
+
viewing;
|
|
43
|
+
motion;
|
|
44
|
+
picture = new PictureSettings(this.outbox);
|
|
45
|
+
/**
|
|
46
|
+
* A seek asked for before a recording was ready, where the next one starts.
|
|
47
|
+
*/
|
|
48
|
+
pendingStartTime;
|
|
49
|
+
sound;
|
|
50
|
+
relay = new SessionRelay({
|
|
51
|
+
events: this.outbox,
|
|
52
|
+
onState: () => {
|
|
53
|
+
this.statuses.announce(this.status);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
starts = new PlaybackStarts(this.outbox, () => this.play());
|
|
57
|
+
/**
|
|
58
|
+
* Whether the recording plays again from the start at its end; kept across loads.
|
|
59
|
+
*/
|
|
60
|
+
shouldLoop = false;
|
|
61
|
+
/**
|
|
62
|
+
* Past `dispose`: a listener of the idle it announces must not load again.
|
|
63
|
+
*/
|
|
64
|
+
isDisposed = false;
|
|
65
|
+
/**
|
|
66
|
+
* @internal A page gets its player from `createBrowserPlayer`, which composes the parts.
|
|
67
|
+
*/
|
|
68
|
+
constructor(parts) {
|
|
69
|
+
this.parts = parts;
|
|
70
|
+
this.events = this.emitter;
|
|
71
|
+
this.loop = new FrameLoop(this.tick);
|
|
72
|
+
parts.host.audio.addEventListener("ended", this.tick);
|
|
73
|
+
this.sound = new PlayerSound(parts.host.audio, this.outbox);
|
|
74
|
+
this.viewing = new PlayerView(this.outbox, () => cssSizeOf(parts.host.canvas));
|
|
75
|
+
this.motion = new MotionLook({
|
|
76
|
+
sensor: parts.attitude ?? NO_ATTITUDE_SENSOR,
|
|
77
|
+
view: this.viewing,
|
|
78
|
+
events: this.outbox,
|
|
79
|
+
hasRecording: () => this.loaded !== void 0
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
get status() {
|
|
83
|
+
return statusOf(this.phase);
|
|
84
|
+
}
|
|
85
|
+
get metadata() {
|
|
86
|
+
return this.loaded?.opened.metadata;
|
|
87
|
+
}
|
|
88
|
+
get currentTime() {
|
|
89
|
+
return this.loaded?.pipeline.session.currentTime ?? seconds(0);
|
|
90
|
+
}
|
|
91
|
+
get duration() {
|
|
92
|
+
return this.loaded?.opened.duration ?? seconds(0);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* False while playing or holding for frames, as a media element's `paused`.
|
|
96
|
+
*/
|
|
97
|
+
get isPaused() {
|
|
98
|
+
return !isFlowing(this.loaded?.pipeline.session.state);
|
|
99
|
+
}
|
|
100
|
+
get view() {
|
|
101
|
+
return anglesOf(this.viewing.current);
|
|
102
|
+
}
|
|
103
|
+
get viewMode() {
|
|
104
|
+
return this.viewing.viewMode;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Whether a drag moves the picture as it is framed now; the view mode decides.
|
|
108
|
+
*/
|
|
109
|
+
get canPan() {
|
|
110
|
+
return this.viewing.canPan;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Whether turning the device turns the normal view: `unavailable` where the device reports no
|
|
114
|
+
* attitude or access was refused.
|
|
115
|
+
*/
|
|
116
|
+
get motionLook() {
|
|
117
|
+
return this.motion.state;
|
|
118
|
+
}
|
|
119
|
+
get stabilization() {
|
|
120
|
+
return this.picture.stabilization;
|
|
121
|
+
}
|
|
122
|
+
get quality() {
|
|
123
|
+
return this.picture.quality;
|
|
124
|
+
}
|
|
125
|
+
get isLooping() {
|
|
126
|
+
return this.shouldLoop;
|
|
127
|
+
}
|
|
128
|
+
get volume() {
|
|
129
|
+
return this.sound.volume;
|
|
130
|
+
}
|
|
131
|
+
get isMuted() {
|
|
132
|
+
return this.sound.isMuted;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Whether `setVolume` changes anything on this platform; iOS leaves media at the device's volume.
|
|
136
|
+
*/
|
|
137
|
+
get canSetVolume() {
|
|
138
|
+
return this.sound.canSetVolume;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Replaces whatever was loaded. Resolves once the recording is ready, `autoplay` starting it
|
|
142
|
+
* then, a refusal a warning; rejects with the failure after reporting it as an `error` event.
|
|
143
|
+
* A load that a newer load or `unload` supersedes resolves quietly.
|
|
144
|
+
*/
|
|
145
|
+
async load(source, options = {}) {
|
|
146
|
+
if (this.isDisposed) return;
|
|
147
|
+
const loading = this.outbox.change(() => {
|
|
148
|
+
this.unload();
|
|
149
|
+
const next = loadingPhase();
|
|
150
|
+
this.phase = next;
|
|
151
|
+
this.statuses.announce(this.status);
|
|
152
|
+
return next;
|
|
153
|
+
});
|
|
154
|
+
try {
|
|
155
|
+
await this.complete(loading, source, options);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (loading.controller.signal.aborted) return;
|
|
158
|
+
throw this.failWith(error);
|
|
159
|
+
} finally {
|
|
160
|
+
loading.settled.resolve();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
unload() {
|
|
164
|
+
this.outbox.change(() => {
|
|
165
|
+
this.release();
|
|
166
|
+
this.statuses.announce(this.status);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Starts playback, after a load in progress is ready, and resolves once it runs, as a media
|
|
171
|
+
* element's `play()` does. Rejects with the load's failure, with `playback-blocked` when the
|
|
172
|
+
* browser wants a user gesture first, with `no-source` when nothing is loaded or loading, and
|
|
173
|
+
* with `play-interrupted` when a newer load or `unload` replaced the load it waited for.
|
|
174
|
+
*/
|
|
175
|
+
async play() {
|
|
176
|
+
const waitedFor = this.phase.kind === "loading" ? this.phase : void 0;
|
|
177
|
+
await waitedFor?.settled.promise;
|
|
178
|
+
await sessionToPlay(this.phase, waitedFor).play();
|
|
179
|
+
}
|
|
180
|
+
pause() {
|
|
181
|
+
this.loaded?.pipeline.session.pause();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Pauses, or starts playing and reports a refused start as a `warning`: what a tap on the
|
|
185
|
+
* picture or a play button does.
|
|
186
|
+
*/
|
|
187
|
+
togglePlayback() {
|
|
188
|
+
if (this.isPaused) this.starts.press();
|
|
189
|
+
else this.pause();
|
|
190
|
+
}
|
|
191
|
+
stop() {
|
|
192
|
+
this.loaded?.pipeline.session.stop();
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Seeks exactly to `time` seconds; while a recording is loading, before one is, or after its
|
|
196
|
+
* playback failed, the next one starts there, as a media element's default playback start
|
|
197
|
+
* position has it.
|
|
198
|
+
*/
|
|
199
|
+
seek(time) {
|
|
200
|
+
ensureFinite(time, "time");
|
|
201
|
+
const session = this.loaded?.pipeline.session;
|
|
202
|
+
if (session && session.state !== "error") session.seek(seconds(time));
|
|
203
|
+
else this.pendingStartTime = seconds(time);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Seeks to the key frame at or before `time` seconds: quick to show while a seek bar is dragged.
|
|
207
|
+
*/
|
|
208
|
+
async scrub(time) {
|
|
209
|
+
ensureFinite(time, "time");
|
|
210
|
+
await this.loaded?.pipeline.session.scrub(seconds(time));
|
|
211
|
+
}
|
|
212
|
+
setView(view) {
|
|
213
|
+
this.viewing.set(viewStateOf(view));
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Points the normal view at `yaw` and `pitch`, in degrees: yaw positive to the right, pitch
|
|
217
|
+
* positive up.
|
|
218
|
+
*/
|
|
219
|
+
lookAt(yaw, pitch) {
|
|
220
|
+
ensureFinite(yaw, "yaw");
|
|
221
|
+
ensureFinite(pitch, "pitch");
|
|
222
|
+
this.viewing.lookAt(degrees(yaw), degrees(pitch));
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The viewer dragged the picture by `delta` CSS pixels across the canvas.
|
|
226
|
+
*/
|
|
227
|
+
pan(delta) {
|
|
228
|
+
this.viewing.pan(delta);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The viewer turned by the given angles in degrees, as the arrow keys do.
|
|
232
|
+
*/
|
|
233
|
+
turn(yawDelta, pitchDelta) {
|
|
234
|
+
ensureFinite(yawDelta, "yaw turn");
|
|
235
|
+
ensureFinite(pitchDelta, "pitch turn");
|
|
236
|
+
this.viewing.turn(degrees(yawDelta), degrees(pitchDelta));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Zooms by `steps` (positive zooms in) toward `focus`, a point of the canvas as fractions of its
|
|
240
|
+
* size; about the centre when none is given.
|
|
241
|
+
*/
|
|
242
|
+
zoom(steps, focus) {
|
|
243
|
+
ensureFinite(steps, "zoom steps");
|
|
244
|
+
this.viewing.zoom(steps, focus);
|
|
245
|
+
}
|
|
246
|
+
resetView() {
|
|
247
|
+
this.viewing.reset();
|
|
248
|
+
}
|
|
249
|
+
setViewMode(mode) {
|
|
250
|
+
this.viewing.setMode(mode);
|
|
251
|
+
this.motion.reconsider();
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Lets the device turn the normal view, as a window into the recording: its tilt and roll
|
|
255
|
+
* hold the pitch and keep the horizon level, drags turn the heading alone. Call it from a tap's
|
|
256
|
+
* handler: iOS asks the viewer for access there and refuses it anywhere else. Resolves with the
|
|
257
|
+
* state it ends in; a refusal is a warning, never a rejection.
|
|
258
|
+
*/
|
|
259
|
+
startMotionLook() {
|
|
260
|
+
return this.motion.start();
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Gives the view back to the pointer, level, looking where it looked.
|
|
264
|
+
*/
|
|
265
|
+
stopMotionLook() {
|
|
266
|
+
this.motion.stop();
|
|
267
|
+
}
|
|
268
|
+
setStabilization(mode) {
|
|
269
|
+
this.picture.setStabilization(mode);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* How finely the lens images are read and how many device pixels are drawn; kept across loads.
|
|
273
|
+
*/
|
|
274
|
+
setQuality(quality) {
|
|
275
|
+
this.picture.setQuality(quality);
|
|
276
|
+
}
|
|
277
|
+
setLooping(isLooping) {
|
|
278
|
+
this.shouldLoop = isLooping;
|
|
279
|
+
this.loaded?.pipeline.session.setLooping(isLooping);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Whether the lenses' exposure is matched along the seam; kept across loads.
|
|
283
|
+
*/
|
|
284
|
+
setGainMatching(isEnabled) {
|
|
285
|
+
this.picture.setGainMatching(isEnabled);
|
|
286
|
+
}
|
|
287
|
+
setVolume(volume) {
|
|
288
|
+
ensureFinite(volume, "volume");
|
|
289
|
+
this.sound.setVolume(volume);
|
|
290
|
+
}
|
|
291
|
+
setMuted(isMuted) {
|
|
292
|
+
this.sound.setMuted(isMuted);
|
|
293
|
+
}
|
|
294
|
+
dispose() {
|
|
295
|
+
this.isDisposed = true;
|
|
296
|
+
this.unload();
|
|
297
|
+
this.motion.dispose();
|
|
298
|
+
this.parts.host.audio.removeEventListener("ended", this.tick);
|
|
299
|
+
this.sound.dispose();
|
|
300
|
+
this.emitter.removeAll();
|
|
301
|
+
}
|
|
302
|
+
tick = () => {
|
|
303
|
+
this.loaded?.pipeline.session.tick();
|
|
304
|
+
};
|
|
305
|
+
get loaded() {
|
|
306
|
+
return this.phase.kind === "loaded" ? this.phase.loaded : void 0;
|
|
307
|
+
}
|
|
308
|
+
async complete(loading, source, options) {
|
|
309
|
+
const { signal } = loading.controller;
|
|
310
|
+
const loaded = await loadRecording({
|
|
311
|
+
source,
|
|
312
|
+
parts: this.parts,
|
|
313
|
+
signal
|
|
314
|
+
});
|
|
315
|
+
if (signal.aborted) {
|
|
316
|
+
loaded.dispose();
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
this.outbox.change(() => {
|
|
320
|
+
this.attach(loaded, loading.controller);
|
|
321
|
+
this.startAtPendingTime(loaded);
|
|
322
|
+
if (options.preload !== false) loaded.pipeline.session.preload();
|
|
323
|
+
});
|
|
324
|
+
if (options.autoplay && this.loaded === loaded) this.starts.autoplay();
|
|
325
|
+
}
|
|
326
|
+
startAtPendingTime(loaded) {
|
|
327
|
+
const time = this.pendingStartTime;
|
|
328
|
+
this.pendingStartTime = void 0;
|
|
329
|
+
if (time !== void 0) loaded.pipeline.session.seek(time);
|
|
330
|
+
}
|
|
331
|
+
attach(loaded, controller) {
|
|
332
|
+
this.phase = {
|
|
333
|
+
kind: "loaded",
|
|
334
|
+
loaded,
|
|
335
|
+
controller
|
|
336
|
+
};
|
|
337
|
+
this.viewing.attach(loaded.pipeline.renderer);
|
|
338
|
+
this.motion.reconsider();
|
|
339
|
+
const { session } = loaded.pipeline;
|
|
340
|
+
session.setLooping(this.shouldLoop);
|
|
341
|
+
this.picture.attach(loaded.pipeline);
|
|
342
|
+
this.relay.attach(session);
|
|
343
|
+
this.loop.start();
|
|
344
|
+
this.statuses.announce(this.status);
|
|
345
|
+
for (const warning of loaded.warnings) this.outbox.emit("warning", warning);
|
|
346
|
+
this.outbox.emit("ready", loaded.opened.metadata);
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Lets go of whatever is loading or loaded, announcing nothing.
|
|
350
|
+
*/
|
|
351
|
+
release() {
|
|
352
|
+
const previous = this.phase;
|
|
353
|
+
this.phase = IDLE;
|
|
354
|
+
if (previous.kind === "loading") previous.controller.abort();
|
|
355
|
+
this.loop.stop();
|
|
356
|
+
this.relay.detach();
|
|
357
|
+
this.viewing.attach(void 0);
|
|
358
|
+
this.motion.reconsider();
|
|
359
|
+
this.picture.attach(void 0);
|
|
360
|
+
if (previous.kind !== "loaded") return;
|
|
361
|
+
previous.loaded.dispose();
|
|
362
|
+
previous.controller.abort();
|
|
363
|
+
}
|
|
364
|
+
failWith(error) {
|
|
365
|
+
const failure = asGyroViewError(error, "invariant-violation", "the player failed unexpectedly");
|
|
366
|
+
this.outbox.change(() => {
|
|
367
|
+
this.release();
|
|
368
|
+
this.phase = {
|
|
369
|
+
kind: "failed",
|
|
370
|
+
failure
|
|
371
|
+
};
|
|
372
|
+
this.statuses.announce(this.status);
|
|
373
|
+
this.outbox.emit("error", failure);
|
|
374
|
+
});
|
|
375
|
+
return failure;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
//#endregion
|
|
379
|
+
export { Player };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { keysOf } from "../../../core/src/shared/keysOf.js";
|
|
2
|
+
//#region ../../packages/player/src/player/PlayerEvents.ts
|
|
3
|
+
/**
|
|
4
|
+
* Every event name once.
|
|
5
|
+
*/
|
|
6
|
+
var PLAYER_EVENT_NAMES = keysOf({
|
|
7
|
+
statuschange: true,
|
|
8
|
+
ready: true,
|
|
9
|
+
play: true,
|
|
10
|
+
playing: true,
|
|
11
|
+
waiting: true,
|
|
12
|
+
pause: true,
|
|
13
|
+
ended: true,
|
|
14
|
+
timeupdate: true,
|
|
15
|
+
seeking: true,
|
|
16
|
+
seeked: true,
|
|
17
|
+
frame: true,
|
|
18
|
+
viewchange: true,
|
|
19
|
+
viewmodechange: true,
|
|
20
|
+
motionlookchange: true,
|
|
21
|
+
stabilizationchange: true,
|
|
22
|
+
qualitychange: true,
|
|
23
|
+
volumechange: true,
|
|
24
|
+
warning: true,
|
|
25
|
+
error: true
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
export { PLAYER_EVENT_NAMES };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { GyroViewError } from "../../../core/src/shared/errors/GyroViewError.js";
|
|
2
|
+
import { Deferred } from "../../../core/src/shared/async/Deferred.js";
|
|
3
|
+
//#region ../../packages/player/src/player/PlayerPhase.ts
|
|
4
|
+
var IDLE = { kind: "idle" };
|
|
5
|
+
function loadingPhase() {
|
|
6
|
+
return {
|
|
7
|
+
kind: "loading",
|
|
8
|
+
controller: new AbortController(),
|
|
9
|
+
settled: new Deferred()
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A loaded recording's status is its session's state, `seeking` until a seek's picture is drawn.
|
|
14
|
+
*/
|
|
15
|
+
function statusOf(phase) {
|
|
16
|
+
switch (phase.kind) {
|
|
17
|
+
case "idle": return "idle";
|
|
18
|
+
case "loading": return "loading";
|
|
19
|
+
case "loaded": {
|
|
20
|
+
const { session } = phase.loaded.pipeline;
|
|
21
|
+
return session.isSeeking ? "seeking" : session.state;
|
|
22
|
+
}
|
|
23
|
+
case "failed": return "error";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The session a `play` starts once the load it waited for, if it waited, has settled: the one
|
|
28
|
+
* loaded, by that load. A failure is the load's; a load replaced meanwhile interrupts the play,
|
|
29
|
+
* as a newer load interrupts a media element's.
|
|
30
|
+
*/
|
|
31
|
+
function sessionToPlay(phase, waitedFor) {
|
|
32
|
+
if (phase.kind === "failed") throw phase.failure;
|
|
33
|
+
if (waitedFor !== void 0 && (phase.kind !== "loaded" || phase.controller !== waitedFor.controller)) throw new GyroViewError("play-interrupted", "a newer load or an unload replaced the load to play");
|
|
34
|
+
if (phase.kind !== "loaded") throw new GyroViewError("no-source", "there is no recording to play");
|
|
35
|
+
return phase.loaded.pipeline.session;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { IDLE, loadingPhase, sessionToPlay, statusOf };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { clamp } from "../../../core/src/shared/math/clamp.js";
|
|
2
|
+
//#region ../../packages/player/src/player/PlayerSound.ts
|
|
3
|
+
/**
|
|
4
|
+
* The sound, on the audio element the host lends: its volume and mute, kept across loads by the
|
|
5
|
+
* element itself and announced whoever changes them (the controls, the keyboard, a script, the
|
|
6
|
+
* browser's own media keys).
|
|
7
|
+
*/
|
|
8
|
+
var PlayerSound = class {
|
|
9
|
+
audio;
|
|
10
|
+
events;
|
|
11
|
+
/**
|
|
12
|
+
* Whether the platform lets a page set the volume: iOS keeps media at the device's volume and
|
|
13
|
+
* ignores the setting, where a volume slider would move and change nothing.
|
|
14
|
+
*/
|
|
15
|
+
canSetVolume;
|
|
16
|
+
constructor(audio, events) {
|
|
17
|
+
this.audio = audio;
|
|
18
|
+
this.events = events;
|
|
19
|
+
this.canSetVolume = isVolumeSettable(audio.ownerDocument);
|
|
20
|
+
audio.addEventListener("volumechange", this.onVolumeChange);
|
|
21
|
+
}
|
|
22
|
+
get volume() {
|
|
23
|
+
return this.audio.volume;
|
|
24
|
+
}
|
|
25
|
+
get isMuted() {
|
|
26
|
+
return this.audio.muted;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* From 0 (silent) to 1 (as recorded); anything outside is clamped.
|
|
30
|
+
*/
|
|
31
|
+
setVolume(volume) {
|
|
32
|
+
this.audio.volume = clamp(volume, 0, 1);
|
|
33
|
+
}
|
|
34
|
+
setMuted(isMuted) {
|
|
35
|
+
this.audio.muted = isMuted;
|
|
36
|
+
}
|
|
37
|
+
dispose() {
|
|
38
|
+
this.audio.removeEventListener("volumechange", this.onVolumeChange);
|
|
39
|
+
}
|
|
40
|
+
onVolumeChange = () => {
|
|
41
|
+
this.events.emit("volumechange", {
|
|
42
|
+
volume: this.volume,
|
|
43
|
+
isMuted: this.isMuted
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A volume the probe sets, other than the default of 1.
|
|
49
|
+
*/
|
|
50
|
+
var PROBE_VOLUME = .5;
|
|
51
|
+
/**
|
|
52
|
+
* Tried on an element of its own, so the one playing hears no volume change.
|
|
53
|
+
*/
|
|
54
|
+
function isVolumeSettable(document) {
|
|
55
|
+
const probe = document.createElement("audio");
|
|
56
|
+
probe.volume = PROBE_VOLUME;
|
|
57
|
+
return probe.volume === PROBE_VOLUME;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { PlayerSound };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { DEFAULT_VIEW_MODE } from "../../../core/src/domain/view/ViewMode.js";
|
|
2
|
+
import { SCREEN_CENTRE } from "../../../core/src/domain/view/screenLayout.js";
|
|
3
|
+
import { lookAt } from "../../../core/src/domain/view/viewGestures.js";
|
|
4
|
+
import { DEFAULT_FRAMING, isSameFraming } from "../../../core/src/domain/view/Framing.js";
|
|
5
|
+
import { followReading, withoutRoll } from "../../../core/src/domain/view/motionLookView.js";
|
|
6
|
+
import { motionLookRulesFor, viewModeRulesFor } from "../../../core/src/domain/view/viewModes.js";
|
|
7
|
+
import { anglesOf, isSameAngles } from "./viewAngles.js";
|
|
8
|
+
//#region ../../packages/player/src/player/PlayerView.ts
|
|
9
|
+
/**
|
|
10
|
+
* Every layout the player accepts has two lenses; a renderer attached says so itself.
|
|
11
|
+
*/
|
|
12
|
+
var LENS_COUNT_BEFORE_A_LOAD = 2;
|
|
13
|
+
/**
|
|
14
|
+
* How the picture is framed and which view mode shows it: kept across loads, drawn by whichever
|
|
15
|
+
* renderer is attached, and the normal view's angles announced when they change. The viewer's
|
|
16
|
+
* gestures and a host setting the view go through the mode's rules on the viewport as it is
|
|
17
|
+
* now; while the device holds the view (motion look, ADR 0040), through the rules it follows
|
|
18
|
+
* then.
|
|
19
|
+
*/
|
|
20
|
+
var PlayerView = class {
|
|
21
|
+
events;
|
|
22
|
+
measureViewport;
|
|
23
|
+
framing = DEFAULT_FRAMING;
|
|
24
|
+
mode = DEFAULT_VIEW_MODE;
|
|
25
|
+
surface;
|
|
26
|
+
lensCount = LENS_COUNT_BEFORE_A_LOAD;
|
|
27
|
+
/**
|
|
28
|
+
* The device reading the held view follows from; none while the device does not hold it.
|
|
29
|
+
*/
|
|
30
|
+
previous;
|
|
31
|
+
constructor(events, measureViewport) {
|
|
32
|
+
this.events = events;
|
|
33
|
+
this.measureViewport = measureViewport;
|
|
34
|
+
}
|
|
35
|
+
get current() {
|
|
36
|
+
return this.framing.view;
|
|
37
|
+
}
|
|
38
|
+
get viewMode() {
|
|
39
|
+
return this.mode;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whether a drag moves the picture as it is framed now.
|
|
43
|
+
*/
|
|
44
|
+
get canPan() {
|
|
45
|
+
return this.rules().canPan(this.framing);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Whether the device may turn the view in the current mode.
|
|
49
|
+
*/
|
|
50
|
+
get followsDevice() {
|
|
51
|
+
return motionLookRulesFor(this.mode) !== void 0;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The renderer of the loaded recording, or nothing between loads. A new renderer draws the
|
|
55
|
+
* framing as it is now, however it changed while the recording was loading; the lens tiles are
|
|
56
|
+
* measured by the lenses it draws from then on.
|
|
57
|
+
*/
|
|
58
|
+
attach(surface) {
|
|
59
|
+
this.surface = surface;
|
|
60
|
+
if (surface) this.lensCount = surface.lensCount;
|
|
61
|
+
surface?.setViewMode(this.mode);
|
|
62
|
+
surface?.setFraming(this.framing);
|
|
63
|
+
}
|
|
64
|
+
set(view) {
|
|
65
|
+
this.frame(this.rules().place(this.framing, view));
|
|
66
|
+
}
|
|
67
|
+
setMode(mode) {
|
|
68
|
+
if (mode === this.mode) return;
|
|
69
|
+
this.mode = mode;
|
|
70
|
+
this.surface?.setViewMode(mode);
|
|
71
|
+
this.events.emit("viewmodechange", mode);
|
|
72
|
+
}
|
|
73
|
+
lookAt(yaw, pitch) {
|
|
74
|
+
this.frame(this.rules().place(this.framing, lookAt(this.framing.view, yaw, pitch)));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Turns the view as the device turned: from its first reading on, the device holds the view.
|
|
78
|
+
*/
|
|
79
|
+
followDevice(reading) {
|
|
80
|
+
const hold = followReading(this.framing.view, this.previous, reading);
|
|
81
|
+
this.previous = hold.reading;
|
|
82
|
+
this.frame({
|
|
83
|
+
...this.framing,
|
|
84
|
+
view: hold.view
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The device no longer holds the view: it stays where it looks, level again.
|
|
89
|
+
*/
|
|
90
|
+
letGo() {
|
|
91
|
+
if (!this.previous) return;
|
|
92
|
+
this.previous = void 0;
|
|
93
|
+
this.frame({
|
|
94
|
+
...this.framing,
|
|
95
|
+
view: withoutRoll(this.framing.view)
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
pan(delta) {
|
|
99
|
+
this.frame(this.rules().pan(this.framing, delta, this.context()));
|
|
100
|
+
}
|
|
101
|
+
turn(yaw, pitch) {
|
|
102
|
+
this.frame(this.rules().turn(this.framing, {
|
|
103
|
+
yaw,
|
|
104
|
+
pitch
|
|
105
|
+
}, this.context()));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Zooms by `steps`, keeping the point of the viewport at `focus` on what it shows.
|
|
109
|
+
*/
|
|
110
|
+
zoom(steps, focus = SCREEN_CENTRE) {
|
|
111
|
+
this.frame(this.rules().zoom(this.framing, {
|
|
112
|
+
steps,
|
|
113
|
+
focus
|
|
114
|
+
}, this.context()));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Back to how the current mode starts; the other modes keep their framing.
|
|
118
|
+
*/
|
|
119
|
+
reset() {
|
|
120
|
+
this.frame(this.rules().reset(this.framing));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Draws any change; announces one of the angles a page sees, not a roll alone.
|
|
124
|
+
*/
|
|
125
|
+
frame(next) {
|
|
126
|
+
if (isSameFraming(next, this.framing)) return;
|
|
127
|
+
const haveAnglesChanged = !isSameAngles(next.view, this.framing.view);
|
|
128
|
+
this.framing = next;
|
|
129
|
+
this.surface?.setFraming(next);
|
|
130
|
+
if (haveAnglesChanged) this.events.emit("viewchange", anglesOf(next.view));
|
|
131
|
+
}
|
|
132
|
+
context() {
|
|
133
|
+
return {
|
|
134
|
+
viewport: this.measureViewport(),
|
|
135
|
+
lensCount: this.lensCount
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
rules() {
|
|
139
|
+
return (this.previous === void 0 ? void 0 : motionLookRulesFor(this.mode)) ?? viewModeRulesFor(this.mode);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
//#endregion
|
|
143
|
+
export { PlayerView };
|