···2021**Record Properties:**
2223-| Name | Type | Req'd | Description | Constraints |
24-| ------------- | -------- | ----- | -------------------------------------------------------------------------- | ------------------ |
25-| `streamer` | `string` | ✅ | DID of the streamer whose livestream is being published | Format: `did` |
26-| `server` | `string` | ✅ | did of the server that's currently rebroadcasting the livestream | Format: `did` |
27-| `broadcaster` | `string` | ❌ | did of the broadcaster that operates the server syndicating the livestream | Format: `did` |
28-| `updatedAt` | `string` | ✅ | Periodically updated timestamp when this origin last saw a livestream | Format: `datetime` |
29-| `irohTicket` | `string` | ❌ | Iroh ticket that can be used to access the livestream from the server | Max Length: 2048 |
03031---
32···69 "type": "string",
70 "maxLength": 2048,
71 "description": "Iroh ticket that can be used to access the livestream from the server"
0000072 }
73 }
74 }
···2021**Record Properties:**
2223+| Name | Type | Req'd | Description | Constraints |
24+| -------------- | -------- | ----- | -------------------------------------------------------------------------- | ------------------ |
25+| `streamer` | `string` | ✅ | DID of the streamer whose livestream is being published | Format: `did` |
26+| `server` | `string` | ✅ | did of the server that's currently rebroadcasting the livestream | Format: `did` |
27+| `broadcaster` | `string` | ❌ | did of the broadcaster that operates the server syndicating the livestream | Format: `did` |
28+| `updatedAt` | `string` | ✅ | Periodically updated timestamp when this origin last saw a livestream | Format: `datetime` |
29+| `irohTicket` | `string` | ❌ | Iroh ticket that can be used to access the livestream from the server | Max Length: 2048 |
30+| `websocketURL` | `string` | ❌ | URL of the websocket endpoint for the livestream | Format: `uri` |
3132---
33···70 "type": "string",
71 "maxLength": 2048,
72 "description": "Iroh ticket that can be used to access the livestream from the server"
73+ },
74+ "websocketURL": {
75+ "type": "string",
76+ "format": "uri",
77+ "description": "URL of the websocket endpoint for the livestream"
78 }
79 }
80 }
···652 ]
653 }
654 },
000000000000000000000000000000655 "/xrpc/place.stream.graph.getFollowingUser": {
656 "get": {
657 "summary": "Get whether or not user A is following user B.",
···2097 "record": {}
2098 },
2099 "required": ["cid", "record"]
000002100 },
2101 "com.atproto.repo.strongRef": {
2102 "type": "object",
···652 ]
653 }
654 },
655+ "/xrpc/place.stream.live.subscribeSegments": {
656+ "get": {
657+ "summary": "Subscribe to a stream's new segments as they come in!",
658+ "operationId": "place.stream.live.subscribeSegments",
659+ "tags": ["place.stream.live"],
660+ "x-websocket": true,
661+ "responses": {},
662+ "parameters": [
663+ {
664+ "name": "streamer",
665+ "in": "query",
666+ "required": true,
667+ "description": "The DID of the streamer to subscribe to",
668+ "schema": {
669+ "type": "string",
670+ "description": "The DID of the streamer to subscribe to"
671+ }
672+ }
673+ ],
674+ "x-websocket-message": {
675+ "schema": {
676+ "oneOf": [
677+ {
678+ "$ref": "#/components/schemas/place.stream.live.subscribeSegments_segment"
679+ }
680+ ]
681+ }
682+ }
683+ }
684+ },
685 "/xrpc/place.stream.graph.getFollowingUser": {
686 "get": {
687 "summary": "Get whether or not user A is following user B.",
···2127 "record": {}
2128 },
2129 "required": ["cid", "record"]
2130+ },
2131+ "place.stream.live.subscribeSegments_segment": {
2132+ "type": "string",
2133+ "format": "byte",
2134+ "description": "MP4 file of a user's signed livestream segment"
2135 },
2136 "com.atproto.repo.strongRef": {
2137 "type": "object",
+5
lexicons/place/stream/broadcast/origin.json
···34 "type": "string",
35 "maxLength": 2048,
36 "description": "Iroh ticket that can be used to access the livestream from the server"
0000037 }
38 }
39 }
···34 "type": "string",
35 "maxLength": 2048,
36 "description": "Iroh ticket that can be used to access the livestream from the server"
37+ },
38+ "websocketURL": {
39+ "type": "string",
40+ "format": "uri",
41+ "description": "URL of the websocket endpoint for the livestream"
42 }
43 }
44 }
+31
lexicons/place/stream/live/subscribeSegments.json
···0000000000000000000000000000000
···1+{
2+ "lexicon": 1,
3+ "id": "place.stream.live.subscribeSegments",
4+ "defs": {
5+ "main": {
6+ "type": "subscription",
7+ "description": "Subscribe to a stream's new segments as they come in!",
8+ "parameters": {
9+ "type": "params",
10+ "required": ["streamer"],
11+ "properties": {
12+ "streamer": {
13+ "type": "string",
14+ "description": "The DID of the streamer to subscribe to"
15+ }
16+ }
17+ },
18+ "message": {
19+ "schema": {
20+ "type": "union",
21+ "refs": ["#segment"]
22+ }
23+ },
24+ "errors": []
25+ },
26+ "segment": {
27+ "type": "bytes",
28+ "description": "MP4 file of a user's signed livestream segment"
29+ }
30+ }
31+}
···24 Streamer string `json:"streamer" cborgen:"streamer"`
25 // updatedAt: Periodically updated timestamp when this origin last saw a livestream
26 UpdatedAt string `json:"updatedAt" cborgen:"updatedAt"`
0027}
···24 Streamer string `json:"streamer" cborgen:"streamer"`
25 // updatedAt: Periodically updated timestamp when this origin last saw a livestream
26 UpdatedAt string `json:"updatedAt" cborgen:"updatedAt"`
27+ // websocketURL: URL of the websocket endpoint for the livestream
28+ WebsocketURL *string `json:"websocketURL,omitempty" cborgen:"websocketURL,omitempty"`
29}