import React, { useState, useCallback } from "react"; import { useStreamCrafterContext } from "../context/StreamCrafterContext"; import { useStudioTranslate } from "../context/StudioI18nContext"; import { VolumeSlider } from "./VolumeSlider"; import type { MediaSource } from "@livepeer-frameworks/streamcrafter-core"; function cn(...classes: (string | undefined | false)[]): string { return classes.filter(Boolean).join(" "); } const CameraIcon = ({ size = 16 }: { size?: number }) => ( ); const MonitorIcon = ({ size = 16 }: { size?: number }) => ( ); const MicIcon = ({ size = 14, muted = false }: { size?: number; muted?: boolean }) => muted ? ( ) : ( ); const XIcon = ({ size = 14 }: { size?: number }) => ( ); const VideoIcon = ({ size = 14, active = false }: { size?: number; active?: boolean }) => ( ); const ChevronsRightIcon = ({ size = 14 }: { size?: number }) => ( ); const ChevronsLeftIcon = ({ size = 14 }: { size?: number }) => ( ); export interface StudioMixerProps { /** Override sources (falls back to context) */ sources?: MediaSource[]; /** Whether compositor mode is enabled */ enableCompositor?: boolean; /** Initially collapsed */ defaultCollapsed?: boolean; } export const StudioMixer: React.FC = ({ sources: propSources, enableCompositor = true, defaultCollapsed = false, }) => { const ctx = useStreamCrafterContext(); const t = useStudioTranslate(); const [showSources, setShowSources] = useState(!defaultCollapsed); const sources = propSources ?? ctx.sources; const toggleMute = useCallback( (sourceId: string, currentMuted: boolean) => ctx.setSourceMuted(sourceId, !currentMuted), [ctx] ); if (sources.length === 0) return null; return (
setShowSources(!showSources)} title={showSources ? t("collapseMixer") : t("expandMixer")} > {t("mixer")} ({sources.length}) {showSources ? : }
{showSources && (
{sources.map((source: MediaSource) => (
{source.type === "camera" && } {source.type === "screen" && }
{source.label} {source.primaryVideo && !enableCompositor && ( {t("primary")} )}
{source.type}
{source.stream.getVideoTracks().length > 0 && !enableCompositor && ( )} {Math.round(source.volume * 100)}% ctx.setSourceVolume(source.id, vol)} compact={true} />
))}
)}
); };