Creating your own player UI
Building a Custom Player UI
Section titled “Building a Custom Player UI”This guide will walk you through the process of creating your own custom player
UI for Streamplace. We’ll use the existing MobileUi component as a reference
to understand how to leverage the available hooks and components.
Core Concepts
Section titled “Core Concepts”The mobile UI is built using React Native and relies on a set of custom hooks to
manage state and interactions related to the livestream. By composing these
hooks and the UI components from @streamplace/components, you can build a
unique viewing and streaming experience.
- React Hooks: State management and logic are encapsulated in hooks (e.g.,
useLivestreamInfo,usePlayerDimensions). This keeps the UI component clean and focused on rendering. - Component Library: A shared component and UI library
(
@streamplace/components) provides ready-to-use UI elements likePlayerUI,Toast, andView. - Styling: A theme-based styling system (
atoms) is used for consistency.
Reference Implementation
Section titled “Reference Implementation”Let’s break down the default MobileUi component to understand its structure.
import { useNavigation } from "@react-navigation/native";import { atoms, PlayerUI, Text, Toast, useAvatars, useCameraToggle, useKeyboardSlide, useLivestreamInfo, usePlayerDimensions, useSegmentTiming as useSegmentMetrics, View,} from "@streamplace/components";import { ChevronLeft, SwitchCamera } from "lucide-react-native";import { useEffect } from "react";import { Image, Pressable } from "react-native";// Ready-to-use chat component is not available yetimport { ChatPanel } from "./chat";
const { borders, colors, gap, h, layout, position, w } = atoms;
export function MobileUi() { // 1. Hooks for State and Logic const navigation = useNavigation(); const { ingest, profile, title, setTitle, showCountdown, setShowCountdown, recordSubmitted, setRecordSubmitted, ingestStarting, setIngestStarting, connectionQuality, toggleGoLive, } = useLivestreamInfo(); const { width, height, isPlayerRatioGreater } = usePlayerDimensions(); const { slideKeyboard } = useKeyboardSlide(); const { segmentDeltas, mean, range } = useSegmentMetrics(); const { doSetIngestCamera } = useCameraToggle(); const avatars = useAvatars(profile?.did ? [profile?.did] : []);
// 2. Effects and Derived State useEffect(() => { return () => { if (ingestStarting) { setIngestStarting(false); } }; }, [ingestStarting, setIngestStarting]);
const isSelfAndNotLive = ingest === "new"; const isLive = ingest !== null && ingest !== "new";
// 3. JSX for Rendering return ( <> {/* Top Bar: Navigation, Profile, and Camera Switch */} <View style={[layout.position.absolute, h.percent[100], w.percent[100]]}> {/* ... */} </View>
{/* Metrics Panel */} {isLive && ( <View> <PlayerUI.MetricsPanel connectionQuality={connectionQuality} showMetrics={isLive || isSelfAndNotLive} segmentDeltas={segmentDeltas} mean={mean || 999} range={range || 999} /> </View> )}
{/* Input Panel (for streamer) or Chat Panel (for viewer, or streamer when live) */} {isSelfAndNotLive ? ( <PlayerUI.InputPanel title={title} setTitle={setTitle} ingestStarting={ingestStarting} toggleGoLive={toggleGoLive} slideKeyboard={slideKeyboard} /> ) : ( <ChatPanel isPlayerRatioGreater={isPlayerRatioGreater} slideKeyboard={slideKeyboard} /> )}
{/* Overlays and Toasts */} <PlayerUI.CountdownOverlay visible={showCountdown} width={width} height={height} startFrom={3} onDone={() => setShowCountdown(false)} /> <Toast open={recordSubmitted} onOpenChange={setRecordSubmitted} title="You're live!" description="We're notifying your followers that you just went live." duration={5} /> </> );}Creating Your Own UI
Section titled “Creating Your Own UI”1. Set Up the File
Section titled “1. Set Up the File”Create a new file for your custom UI component, for example, MyCustomUi.tsx,
inside streamplace/js/app/components/mobile/.
2. Import Necessary Hooks and Components
Section titled “2. Import Necessary Hooks and Components”Start by importing the tools you’ll need. The more important ones are:
useLivestreamInfo: Provides all core data and actions for the stream (e.g.,ingeststatus,profileinfo,toggleGoLivefunction).usePlayerDimensions: Gives you thewidthandheightof the video player area.@streamplace/components: Our source for pre-built hooks, UI elements (PlayerUI,View,Text, etc.) and stylingatoms.react-native: For basic components likePressableandImage.
