···438438.PHONY: ci-lexicons
439439ci-lexicons:
440440 $(MAKE) lexicons \
441441- && if ! git diff --exit-code >/dev/null; then echo "lexicons are out of date, run 'make lexicons' to fix"; exit 1; fi
441441+ && if ! git diff --exit-code >/dev/null; then echo "lexicons are out of date, run 'make lexicons' to fix"; git diff; exit 1; fi
442442443443# _______ ______ _____ _______ _____ _ _ _____
444444# |__ __| ____|/ ____|__ __|_ _| \ | |/ ____|
···11+import { Platform } from "react-native";
22+33+export default function clearQueryParams(par = ["iss", "state", "code"]) {
44+ if (Platform.OS !== "web") {
55+ return;
66+ }
77+ const u = new URL(document.location.href);
88+ const params = new URLSearchParams(u.search);
99+ if (u.search === "") {
1010+ return;
1111+ }
1212+ par.forEach((p) => params.delete(p));
1313+ u.search = params.toString();
1414+ window.history.replaceState(null, "", u.toString());
1515+}
+3-6
js/atproto-oauth-client-react-native/README.md
···8787forwarded the port with `adb reverse`. For testing on iOS hardware, you'll
8888instead need to set up TLS.
89899090-[react-native-quick-crypto]:
9191- https://github.com/margelo/react-native-quick-crypto
9090+[react-native-quick-crypto]: https://github.com/margelo/react-native-quick-crypto
9291[expo-sqlite]: https://docs.expo.dev/versions/latest/sdk/sqlite/
9393-[README]:
9494- https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client-browser
9595-[example]:
9696- https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client-browser-example
9292+[README]: https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client-browser
9393+[example]: https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client-browser-example
···11+censored-text-hide = Hide Text
22+censored-text-reveal = Reveal Text
33+censored-text-blocked-with-reasons = This text was blocked because of these reasons: { $reasons }
44+censored-text-blocked-unknown = This text was blocked for an unknown reason
55+66+category-discriminatory = Discriminatory content
77+category-sexually-explicit = Sexually explicit content
88+category-profanity = Profanity
+13-1
js/components/locales/en-US/common.ftl
···5151 [streamer] Looks like <1>@{ $handle } is offline</1>, but they recommend checking out:
5252 *[default] Looks like <1>@{ $handle } is offline</1>, but we recommend checking out:
5353}
5454-user-offline-no-recommendations =
5454+user-offline-no-recommendations =
5555 Looks like <1>@{ $handle } is offline</1> right now.
5656 Check back later.
5757streaming-title = streaming { $title }
···6060 [1] 1 viewer
6161 *[other] { $count } viewers
6262}
6363+6464+## PDS Host Selector
6565+pds-selector-title = New to the Atmosphere?
6666+pds-selector-description = You'll need to select a PDS (Personal Data Server) to access apps on the Atmosphere, such as Bluesky, Tangled, and Spark.
6767+pds-selector-custom-label = Another PDS
6868+pds-selector-custom-description = Enter your own PDS host URL
6969+pds-selector-custom-url-label = Custom PDS URL
7070+pds-selector-custom-url-placeholder = https://pds.example.com
7171+pds-selector-learn-more = Learn more about self-hosting
7272+pds-selector-info = Each host has their own policies and reliability standards. Your ATProto data lives on the host you choose and you can migrate later. Note: Streamplace has its own moderation rules - you can be banned from Streamplace regardless of which host you choose.
7373+pds-selector-read-policies = Read { $label }'s <tosLink>Terms of Service</tosLink> and <privacyLink>Privacy Policy</privacyLink> before continuing.
7474+pds-selector-handle-policy-checkbox = I have read and agree to the <policyLink>handle policy</policyLink>
+8
js/components/locales/es-ES/chat.ftl
···11+censored-text-hide = Ocultar texto
22+censored-text-reveal = Revelar texto
33+censored-text-blocked-with-reasons = Este texto fue bloqueado por estas razones: { $reasons }
44+censored-text-blocked-unknown = Este texto fue bloqueado por un motivo desconocido
55+66+category-discriminatory = Contenido discriminatorio
77+category-sexually-explicit = Contenido sexualmente explícito
88+category-profanity = Blasfemia
+8
js/components/locales/fr-FR/chat.ftl
···11+censored-text-hide = Masquer le texte
22+censored-text-reveal = Révéler le texte
33+censored-text-blocked-with-reasons = Ce texte a été bloqué pour ces raisons : { $reasons }
44+censored-text-blocked-unknown = Ce texte a été bloqué pour une raison inconnue
55+66+category-discriminatory = Contenu discriminatoire
77+category-sexually-explicit = Contenu sexuellement explicite
88+category-profanity = Blasphème
+8
js/components/locales/pt-BR/chat.ftl
···11+censored-text-hide = Ocultar texto
22+censored-text-reveal = Revelar texto
33+censored-text-blocked-with-reasons = Este texto foi bloqueado por estes motivos: { $reasons }
44+censored-text-blocked-unknown = Este texto foi bloqueado por um motivo desconhecido
55+66+category-discriminatory = Conteúdo discriminatório
77+category-sexually-explicit = Conteúdo sexualmente explícito
88+category-profanity = Profanidade
···11// barrel file :)
22+export * from "./useAQState";
23export * from "./useAvatars";
34export * from "./useCameraToggle";
45export * from "./useDocumentTitle";
···22// Metro will use this file for React Native builds
3344// Import all translations directly so they're bundled into the app
55+import enUSChat from "../../public/locales/en-US/chat.json";
56import enUSCommon from "../../public/locales/en-US/common.json";
67import enUSSettings from "../../public/locales/en-US/settings.json";
88+import esESChat from "../../public/locales/es-ES/chat.json";
79import esESCommon from "../../public/locales/es-ES/common.json";
810import esESSettings from "../../public/locales/es-ES/settings.json";
1111+import frFRChat from "../../public/locales/fr-FR/chat.json";
912import frFRCommon from "../../public/locales/fr-FR/common.json";
1013import frFRSettings from "../../public/locales/fr-FR/settings.json";
1414+import ptBRChat from "../../public/locales/pt-BR/chat.json";
1115import ptBRCommon from "../../public/locales/pt-BR/common.json";
1216import ptBRSettings from "../../public/locales/pt-BR/settings.json";
1717+import zhHantChat from "../../public/locales/zh-Hant/chat.json";
1318import zhHantCommon from "../../public/locales/zh-Hant/common.json";
1419import zhHantSettings from "../../public/locales/zh-Hant/settings.json";
15201621const translationMap: Record<string, any> = {
2222+ "en-US/chat": enUSChat,
1723 "en-US/common": enUSCommon,
1824 "en-US/settings": enUSSettings,
2525+ "pt-BR/chat": ptBRChat,
1926 "pt-BR/common": ptBRCommon,
2027 "pt-BR/settings": ptBRSettings,
2828+ "es-ES/chat": esESChat,
2129 "es-ES/common": esESCommon,
2230 "es-ES/settings": esESSettings,
3131+ "zh-Hant/chat": zhHantChat,
2332 "zh-Hant/common": zhHantCommon,
2433 "zh-Hant/settings": zhHantSettings,
3434+ "fr-FR/chat": frFRChat,
2535 "fr-FR/common": frFRCommon,
2636 "fr-FR/settings": frFRSettings,
2737};
+1-1
js/components/src/i18n/i18next-config.ts
···116116117117export const I18NEXT_CONFIG = {
118118 lng: LOCALE,
119119- ns: ["common", "settings"], // Common should be first as it's most frequently used
119119+ ns: ["common", "settings", "chat"], // Common should be first as it's most frequently used
120120 defaultNS: "common",
121121 interpolation: {
122122 escapeValue: false, // React already safes from XSS
+1
js/components/src/index.tsx
···33333434export * from "./components/chat/chat";
3535export * from "./components/chat/chat-box";
3636+export * from "./components/chat/chat-settings";
3637export * from "./components/chat/system-message";
3738export * from "./components/chat/update-stream-title-dialog";
3839export { default as VideoRetry } from "./components/mobile-player/video-retry";
+3
js/components/src/player-store/player-state.tsx
···6363 ingestAutoStart?: boolean;
6464 setIngestAutoStart?: (autoStart: boolean) => void;
65656666+ /** stop ingest process, again with a slight delay to allow UI to update */
6767+ stopIngest: () => void;
6868+6669 /** Timestamp (number) when ingest started, or null if not started */
6770 ingestStarted: number | null;
6871
···11+---
22+import { Card, CardGrid } from "@astrojs/starlight/components";
33+44+interface Props {
55+ searchPlaceholder?: string;
66+}
77+---
88+99+<div class="helpdesk">
1010+1111+ <h2>How can we help?</h2>
1212+ <p>Search the knowledge base, or check out topics below.</p>
1313+1414+ <CardGrid>
1515+ <Card title="Getting Started" icon="rocket">
1616+ <p>New to Streamplace? Start here to set up your first stream.</p>
1717+ <ul>
1818+ <li><a href="/docs/guides/start-streaming/quick-start">Quick start guide</a></li>
1919+ <li><a href="/docs/guides/start-streaming/obs">Stream with OBS</a></li>
2020+ </ul>
2121+ </Card>
2222+2323+ <Card title="Developers & Self-Hosters" icon="laptop">
2424+ <p>Building with Streamplace or running your own node?</p>
2525+ <ul>
2626+ <li><a href="/docs/developers">Developer documentation</a></li>
2727+ </ul>
2828+ </Card>
2929+ </CardGrid>
3030+</div>
3131+3232+<style>
3333+ .helpdesk {
3434+ margin: 0 auto;
3535+ }
3636+3737+ .helpdesk-search {
3838+ margin-bottom: 2rem;
3939+ }
4040+4141+ .search-input {
4242+ width: 100%;
4343+ padding: 1rem 1.5rem;
4444+ font-size: 1.125rem;
4545+ border: 2px solid var(--sl-color-gray-5);
4646+ border-radius: 0.5rem;
4747+ background: var(--sl-color-bg);
4848+ color: var(--sl-color-text);
4949+ transition: border-color 0.2s;
5050+ }
5151+5252+ .search-input:focus {
5353+ outline: none;
5454+ border-color: var(--sl-color-accent);
5555+ }
5656+5757+ .helpdesk h2 {
5858+ margin-bottom: 1.5rem;
5959+ }
6060+</style>
+1-2
js/docs/src/content/docs/components/custom_ui.md
···11---
22title: Creating your own player UI
33-description:
44- How to set up your player UI with components from @streamplace/components.
33+description: How to set up your player UI with components from @streamplace/components.
54---
6576# Building a Custom Player UI
+40
js/docs/src/content/docs/developers.mdx
···11+---
22+title: Developers & Self-Hosters
33+description: Build with Streamplace or run your own infrastructure.
44+template: doc
55+---
66+77+import { Card, CardGrid } from "@astrojs/starlight/components";
88+99+## Learn how to deploy, or contribute to Streamplace.
1010+1111+<br />
1212+1313+<CardGrid stagger>
1414+ <Card title="Building an Application" icon="laptop">
1515+ Integrate live video into your project. - [API
1616+ reference](/docs/lex-reference/place-stream-defs) - [Our component
1717+ library](/docs/components/custom_ui/)
1818+ </Card>
1919+2020+{" "}
2121+2222+<Card title="Self-Hosting" icon="seti:config">
2323+ Run your own Streamplace infrastructure. - [Installation
2424+ guide](/docs/guides/installing/installing-streamplace)
2525+</Card>
2626+2727+{" "}
2828+2929+<Card title="Contributing" icon="github">
3030+ Help improve Streamplace. - [Development
3131+ setup](/docs/guides/streamplace-dev-setup) - [Video
3232+ signing](/docs/video-metadata/intro/)
3333+</Card>
3434+3535+ <Card title="Support & Community" icon="information">
3636+ Get help and connect with other developers. - [GitHub
3737+ issues](https://github.com/streamplace/streamplace/issues) - [Discord
3838+ community](https://discord.stream.place)
3939+ </Card>
4040+</CardGrid>
+3-1
js/docs/src/content/docs/features/danmu.md
···33description: Add flying bullet-style chat comments to the player, or your stream
44---
5566-:::note This feature is experimental and may change in future releases. :::
66+:::note
77+This feature is experimental and may change in future releases.
88+:::
79810[Danmu (or Danmaku)](https://en.wikipedia.org/wiki/Danmaku_subtitling) (弹幕,
911"bullet curtain") is a comment style where messages fly across the video
+27
js/docs/src/content/docs/features/embed.md
···11+---
22+title: Embedding your livestream
33+description: How to embed your livestream on your website, blog, etc.
44+---
55+66+Streamplace provides an easy way to embed your livestream on any website or
77+blog.
88+99+You can access the embedded livestream page by putting `/embed` in the URL of
1010+your livestream. For example, if your livestream URL is
1111+`https://stream.place/iame.li`, the embed URL will be
1212+`https://stream.place/embed/iame.li`.
1313+1414+You can use the following HTML snippet to embed your livestream:
1515+1616+```html
1717+<iframe
1818+ src="https://stream.place/embed/your-handle"
1919+ width="560"
2020+ height="315"
2121+ frameborder="0"
2222+ allowfullscreen
2323+></iframe>
2424+```
2525+2626+Alternatively, you can use the share sheet located on your livestream page.
2727+Click the "Share" button, and you'll find the embed code ready to copy.
···11+---
22+title: Multistreaming
33+description: Forward your Streamplace stream to other providers.
44+---
55+66+:::note
77+This guide isn't about setting up Streamplace as an OBS destination. See [OBS Multistreaming to Streamplace](/docs/guides/start-streaming/obs-multistreaming/) for information on that.
88+:::
99+1010+Multistreaming lets you forward your Streamplace stream to multiple platforms at the same time. Instead of streaming only to Streamplace, you can forward your stream to any platform that accepts RTMP input.
1111+1212+## Setting up multistream targets
1313+1414+1. Go to **Settings** > **Streaming** > **Multistream Targets**
1515+2. Click **Create Multistream Target**
1616+3. Enter the RTMP or RTMPS URL from your destination platform
1717+4. Optionally give it a name to identify it later
1818+5. Click **Create**
1919+2020+### Finding your multistream URL
2121+2222+Different platforms will provide their own RTMP URLs. Some common examples:
2323+2424+- **YouTube Live**: Format `rtmp://a.rtmp.youtube.com/live2/your-stream-key`
2525+ - Find your stream key at https://studio.youtube.com/channel/UC/livestreaming (click the copy icon in the top right corner of the 'connect your encoder to go live' box)
2626+- **Twitch**: Format `rtmp://usw20.contribute.live-video.net/app/your-stream-key`
2727+ - You can get a valid RTMPS url at https://help.twitch.tv/s/twitch-ingest-recommendation
2828+ - Find your stream key at https://dashboard.twitch.tv/settings/stream (your 'primary stream key')
2929+3030+:::note
3131+Your stream key should automatically be hidden once you confirm. Make sure you've entered it correctly!
3232+:::
3333+3434+## Managing targets during a stream
3535+3636+When you're live, you can see all your multistream targets on the Live Dashboard with their current status:
3737+3838+- **Green (Active)**: Successfully streaming to this target
3939+- **Yellow (Pending)**: Connecting to this target
4040+- **Red (Error)**: Connection failed; check your URL and credentials
4141+- **Gray (Inactive)**: This target is disabled
4242+4343+You can toggle any target on or off with the switch next to its name. Changes take effect immediately.
4444+4545+## Limits
4646+4747+- **Maximum targets**: 100 total per account
4848+- **Maximum active targets**: 5 simultaneous streams
4949+5050+### Credits
5151+5252+A portion of this documentation was taken from [ndroo.tv](https://bsky.app/profile/ndroo.tv)'s [guide on Streamplace](https://ndroo.tv/streamplace.html#2-configuring-your-account).
+83
js/docs/src/content/docs/features/webhooks.md
···11+---
22+title: Discord Webhooks
33+description: Configure Discord webhooks for livestream announcements and chat
44+sidebar:
55+ order: 30
66+---
77+88+Streamplace supports Discord webhooks for receiving livestream
99+notifications and chat messages. You can create, manage, and configure webhooks
1010+to customize how events are delivered to your Discord channels.
1111+1212+## Webhook Events
1313+1414+You can configure webhooks to listen for specific events. For right now, the
1515+following events are supported:
1616+1717+- `Chat`: Triggered when a chat message is sent.
1818+- `Livestream`: Triggered when a livestream starts.
1919+2020+## Creating a Webhook
2121+2222+To create a webhook, go to the "Settings" page of the Streamplace web app, then
2323+navigate to the "Webhooks" section. Click on "Create Webhook". The following
2424+fields are required:
2525+2626+- Name: Webhook URL. For example,
2727+ `https://discord.com/api/webhooks/{webhook.id}/{webhook.token}`
2828+- Events: Select the events you want to subscribe to (e.g., `Chat Messages`,
2929+ `Livestream Started`). `Livestream Started` is pre-checked by default.
3030+3131+We'd recommend also filling out these optional fields:
3232+3333+- Name: A name for the webhook (e.g., "Discord Livestream Notifications") that
3434+ you can remember.
3535+- Description: A description of what this webhook is for (e.g., "Sends
3636+ livestream start notifications to Discord channel").
3737+- Prefix: A prefix to add to each message sent by this webhook (e.g.,
3838+ "[Streamplace] "). Will apply to both Chat and Livestream events!
3939+- Suffix: A suffix to add to each message sent by this webhook (e.g., "is now
4040+ live!"). Will apply to both Chat and Livestream events!
4141+- Text replacements: A list of text replacements to apply to chat messages sent
4242+ by this webhook. Each replacement consists of a "from" string and a "to"
4343+ string. For example, you could replace all instances of "foo" with "bar".
4444+4545+After filling out the form, click "Create" to save your webhook. You should see
4646+it listed in the "Webhooks" section.
4747+4848+## Updating a Webhook
4949+5050+To update a webhook, go to the "Settings" page of the Streamplace web app, then
5151+navigate to the "Webhooks" section. Find the webhook you want to update and
5252+click on the "pen" icon next to it. This will open the webhook edit form, where
5353+you can modify the fields as needed. After making your changes, click "Update"
5454+to save your changes.
5555+5656+## Deleting a Webhook
5757+5858+To delete a webhook, go to the "Settings" page of the Streamplace web app, then
5959+navigate to the "Webhooks" section. Find the webhook you want to delete and
6060+click on the "trash" icon next to it. A confirmation dialog will appear; click
6161+"Delete" to confirm. The webhook will be removed from the list.
6262+6363+## Recommendations
6464+6565+We'd recommend:
6666+6767+- Creating separate Discord channels for livestream notifications and chat
6868+ messages to keep them organized.
6969+ - If you want to have one webhook for both chat and livestream events, you can
7070+ create multiple webhooks with the same URL but different event subscriptions
7171+ and prefixes/suffixes/replacements.
7272+- Testing your webhook by starting a livestream or sending a chat message to
7373+ ensure that notifications are being sent correctly.
7474+7575+## API Documentation
7676+7777+See these endpoint pages:
7878+7979+- [Create Webhook](/docs/api/operations/placestreamservercreatewebhook)
8080+- [Get Webhook](/docs/api/operations/placestreamservergetwebhook)
8181+- [List Webhooks](/docs/api/operations/placestreamserverlistwebhooks)
8282+- [Update Webhook](/docs/api/operations/placestreamserverupdatewebhook)
8383+- [Delete Webhook](/docs/api/operations/placestreamserverdeletewebhook)
···11----
22-title: Discord Webhooks
33-description: Configure Discord webhooks for livestream announcements and chat
44-sidebar:
55- order: 30
66----
77-88-Streamplace supports Discord webhook integration for receiving livestream
99-notifications and chat messages. You can create, manage, and configure webhooks
1010-to customize how events are delivered to your Discord channels.
1111-1212-## Webhook Events
1313-1414-You can configure webhooks to listen for specific events. For right now, the
1515-following events are supported:
1616-1717-- `Chat`: Triggered when a chat message is sent.
1818-- `Livestream`: Triggered when a livestream starts.
1919-2020-## Creating a Webhook
2121-2222-To create a webhook, go to the "Settings" page of the Streamplace web app, then
2323-navigate to the "Webhooks" section. Click on "Create Webhook". The following
2424-fields are required:
2525-2626-- Name: Webhook URL. For example,
2727- `https://discord.com/api/webhooks/{webhook.id}/{webhook.token}`
2828-- Events: Select the events you want to subscribe to (e.g., `Chat Messages`,
2929- `Livestream Started`). `Livestream Started` is pre-checked by default.
3030-3131-We'd recommend also filling out these optional fields:
3232-3333-- Name: A name for the webhook (e.g., "Discord Livestream Notifications") that
3434- you can remember.
3535-- Description: A description of what this webhook is for (e.g., "Sends
3636- livestream start notifications to Discord channel").
3737-- Prefix: A prefix to add to each message sent by this webhook (e.g.,
3838- "[Streamplace] "). Will apply to both Chat and Livestream events!
3939-- Suffix: A suffix to add to each message sent by this webhook (e.g., "is now
4040- live!"). Will apply to both Chat and Livestream events!
4141-- Text replacements: A list of text replacements to apply to chat messages sent
4242- by this webhook. Each replacement consists of a "from" string and a "to"
4343- string. For example, you could replace all instances of "foo" with "bar".
4444-4545-After filling out the form, click "Create" to save your webhook. You should see
4646-it listed in the "Webhooks" section.
4747-4848-## Updating a Webhook
4949-5050-To update a webhook, go to the "Settings" page of the Streamplace web app, then
5151-navigate to the "Webhooks" section. Find the webhook you want to update and
5252-click on the "pen" icon next to it. This will open the webhook edit form, where
5353-you can modify the fields as needed. After making your changes, click "Update"
5454-to save your changes.
5555-5656-## Deleting a Webhook
5757-5858-To delete a webhook, go to the "Settings" page of the Streamplace web app, then
5959-navigate to the "Webhooks" section. Find the webhook you want to delete and
6060-click on the "trash" icon next to it. A confirmation dialog will appear; click
6161-"Delete" to confirm. The webhook will be removed from the list.
6262-6363-## Recommendations
6464-6565-We'd recommend:
6666-6767-- Creating separate Discord channels for livestream notifications and chat
6868- messages to keep them organized.
6969- - If you want to have one webhook for both chat and livestream events, you can
7070- create multiple webhooks with the same URL but different event subscriptions
7171- and prefixes/suffixes/replacements.
7272-- Testing your webhook by starting a livestream or sending a chat message to
7373- ensure that notifications are being sent correctly.
7474-7575-## API Documentation
7676-7777-See these endpoint pages:
7878-7979-- [Create Webhook](/docs/api/operations/placestreamservercreatewebhook)
8080-- [Get Webhook](/docs/api/operations/placestreamservergetwebhook)
8181-- [List Webhooks](/docs/api/operations/placestreamserverlistwebhooks)
8282-- [Update Webhook](/docs/api/operations/placestreamserverupdatewebhook)
8383-- [Delete Webhook](/docs/api/operations/placestreamserverdeletewebhook)
···11----
22-title: Embedding your livestream
33-description: How to embed your livestream on your website, blog, etc.
44----
55-66-Streamplace provides an easy way to embed your livestream on any website or
77-blog.
88-99-You can access the embedded livestream page by putting `/embed` in the URL of
1010-your livestream. For example, if your livestream URL is
1111-`https://stream.place/iame.li`, the embed URL will be
1212-`https://stream.place/embed/iame.li`.
1313-1414-You can use the following HTML snippet to embed your livestream:
1515-1616-```html
1717-<iframe
1818- src="https://stream.place/embed/your-handle"
1919- width="560"
2020- height="315"
2121- frameborder="0"
2222- allowfullscreen
2323-></iframe>
2424-```
2525-2626-Alternatively, you can use the share sheet located on your livestream page.
2727-Click the "Share" button, and you'll find the embed code ready to copy.
···11---
22-title: OBS Multistreaming with Streamplace
22+title: OBS Multistreaming to Streamplace
33description:
44 Configure OBS for multistreaming to Streamplace and other platforms using the
55 obs-multi-rtmp plugin.
66sidebar:
77 order: 20
88---
99+1010+:::note
1111+This guide is not about the multistreaming feature. Check
1212+[the multistreaming guide](/docs/features/multistreaming) out for more
1313+information.
1414+:::
9151016This guide explains how to configure Open Broadcaster Software (OBS) for
1117simultaneous streaming to Streamplace and other platforms using the
···66666767- Video Encoder: x264/h264 (**must** be an x/h.264 encoder)
6868- Rate Control: `CBR`
6969-- Keyframe Interval: `1s`
6969+- Keyframe Interval: `1s` (or anything less than once every ~7s)
7070 - This is _one keyframe per second_
7171 - In some situations (e.g. 'keyframe interval (**frames**)'), this should be
7272 set to your FPS.
7373- x264 Options: `bframes=0`
7474 - If available, there also may be a 'bframes' checkbox which should **NOT** be
7575 checked
7676+7777+:::caution
7878+These last two options are very important! Your viewers' experience may be choppy or otherwise subpar if you don't have them correct.
7979+:::
76807781### 3. Announce your stream
7882···9094 - [OBS Multistreaming Guide](guides/obs-multistreaming)
919592962. [**Aitum Multistream Plugin**](https://aitum.tv/products/multi)
9797+9898+Alternatively, you can
9999+[multistream through Streamplace itself.](/docs/features/multistreaming)
9310094101## Best Practices
95102
···11+---
22+title: Quick Start
33+description: Get up and streaming on Streamplace quickly.
44+sidebar:
55+ order: 1
66+---
77+88+This guide gets you from zero to streaming. If you get stuck, check out the full [OBS setup guide](/docs/guides/start-streaming/obs).
99+1010+:::tip
1111+You will want to check out our [community guidelines](https://blog.stream.place/3mcqwibo4ks2w) first for guidance on what you can and cannot do on Streamplace.
1212+:::
1313+1414+## So, what is Streamplace?
1515+1616+Streamplace is a video streaming service built on top of the AT Protocol (Authenticated Transfer Protocol), the same protocol Bluesky is built on.
1717+1818+## Step 1: Create your account
1919+2020+1. Go to [stream.place](https://stream.place)
2121+2. Click "Sign in" in the top right.
2222+3. Use your Atmosphere credentials to log in (ex. your Bluesky handle)
2323+ - You'll need to use your actual password here - we're using OAuth so you enter your password on your PDS. We do not receive your password at all.
2424+4. You're done! Your stream profile is live at `stream.place/your-handle`
2525+2626+## Step 2: Get your stream key
2727+2828+1. Click **Live Dashboard** (or go to [stream.place/dashboard](https://stream.place/dashboard))
2929+2. Click **Stream from OBS**
3030+3. Click **Generate Stream Key**
3131+4. Your key is copied to clipboard automatically
3232+3333+Keep this key private. It's like a password, but for your stream.
3434+3535+## Step 3: Configure OBS
3636+3737+Open OBS and go to **Settings → Stream**:
3838+3939+- **Service**: `Custom...`
4040+- **Server**: `rtmps://stream.place:1935/live`
4141+- **Stream Key**: Paste what you copied in Step 2
4242+4343+Then go to **Settings → Output → Streaming**:
4444+4545+- **Video Encoder**: `libx264` (or `NVIDIA NVENC H.264` if you have an NVIDIA GPU)
4646+- **Rate Control**: `CBR`
4747+- **Bitrate**: `6000` Kbps (adjust down if you drop frames)
4848+- **Keyframe Interval**: `1`
4949+- **x264 Options**: `bframes=0`. If there's a 'bframes' option, you'll want to have that at '0' or unchecked.
5050+5151+:::caution
5252+These last two options are very important! Your viewers' experience may be choppy or otherwise subpar if you don't have them correct.
5353+:::
5454+5555+## Step 4: Go live
5656+5757+1. In OBS, click **Start Streaming**
5858+2. Go back to the Live Dashboard at stream.place
5959+3. Fill in your stream title and optionally pick a thumbnail8
6060+4. If needed, turn on content warnings. ("Metadata" tab in Stream Settings)
6161+5. Click **Announce Livestream**
6262+6. Your stream is now live and visible to the world!
6363+6464+## Next steps
6565+6666+- **Customize your chat**: Change your name color in Settings > Account
6767+- **Stream to other platforms too**: Set your Twitch/YouTube URLs in Settings > Multistream Targets to push your stream there automatically. See the [Multistreaming guide](/docs/features/multistreaming) for more information
6868+- **Improve stream quality**: See the [OBS guide](/docs/guides/start-streaming/obs) for encoder settings and troubleshooting
6969+- **Join the Discord!**: If you need any help, or just want to chat, check out our discord at https://discord.stream.place.
7070+7171+### Credits
7272+7373+A portion of this documentation was taken from [ndroo.tv](https://bsky.app/profile/ndroo.tv)'s excellent [guide on Streamplace](https://ndroo.tv/streamplace.html#2-configuring-your-account).
+2-32
js/docs/src/content/docs/index.mdx
···22title: Welcome to Streamplace!
33description: Begin your development journey with the Streamplace documentation.
44template: doc
55-hero:
66- tagline: Solve live video for your project with Streamplace.
77- image:
88- file: ../../assets/cube.png
99- alt: Streamplace logo. A pink 3d box viewed from a top corner.
1010- actions:
1111- - text: Get Started
1212- link: /docs/guides/start-streaming/obs
1313- icon: right-arrow
1414- - text: Visit Streamplace
1515- link: /
1616- icon: external
1717- variant: minimal
185---
1962020-import { Card, CardGrid } from "@astrojs/starlight/components";
2121-2222-## Next Steps
77+import HelpDesk from "../../components/HelpDesk.astro";
2382424-<CardGrid>
2525- <Card title="Read the Docs" icon="open-book">
2626- Learn how to start streaming with
2727- [Streamplace](/docs/guides/start-streaming/obs).
2828- </Card>
2929- <Card title="Install Streamplace" icon="download">
3030- [Run your own Streamplace
3131- node](/docs/guides/installing/installing-streamplace).
3232- </Card>
3333- <Card title="API Reference" icon="document">
3434- Explore the [Lexicon API reference](/docs/lex-reference/place-stream-defs).
3535- </Card>
3636- <Card title="Developer Setup" icon="setting">
3737- Set up your [development environment](/docs/guides/streamplace-dev-setup).
3838- </Card>
3939-</CardGrid>
99+<HelpDesk />
···2828- **Description:** Raw blob data with appropriate content-type
2929- **Schema:**
30303131-_Schema not defined._ **Possible Errors:**
3131+_Schema not defined._
3232+**Possible Errors:**
32333334- `BrandingNotFound`: The requested branding asset does not exist
3435
···13131414**Type:** `record`
15151616-Record indicating a livestream is published and available for replication at a
1717-given address. By convention, the record key is streamer::server
1616+Record indicating a livestream is published and available for replication at a given address. By convention, the record key is streamer::server
18171918**Record Key:** `any`
2019
···13131414**Type:** `record`
15151616-Record created by a Streamplace broadcaster to indicate that they will be
1717-replicating a livestream. NYI
1616+Record created by a Streamplace broadcaster to indicate that they will be replicating a livestream. NYI
18171918**Record Key:** `tid`
2019
···13131414**Type:** `query`
15151616-Find actor suggestions for a prefix search term. Expected use is for
1717-auto-completion during text field entry.
1616+Find actor suggestions for a prefix search term. Expected use is for auto-completion during text field entry.
18171918**Parameters:**
2019
···13131414**Type:** `record`
15151616-Default metadata record for livestream including content warnings, rights, and
1717-distribution policy
1616+Default metadata record for livestream including content warnings, rights, and distribution policy
18171918**Record Key:** `literal:self`
2019
···33333434**Type:** `token`
35353636-All rights reserved to the creator — others cannot use, modify, or share without
3737-explicit authorization.
3636+All rights reserved to the creator — others cannot use, modify, or share without explicit authorization.
38373938---
4039···44434544**Type:** `token`
46454747-Public domain dedication. You waive all copyright and related rights where
4848-possible. Others may copy, modify, distribute, or perform your work for any
4949-purpose without attribution.
4646+Public domain dedication. You waive all copyright and related rights where possible. Others may copy, modify, distribute, or perform your work for any purpose without attribution.
50475148---
5249···56535754**Type:** `token`
58555959-Attribution required. Others may copy, distribute, remix, and build upon your
6060-work, even commercially, if they credit you.
5656+Attribution required. Others may copy, distribute, remix, and build upon your work, even commercially, if they credit you.
61576258---
6359···67636864**Type:** `token`
69657070-Attribution + share-alike. Others may adapt and build upon your work, even
7171-commercially, if they credit you and license their new creations under identical
7272-terms.
6666+Attribution + share-alike. Others may adapt and build upon your work, even commercially, if they credit you and license their new creations under identical terms.
73677468---
7569···79738074**Type:** `token`
81758282-Attribution + non-commercial. Others may adapt and build upon your work for
8383-non-commercial purposes only, and must credit you.
7676+Attribution + non-commercial. Others may adapt and build upon your work for non-commercial purposes only, and must credit you.
84778578---
8679···90839184**Type:** `token`
92859393-Attribution + non-commercial + share-alike. Others may adapt and build upon your
9494-work for non-commercial purposes only, must credit you, and must license their
9595-new creations under identical terms.
8686+Attribution + non-commercial + share-alike. Others may adapt and build upon your work for non-commercial purposes only, must credit you, and must license their new creations under identical terms.
96879788---
9889···1029310394**Type:** `token`
10495105105-Attribution + no derivatives. Others may reuse your work, even commercially, but
106106-it must remain unchanged and you must be credited.
9696+Attribution + no derivatives. Others may reuse your work, even commercially, but it must remain unchanged and you must be credited.
1079710898---
10999···113103114104**Type:** `token`
115105116116-Attribution + non-commercial + no derivatives. Others may download and share
117117-your work with credit, but cannot change it or use it commercially.
106106+Attribution + non-commercial + no derivatives. Others may download and share your work with credit, but cannot change it or use it commercially.
118107119108---
120109
···29293030**Type:** `token`
31313232-The content could be perceived as offensive due to the discussion or display of
3333-death.
3232+The content could be perceived as offensive due to the discussion or display of death.
34333534---
3635···40394140**Type:** `token`
42414343-The content contains a portrayal of the use or abuse of mind altering
4444-substances.
4242+The content contains a portrayal of the use or abuse of mind altering substances.
45434644---
4745···51495250**Type:** `token`
53515454-The content contains violent actions of a fantasy nature, involving human or
5555-non-human characters in situations easily distinguishable from real life.
5252+The content contains violent actions of a fantasy nature, involving human or non-human characters in situations easily distinguishable from real life.
56535754---
5855···62596360**Type:** `token`
64616565-The content contains flashing lights that could be harmful to viewers with
6666-seizure disorders such as photosensitive epilepsy.
6262+The content contains flashing lights that could be harmful to viewers with seizure disorders such as photosensitive epilepsy.
67636864---
6965···93899490**Type:** `token`
95919696-The content contains information that can be used to identify a particular
9797-individual, such as a name, phone number, email address, physical address, or IP
9898-address.
9292+The content contains information that can be used to identify a particular individual, such as a name, phone number, email address, physical address, or IP address.
999310094---
10195···10599106100**Type:** `token`
107101108108-The content could be perceived as offensive due to the discussion or display of
109109-sexuality.
102102+The content could be perceived as offensive due to the discussion or display of sexuality.
110103111104---
112105···116109117110**Type:** `token`
118111119119-The content could be perceived as distressing due to the discussion or display
120120-of suffering or triggering topics, including suicide, eating disorders or self
121121-harm.
112112+The content could be perceived as distressing due to the discussion or display of suffering or triggering topics, including suicide, eating disorders or self harm.
122113123114---
124115···128119129120**Type:** `token`
130121131131-The content could be perceived as offensive due to the discussion or display of
132132-violence.
122122+The content could be perceived as offensive due to the discussion or display of violence.
133123134124---
135125
···13131414**Type:** `procedure`
15151616-Create a block (ban) on behalf of a streamer. Requires 'ban' permission. Creates
1717-an app.bsky.graph.block record in the streamer's repository.
1616+Create a block (ban) on behalf of a streamer. Requires 'ban' permission. Creates an app.bsky.graph.block record in the streamer's repository.
18171918**Parameters:** _(None defined)_
2019···4645**Possible Errors:**
47464847- `Unauthorized`: The request lacks valid authentication credentials.
4949-- `Forbidden`: The caller does not have permission to create blocks for this
5050- streamer.
5151-- `SessionNotFound`: The streamer's OAuth session could not be found or is
5252- invalid.
4848+- `Forbidden`: The caller does not have permission to create blocks for this streamer.
4949+- `SessionNotFound`: The streamer's OAuth session could not be found or is invalid.
53505451---
5552
···13131414**Type:** `procedure`
15151616-Create a gate (hide message) on behalf of a streamer. Requires 'hide'
1717-permission. Creates a place.stream.chat.gate record in the streamer's
1818-repository.
1616+Create a gate (hide message) on behalf of a streamer. Requires 'hide' permission. Creates a place.stream.chat.gate record in the streamer's repository.
19172018**Parameters:** _(None defined)_
2119···4644**Possible Errors:**
47454846- `Unauthorized`: The request lacks valid authentication credentials.
4949-- `Forbidden`: The caller does not have permission to hide messages for this
5050- streamer.
5151-- `SessionNotFound`: The streamer's OAuth session could not be found or is
5252- invalid.
4747+- `Forbidden`: The caller does not have permission to hide messages for this streamer.
4848+- `SessionNotFound`: The streamer's OAuth session could not be found or is invalid.
53495450---
5551
···13131414**Type:** `procedure`
15151616-Delete a block (unban) on behalf of a streamer. Requires 'ban' permission.
1717-Deletes an app.bsky.graph.block record from the streamer's repository.
1616+Delete a block (unban) on behalf of a streamer. Requires 'ban' permission. Deletes an app.bsky.graph.block record from the streamer's repository.
18171918**Parameters:** _(None defined)_
2019···37363837**Schema Type:** `object`
39384040-_(No properties defined)_ **Possible Errors:**
3939+_(No properties defined)_
4040+**Possible Errors:**
41414242- `Unauthorized`: The request lacks valid authentication credentials.
4343-- `Forbidden`: The caller does not have permission to delete blocks for this
4444- streamer.
4545-- `SessionNotFound`: The streamer's OAuth session could not be found or is
4646- invalid.
4343+- `Forbidden`: The caller does not have permission to delete blocks for this streamer.
4444+- `SessionNotFound`: The streamer's OAuth session could not be found or is invalid.
47454846---
4947
···13131414**Type:** `procedure`
15151616-Delete a gate (unhide message) on behalf of a streamer. Requires 'hide'
1717-permission. Deletes a place.stream.chat.gate record from the streamer's
1818-repository.
1616+Delete a gate (unhide message) on behalf of a streamer. Requires 'hide' permission. Deletes a place.stream.chat.gate record from the streamer's repository.
19172018**Parameters:** _(None defined)_
2119···38363937**Schema Type:** `object`
40384141-_(No properties defined)_ **Possible Errors:**
3939+_(No properties defined)_
4040+**Possible Errors:**
42414342- `Unauthorized`: The request lacks valid authentication credentials.
4444-- `Forbidden`: The caller does not have permission to unhide messages for this
4545- streamer.
4646-- `SessionNotFound`: The streamer's OAuth session could not be found or is
4747- invalid.
4343+- `Forbidden`: The caller does not have permission to unhide messages for this streamer.
4444+- `SessionNotFound`: The streamer's OAuth session could not be found or is invalid.
48454946---
5047
···13131414**Type:** `procedure`
15151616-Update livestream metadata on behalf of a streamer. Requires 'livestream.manage'
1717-permission. Updates a place.stream.livestream record in the streamer's
1818-repository.
1616+Update livestream metadata on behalf of a streamer. Requires 'livestream.manage' permission. Updates a place.stream.livestream record in the streamer's repository.
19172018**Parameters:** _(None defined)_
2119···4745**Possible Errors:**
48464947- `Unauthorized`: The request lacks valid authentication credentials.
5050-- `Forbidden`: The caller does not have permission to update livestream metadata
5151- for this streamer.
5252-- `SessionNotFound`: The streamer's OAuth session could not be found or is
5353- invalid.
4848+- `Forbidden`: The caller does not have permission to update livestream metadata for this streamer.
4949+- `SessionNotFound`: The streamer's OAuth session could not be found or is invalid.
5450- `RecordNotFound`: The specified livestream record does not exist.
55515652---
···5656 Build *BuildFlags
5757 DataDir string
5858 DBURL string
5959+ LocalDBURL string
5960 EthAccountAddr string
6061 EthKeystorePath string
6162 EthPassword string
···242243 cli.StringSliceFlag(fs, &cli.AdminDIDs, "admin-dids", []string{}, "comma-separated list of DIDs that are authorized to modify branding and other admin operations")
243244 cli.StringSliceFlag(fs, &cli.Syndicate, "syndicate", []string{}, "list of DIDs that we should rebroadcast ('*' for everybody)")
244245 fs.BoolVar(&cli.PlayerTelemetry, "player-telemetry", true, "enable player telemetry")
246246+ fs.StringVar(&cli.LocalDBURL, "local-db-url", "sqlite://$SP_DATA_DIR/localdb.sqlite", "URL of the local database to use for storing local data")
247247+ cli.dataDirFlags = append(cli.dataDirFlags, &cli.LocalDBURL)
245248246249 fs.Bool("external-signing", true, "DEPRECATED, does nothing.")
247250 fs.Bool("insecure", false, "DEPRECATED, does nothing.")