@bubo-squared/gyroview 0.2.0 → 0.3.1

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 (74) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +35 -15
  3. package/dist/index.d.ts +21 -2
  4. package/dist/index.js +2 -2
  5. package/dist/packages/adapters/fetch/src/HttpByteStream.js +174 -0
  6. package/dist/packages/adapters/fetch/src/HttpRangeSource.js +14 -170
  7. package/dist/packages/adapters/fetch/src/HttpResource.js +192 -0
  8. package/dist/packages/adapters/fetch/src/contentRange.js +15 -0
  9. package/dist/packages/adapters/fetch/src/httpRequest.js +5 -3
  10. package/dist/packages/adapters/fetch/src/index.js +3 -1
  11. package/dist/packages/adapters/fetch/src/passingFailures.js +24 -0
  12. package/dist/packages/adapters/fetch/src/rangeFailures.js +17 -0
  13. package/dist/packages/adapters/fetch/src/recordingVersion.js +37 -0
  14. package/dist/packages/adapters/mediabunny/src/MediabunnyAudioPackager.js +129 -0
  15. package/dist/packages/adapters/mediabunny/src/MediabunnyCodecReader.js +80 -0
  16. package/dist/packages/adapters/mediabunny/src/SegmentChannel.js +58 -6
  17. package/dist/packages/adapters/mediabunny/src/decoderConfigurations.js +28 -0
  18. package/dist/packages/adapters/mediabunny/src/index.js +3 -2
  19. package/dist/packages/adapters/webcodecs/src/WebCodecsVideoDecoderPort.js +12 -3
  20. package/dist/packages/core/src/application/download/BlockStore.js +97 -0
  21. package/dist/packages/core/src/application/download/DownloadedAudioSamples.js +50 -0
  22. package/dist/packages/core/src/application/download/DownloadedVideoTrack.js +122 -0
  23. package/dist/packages/core/src/application/download/FileDownload.js +183 -0
  24. package/dist/packages/core/src/application/download/RecordingBuffer.js +22 -0
  25. package/dist/packages/core/src/application/download/SampleCursor.js +88 -0
  26. package/dist/packages/core/src/application/download/SourceByteStream.js +46 -0
  27. package/dist/packages/core/src/application/download/Transfers.js +75 -0
  28. package/dist/packages/core/src/application/download/startFileDownload.js +37 -0
  29. package/dist/packages/core/src/application/playback/Buffering.js +53 -0
  30. package/dist/packages/core/src/application/playback/DecodePipeline.js +11 -7
  31. package/dist/packages/core/src/application/playback/DecodeRun.js +15 -0
  32. package/dist/packages/core/src/application/playback/PlaybackSession.js +18 -27
  33. package/dist/packages/core/src/application/playback/keyframeTimeAt.js +1 -1
  34. package/dist/packages/core/src/application/playback/probeDecoding.js +17 -3
  35. package/dist/packages/core/src/application/recording/readSampleTable.js +27 -0
  36. package/dist/packages/core/src/application/recording/timeRecording.js +3 -3
  37. package/dist/packages/core/src/domain/container/KeyframeRule.js +7 -0
  38. package/dist/packages/core/src/domain/container/SampleTable.js +29 -0
  39. package/dist/packages/core/src/domain/container/TrackSampleTable.js +96 -0
  40. package/dist/packages/core/src/domain/container/presentationOrder.js +10 -0
  41. package/dist/packages/core/src/domain/download/DownloadPolicy.js +41 -0
  42. package/dist/packages/core/src/domain/download/isReadyToResume.js +27 -0
  43. package/dist/packages/core/src/domain/download/planDownloads.js +175 -0
  44. package/dist/packages/core/src/domain/download/trackNeeds.js +32 -0
  45. package/dist/packages/core/src/domain/format/boxes/boxHeader.js +44 -0
  46. package/dist/packages/core/src/domain/format/boxes/scanBoxes.js +7 -34
  47. package/dist/packages/core/src/domain/format/mp4/keyframeRules.js +81 -0
  48. package/dist/packages/core/src/domain/format/mp4/movieBoxes.js +52 -0
  49. package/dist/packages/core/src/domain/format/mp4/mp4BoxTypes.js +46 -0
  50. package/dist/packages/core/src/domain/format/mp4/mp4Layouts.js +183 -0
  51. package/dist/packages/core/src/domain/format/mp4/parseMovie.js +67 -0
  52. package/dist/packages/core/src/domain/format/mp4/readTable.js +31 -0
  53. package/dist/packages/core/src/domain/format/mp4/sampleLocations.js +69 -0
  54. package/dist/packages/core/src/domain/format/mp4/sampleTiming.js +109 -0
  55. package/dist/packages/core/src/domain/format/mp4/trackHeaders.js +75 -0
  56. package/dist/packages/core/src/index.js +10 -2
  57. package/dist/packages/core/src/shared/async/iteration.js +24 -0
  58. package/dist/packages/core/src/shared/binary/ByteRange.js +12 -0
  59. package/dist/packages/core/src/shared/binary/ByteRangeSet.js +85 -0
  60. package/dist/packages/core/src/shared/binary/ByteReader.js +21 -3
  61. package/dist/packages/core/src/shared/binary/concatenated.js +15 -0
  62. package/dist/packages/core/src/shared/errors/GyroViewError.js +56 -3
  63. package/dist/packages/core/src/shared/math/countAtOrBelow.js +17 -0
  64. package/dist/packages/player/src/composition/browserPorts.js +23 -4
  65. package/dist/packages/player/src/composition/buildPipeline.js +15 -3
  66. package/dist/packages/player/src/composition/openInputs.js +51 -107
  67. package/dist/packages/player/src/composition/readInputs.js +111 -0
  68. package/dist/packages/player/src/controls/messages.js +3 -1
  69. package/dist/packages/player/src/inspectRecording.js +1 -1
  70. package/dist/standalone.js +58 -58
  71. package/package.json +1 -1
  72. package/dist/packages/adapters/mediabunny/src/MediabunnyAudioSegments.js +0 -133
  73. package/dist/packages/adapters/mediabunny/src/MediabunnyDemuxer.js +0 -63
  74. package/dist/packages/adapters/mediabunny/src/MediabunnyVideoTrackReader.js +0 -84
@@ -0,0 +1,111 @@
1
+ import { ensureInvariant, hasErrorCode } from "../../../core/src/shared/errors/GyroViewError.js";
2
+ import { readRecording } from "../../../core/src/application/recording/readRecording.js";
3
+ import { readSampleTable } from "../../../core/src/application/recording/readSampleTable.js";
4
+ import { detectLensLayout } from "../../../core/src/domain/format/layout/detectLensLayout.js";
5
+ import "../../../core/src/index.js";
6
+ import { inputName } from "../PlayerSource.js";
7
+ //#region ../../packages/player/src/composition/readInputs.ts
8
+ /**
9
+ * Reads the given inputs, and the other lens file an info record declares, as one recording: its
10
+ * metadata from the input that carries the trailer, and every input's sample table and codecs.
11
+ */
12
+ async function readInputs(inputs, attempt) {
13
+ const { ports, signal } = attempt;
14
+ const given = inputs.map((input) => ({
15
+ input,
16
+ opened: ports.sources.open(input, signal)
17
+ }));
18
+ const recording = await readRecordingOf(given, ports);
19
+ signal.throwIfAborted();
20
+ const openings = [...given, ...await declaredSecond(given, recording, attempt)];
21
+ const read = await Promise.all(openings.map((opening) => readInput(opening, ports)));
22
+ signal.throwIfAborted();
23
+ return {
24
+ recording,
25
+ inputs: read
26
+ };
27
+ }
28
+ function describedInput(read) {
29
+ const videoTracks = read.codecs.video.map(({ description }) => ({ description }));
30
+ return {
31
+ name: inputName(read.input),
32
+ videoTracks
33
+ };
34
+ }
35
+ async function readInput(opening, ports) {
36
+ const { source } = opening.opened;
37
+ const { table, movieBytes } = await readSampleTable(source);
38
+ const codecs = await ports.codecReader.read(movieBytes);
39
+ return {
40
+ ...opening,
41
+ table,
42
+ codecs,
43
+ size: await source.size()
44
+ };
45
+ }
46
+ /**
47
+ * The other lens file a lone file's info record says the recording is split into, when the
48
+ * server has it: found before the lone file's tracks are read, which finding it only once they
49
+ * fell short would read twice. A file that does not say so still gets its sibling looked for
50
+ * once its tracks fall short (see openRecording).
51
+ */
52
+ async function declaredSecond(given, recording, attempt) {
53
+ if (!(given.length === 1 && recording.info.fileLayout === "split-files") || !attempt.findSecondFile) return [];
54
+ const input = await attempt.findSecondFile();
55
+ attempt.signal.throwIfAborted();
56
+ return input === void 0 ? [] : [{
57
+ input,
58
+ opened: attempt.ports.sources.open(input, attempt.signal)
59
+ }];
60
+ }
61
+ /**
62
+ * The layout hints of a file without an info record: the tracks alone decide.
63
+ */
64
+ var NO_HINTS = {
65
+ fileLayout: void 0,
66
+ trackOrder: void 0
67
+ };
68
+ async function readRecordingOf(openings, ports) {
69
+ try {
70
+ return await readTrailerCarrier(openings.map(({ opened }) => opened.source));
71
+ } catch (error) {
72
+ const [only] = openings;
73
+ if (openings.length === 1 && hasErrorCode(error, "invalid-trailer") && only) await refuseAsLoneHalf(only, ports);
74
+ throw error;
75
+ }
76
+ }
77
+ /**
78
+ * A file without a trailer may be the _10_ half of an older camera's pair, which writes the
79
+ * trailer to _00_ alone: its one square track tells, and the refusal asks for the other file
80
+ * instead of calling it damaged. Anything else leaves the trailer's own refusal standing.
81
+ */
82
+ async function refuseAsLoneHalf(opening, ports) {
83
+ let read;
84
+ try {
85
+ read = await readInput(opening, ports);
86
+ } catch {
87
+ return;
88
+ }
89
+ try {
90
+ detectLensLayout([describedInput(read)], NO_HINTS);
91
+ } catch (error) {
92
+ if (hasErrorCode(error, "missing-second-file")) throw error;
93
+ }
94
+ }
95
+ /**
96
+ * The recording read from the input that carries the trailer: the first, or the second when the
97
+ * first has none, as the _10_ file of an older camera's pair, which writes it to _00_ alone,
98
+ * when the pair is given the other way round.
99
+ */
100
+ async function readTrailerCarrier(sources) {
101
+ const [first, second] = sources;
102
+ ensureInvariant(first !== void 0, "a recording needs at least one input");
103
+ try {
104
+ return await readRecording(first);
105
+ } catch (error) {
106
+ if (second === void 0 || !hasErrorCode(error, "invalid-trailer")) throw error;
107
+ return readRecording(second);
108
+ }
109
+ }
110
+ //#endregion
111
+ export { describedInput, readInputs };
@@ -71,13 +71,15 @@ var DEFAULT_MESSAGES = {
71
71
  "playback-blocked": FAILED,
72
72
  "range-unsupported": UNREACHABLE,
73
73
  "render-unavailable": UNSUPPORTED_BROWSER,
74
+ "source-changed": "The video was replaced while it played.",
74
75
  "source-truncated": UNREACHABLE,
75
76
  "source-unreadable": UNREACHABLE,
76
77
  "unsupported-calibration": UNREADABLE,
77
78
  "unsupported-container": UNREADABLE,
78
79
  "unsupported-gyro-record": UNREADABLE,
79
80
  "unsupported-info-format": UNREADABLE,
80
- "unsupported-layout": UNREADABLE
81
+ "unsupported-layout": UNREADABLE,
82
+ "webcodecs-unavailable": UNSUPPORTED_BROWSER
81
83
  }
82
84
  };
83
85
  /**
@@ -9,7 +9,7 @@ import { browserSources } from "./composition/browserPorts.js";
9
9
  */
10
10
  function inspectRecording(recording, options = {}) {
11
11
  const signal = options.signal ?? new AbortController().signal;
12
- const source = browserSources(options.http ?? {}).open(inputOf(recording), signal);
12
+ const { source } = browserSources(options.http ?? {}).open(inputOf(recording), signal);
13
13
  return inspectRecording$1(source);
14
14
  }
15
15
  function inputOf(recording) {