Live video on the AT Protocol

run `make fix`

+27 -22
+17 -15
js/docs/src/content/docs/video-metadata/c2pa-integration.md
··· 6 7 The actual metadata insertion and signing done to each video segment is through 8 [C2PA](https://c2pa.org/) tooling. A 9 - [fork](https://github.com/streamplace/c2pa-rs) of their Rust 10 - SDK that adds support for ES256K is used, and called in Go through FFI. The code 11 - for this can be seen in `rust/iroh-streamplace/src/c2pa.rs`. 12 13 The metadata stored in the video with C2PA must be in a valid C2PA "manifest" 14 format, documented in the specification. Here is an example Streamplace ··· 97 "Iptc4xmpExt": "http://iptc.org/std/Iptc4xmpExt/2008-02-29/" 98 }, 99 "dc:creator": "did:plc:y3lae7hmqiwyq7w2v3bcb2c2", 100 - "dc:title": [ 101 - "🦎🦎" 102 - ], 103 - "dc:date": [ 104 - "2025-10-21T19:24:24.156Z" 105 - ], 106 "distributionPolicy": { 107 "deleteAfter": "2025-10-21T19:29:24.000Z" 108 }, ··· 157 158 The official version of c2patool can extract this manifest, but will not 159 consider it valid due to the use of ES256K. If you build c2patool from the 160 - [fork](https://github.com/streamplace/c2pa-rs) used by 161 - Streamplace, it will validate. 162 163 Note the variety of information stored in the manifest: user DID, signing key, 164 timestamp, content warnings, copyright, etc. More can be added in the future, 165 for example whether you consent to remixing. 166 167 - You can see several assertions with the name `place.stream.*`. This is 168 - where Streamplace-specific metadata is stored, and is related to the lexicon. 169 - It's the easiest place to parse out this metadata. 170 171 - In addition to the primary `place.stream` assertions, we make a best-effort attempt to translate the Streamplace assertions into spec-compliant C2PA metadata assertions, which are also included in the signed manifest. This allows other C2PA-compliant software to parse out information about Streamplace segments, such as content warnings. However, not everything Streamplace does fits neatly into C2PA-compliant metadata, so the primary source of truth for metadata on a Streamplace segment remains the `place.stream` assertions. 172 173 ## Code paths 174
··· 6 7 The actual metadata insertion and signing done to each video segment is through 8 [C2PA](https://c2pa.org/) tooling. A 9 + [fork](https://github.com/streamplace/c2pa-rs) of their Rust SDK that adds 10 + support for ES256K is used, and called in Go through FFI. The code for this can 11 + be seen in `rust/iroh-streamplace/src/c2pa.rs`. 12 13 The metadata stored in the video with C2PA must be in a valid C2PA "manifest" 14 format, documented in the specification. Here is an example Streamplace ··· 97 "Iptc4xmpExt": "http://iptc.org/std/Iptc4xmpExt/2008-02-29/" 98 }, 99 "dc:creator": "did:plc:y3lae7hmqiwyq7w2v3bcb2c2", 100 + "dc:title": ["🦎🦎"], 101 + "dc:date": ["2025-10-21T19:24:24.156Z"], 102 "distributionPolicy": { 103 "deleteAfter": "2025-10-21T19:29:24.000Z" 104 }, ··· 153 154 The official version of c2patool can extract this manifest, but will not 155 consider it valid due to the use of ES256K. If you build c2patool from the 156 + [fork](https://github.com/streamplace/c2pa-rs) used by Streamplace, it will 157 + validate. 158 159 Note the variety of information stored in the manifest: user DID, signing key, 160 timestamp, content warnings, copyright, etc. More can be added in the future, 161 for example whether you consent to remixing. 162 163 + You can see several assertions with the name `place.stream.*`. This is where 164 + Streamplace-specific metadata is stored, and is related to the lexicon. It's the 165 + easiest place to parse out this metadata. 166 167 + In addition to the primary `place.stream` assertions, we make a best-effort 168 + attempt to translate the Streamplace assertions into spec-compliant C2PA 169 + metadata assertions, which are also included in the signed manifest. This allows 170 + other C2PA-compliant software to parse out information about Streamplace 171 + segments, such as content warnings. However, not everything Streamplace does 172 + fits neatly into C2PA-compliant metadata, so the primary source of truth for 173 + metadata on a Streamplace segment remains the `place.stream` assertions. 174 175 ## Code paths 176
+4 -2
js/docs/src/content/docs/video-metadata/metadata-record.md
··· 20 the 21 [IPTC controlled vocabulary for content warnings](https://cv.iptc.org/newscodes/contentwarning/). 22 Each warning provides descriptions to help creators properly categorize their 23 - content. Streamplace node operators may also configure their nodes to exclude certain types of content. 24 2. **Content Rights** (`place.stream.metadata.contentRights`): This section 25 captures copyright and attribution information, including the creator’s name, 26 copyright notice, publication year, license type, and credit line. The system ··· 31 3. **Distribution Policy** (`place.stream.metadata.distributionPolicy`): This 32 section currently allows creators to specify a `deleteAfter` property, which 33 is meant to indicate the time after which the user no longer wants the stream 34 - to be made available for playback. It also allows you to optionally restrict syndication of your livestream to a certain set of broadcasters. 35 36 When a user creates or updates their metadata configuration through the 37 frontend, the record is published to their Personal Data Server (PDS) with the
··· 20 the 21 [IPTC controlled vocabulary for content warnings](https://cv.iptc.org/newscodes/contentwarning/). 22 Each warning provides descriptions to help creators properly categorize their 23 + content. Streamplace node operators may also configure their nodes to exclude 24 + certain types of content. 25 2. **Content Rights** (`place.stream.metadata.contentRights`): This section 26 captures copyright and attribution information, including the creator’s name, 27 copyright notice, publication year, license type, and credit line. The system ··· 32 3. **Distribution Policy** (`place.stream.metadata.distributionPolicy`): This 33 section currently allows creators to specify a `deleteAfter` property, which 34 is meant to indicate the time after which the user no longer wants the stream 35 + to be made available for playback. It also allows you to optionally restrict 36 + syndication of your livestream to a certain set of broadcasters. 37 38 When a user creates or updates their metadata configuration through the 39 frontend, the record is published to their Personal Data Server (PDS) with the
+6 -5
js/docs/src/content/docs/video-metadata/signing.md
··· 22 and **distribution policy**. This record is also synced by nodes to their 23 local database. 24 5. **Stream Authentication**: When a user starts a stream, they include their 25 - stream key as a param in the WHIP or RTMPS request to the node. The node decodes the 26 - key, extracts the private key and DID, and verifies that the public key 27 - exists and is valid. 28 6. **Signer Creation**: Once authenticated, the node creates a signer instance 29 using the user's private key. 30 7. **Segmentation**: The incoming live stream is segmented into one-second MP4 31 chunks. 32 8. **Manifest Creation and Signing**: For each segment, the node creates a C2PA 33 - manifest using the user's metadata configuration. It then uses the streamer's private key to sign the manifest, and embeds the signed manifest directly into 34 - the MP4 segment. 35 9. **Signed Segments**: The output is a continuous stream of MP4 segments, each 36 cryptographically signed and containing its own C2PA manifest.
··· 22 and **distribution policy**. This record is also synced by nodes to their 23 local database. 24 5. **Stream Authentication**: When a user starts a stream, they include their 25 + stream key as a param in the WHIP or RTMPS request to the node. The node 26 + decodes the key, extracts the private key and DID, and verifies that the 27 + public key exists and is valid. 28 6. **Signer Creation**: Once authenticated, the node creates a signer instance 29 using the user's private key. 30 7. **Segmentation**: The incoming live stream is segmented into one-second MP4 31 chunks. 32 8. **Manifest Creation and Signing**: For each segment, the node creates a C2PA 33 + manifest using the user's metadata configuration. It then uses the streamer's 34 + private key to sign the manifest, and embeds the signed manifest directly 35 + into the MP4 segment. 36 9. **Signed Segments**: The output is a continuous stream of MP4 segments, each 37 cryptographically signed and containing its own C2PA manifest.