space.remanso.recording
Schema Diff
+115 -0
Compatibility Analysis
Breaking Changes Detected
5 breaking changes, 17 non-breaking changes.
Breaking Changes (5)
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.createdAt", kind: "prop", name: Some("createdAt") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.text", kind: "prop", name: Some("text") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.endMs", kind: "prop", name: Some("endMs") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.startMs", kind: "prop", name: Some("startMs") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.text", kind: "prop", name: Some("text") }
Non-Breaking Changes (17)
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.createdAt" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.segments" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.segments:items" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.text" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.endMs" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.startMs" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.text" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording:body.language" }
- AddedVertex AddedVertex { vertex_id: "space.remanso.recording:body.transcript" }
- AddedEdge AddedEdge { src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.segments", kind: "prop", name: Some("segments") }
- AddedEdge AddedEdge { src: "space.remanso.recording#transcript.segments", tgt: "space.remanso.recording#transcript.segments:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "space.remanso.recording#transcript.segments:items", tgt: "space.remanso.recording#transcriptSegment", kind: "ref", name: None }
- AddedEdge AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.language", kind: "prop", name: Some("language") }
- AddedEdge AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.transcript", kind: "prop", name: Some("transcript") }
- AddedEdge AddedEdge { src: "space.remanso.recording:body.transcript", tgt: "space.remanso.recording#transcript", kind: "ref", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "space.remanso.recording#transcript" }AddedVertex { vertex_id: "space.remanso.recording#transcript.createdAt" }AddedVertex { vertex_id: "space.remanso.recording#transcript.segments" }AddedVertex { vertex_id: "space.remanso.recording#transcript.segments:items" }AddedVertex { vertex_id: "space.remanso.recording#transcript.text" }AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment" }AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.endMs" }AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.startMs" }AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.text" }AddedVertex { vertex_id: "space.remanso.recording:body.language" }AddedVertex { vertex_id: "space.remanso.recording:body.transcript" }
Additional Notes
- Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.createdAt", kind: "prop", name: Some("createdAt") }
- Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.text", kind: "prop", name: Some("text") }
- Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.endMs", kind: "prop", name: Some("endMs") }
- Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.startMs", kind: "prop", name: Some("startMs") }
- Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.text", kind: "prop", name: Some("text") }
- Non-breaking: AddedEdge { src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.segments", kind: "prop", name: Some("segments") }
- Non-breaking: AddedEdge { src: "space.remanso.recording#transcript.segments", tgt: "space.remanso.recording#transcript.segments:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "space.remanso.recording#transcript.segments:items", tgt: "space.remanso.recording#transcriptSegment", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.language", kind: "prop", name: Some("language") }
- Non-breaking: AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.transcript", kind: "prop", name: Some("transcript") }
- Non-breaking: AddedEdge { src: "space.remanso.recording:body.transcript", tgt: "space.remanso.recording#transcript", kind: "ref", name: None }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"credit": {
5
5
"description": "One openly licensed work used in the recording, and where its terms live.",
6
6
"properties": {
7
7
"creator": {
8
8
"maxLength": 1000,
9
9
"type": "string"
10
10
},
11
11
"license": {
12
12
"description": "The licence's short id, e.g. \"by\".",
13
13
"maxLength": 64,
14
14
"type": "string"
15
15
},
16
16
"licenseUrl": {
17
17
"format": "uri",
18
18
"type": "string"
19
19
},
20
20
"sourceUrl": {
21
21
"description": "The work's landing page at its provider.",
22
22
"format": "uri",
23
23
"type": "string"
24
24
},
25
25
"title": {
26
26
"maxLength": 1000,
27
27
"type": "string"
28
28
}
29
29
},
30
30
"required": [
31
31
"title",
32
32
"creator",
33
33
"license",
34
34
"licenseUrl",
35
35
"sourceUrl"
36
36
],
37
37
"type": "object"
38
38
},
39
39
"main": {
40
40
"description": "An audio recording — a past stream, a podcast episode, a voice note. A recording at rkey R is the recording of the space.remanso.note at rkey R in the same repo: one note, at most one recording, paired by convention rather than by a field, so a reader that knows the note's did and rkey reaches the audio with a single getRecord. A recording whose rkey matches no note stands alone and belongs to nobody. Legacy path: a recording is also referenced from a note by at-uri embedded in the note's content.",
41
41
"key": "tid",
42
42
"record": {
43
43
"properties": {
44
44
"audio": {
45
45
"accept": [
46
46
"audio/*",
47
47
"video/mp4",
48
48
"video/webm"
49
49
],
50
50
"description": "The recording itself. video/mp4 and video/webm are accepted alongside audio/* because a PDS sniffs the container rather than trusting the upload's Content-Type: an audio-only MP4 or M4A sniffs as video/mp4, and a sniffer that reads no further than the EBML magic calls an audio-only WebM video/webm.",
51
51
"maxSize": 50000000,
52
52
"type": "blob"
53
53
},
54
54
"createdAt": {
55
55
"format": "datetime",
56
56
"type": "string"
57
57
},
58
58
"credits": {
59
59
"description": "Attribution for openly licensed music mixed into the recording. Only licences that require it are listed — a CC0 track is deliberately absent, because CC0 asks for nothing and an entry here would imply otherwise.",
60
60
"items": {
61
61
"ref": "#credit",
62
62
"type": "ref"
63
63
},
64
64
"maxLength": 64,
65
65
"type": "array"
66
66
},
67
67
"durationSec": {
68
68
"description": "Playback length in seconds.",
69
69
"type": "integer"
70
70
},
71
+
"language": {
72
+
"description": "The language spoken in the recording. ISO 639-3, the same code space as space.remanso.note's `language`, so a note and its recording agree on how a language is spelled. A recording whose speech was never identified simply omits this.",
73
+
"knownValues": [
74
+
"afr",
75
+
"ara",
76
+
"aze",
77
+
"bel",
78
+
"ben",
79
+
"bul",
80
+
"cat",
81
+
"ces",
82
+
"ckb",
83
+
"cmn",
84
+
"dan",
85
+
"deu",
86
+
"ell",
87
+
"eng",
88
+
"est",
89
+
"eus",
90
+
"fin",
91
+
"fra",
92
+
"hau",
93
+
"heb",
94
+
"hin",
95
+
"hrv",
96
+
"hun",
97
+
"hye",
98
+
"ind",
99
+
"isl",
100
+
"ita",
101
+
"jpn",
102
+
"kat",
103
+
"kaz",
104
+
"kor",
105
+
"lit",
106
+
"mar",
107
+
"mkd",
108
+
"nld",
109
+
"nob",
110
+
"pes",
111
+
"pol",
112
+
"por",
113
+
"ron",
114
+
"run",
115
+
"rus",
116
+
"slk",
117
+
"spa",
118
+
"srp",
119
+
"swe",
120
+
"tgl",
121
+
"tur",
122
+
"ukr",
123
+
"vie"
124
+
],
125
+
"maxLength": 10,
126
+
"type": "string"
127
+
},
71
128
"recordedAt": {
72
129
"description": "When the audio was originally captured — a past stream's air date, not the upload time.",
73
130
"format": "datetime",
74
131
"type": "string"
75
132
},
76
133
"title": {
77
134
"maxLength": 1000,
78
135
"type": "string"
136
+
},
137
+
"transcript": {
138
+
"ref": "#transcript",
139
+
"type": "ref"
79
140
}
80
141
},
81
142
"required": [
82
143
"audio",
83
144
"createdAt"
84
145
],
85
146
"type": "object"
86
147
},
87
148
"type": "record"
149
+
},
150
+
"transcript": {
151
+
"description": "What was said, as text. A recording is published before anything has transcribed it, so audio with no transcript is the normal starting state rather than an incomplete record — which is why this is optional and written by a later putRecord. `text` is the whole transcript in reading order and is always present; `segments` is that same text cut into timestamped spans. The two never disagree: a client renders either one without reconciling them, and a writer that edits one rewrites both.",
152
+
"properties": {
153
+
"createdAt": {
154
+
"description": "When this transcript was written, which is later than the recording's own createdAt, and is bumped on every correction.",
155
+
"format": "datetime",
156
+
"type": "string"
157
+
},
158
+
"segments": {
159
+
"description": "The transcript cut into timestamped spans, one paragraph each — the granularity a reader scans and seeks by, not the two-second slivers a speech model emits. Absent when the audio yielded no usable timestamps, which happens on very short clips.",
160
+
"items": {
161
+
"ref": "#transcriptSegment",
162
+
"type": "ref"
163
+
},
164
+
"maxLength": 4096,
165
+
"type": "array"
166
+
},
167
+
"text": {
168
+
"description": "The transcript in reading order, paragraphs separated by a blank line. Equal to `segments` joined the same way, when segments are present.",
169
+
"maxLength": 100000,
170
+
"type": "string"
171
+
}
172
+
},
173
+
"required": [
174
+
"text",
175
+
"createdAt"
176
+
],
177
+
"type": "object"
178
+
},
179
+
"transcriptSegment": {
180
+
"description": "One timestamped span of the transcript. Offsets are milliseconds from the start of the audio: the lexicon data model has no float, and rounding to whole seconds would land a seek target after the words the timestamp labels.",
181
+
"properties": {
182
+
"endMs": {
183
+
"description": "Offset from the start of the audio, in milliseconds. Never before `startMs`.",
184
+
"minimum": 0,
185
+
"type": "integer"
186
+
},
187
+
"startMs": {
188
+
"description": "Offset from the start of the audio, in milliseconds.",
189
+
"minimum": 0,
190
+
"type": "integer"
191
+
},
192
+
"text": {
193
+
"maxLength": 10000,
194
+
"type": "string"
195
+
}
196
+
},
197
+
"required": [
198
+
"startMs",
199
+
"endMs",
200
+
"text"
201
+
],
202
+
"type": "object"
88
203
}
89
204
},
90
205
"id": "space.remanso.recording",
91
206
"lexicon": 1
92
207
}