mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-21 09:09:22 +00:00
Manual stream switching is working.
This commit is contained in:
parent
059254dcd8
commit
f6905f26cd
2 changed files with 80 additions and 2 deletions
|
|
@ -1238,4 +1238,18 @@ export default class API {
|
|||
errorNotification(`Failed to delete recording ${id}`, e);
|
||||
}
|
||||
}
|
||||
|
||||
static async switchStream(channelId, streamId) {
|
||||
try {
|
||||
const response = await request(`${host}/proxy/ts/next_stream/${channelId}`, {
|
||||
method: 'POST',
|
||||
body: { stream_id: streamId },
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
errorNotification('Failed to switch stream', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
Title,
|
||||
Tooltip,
|
||||
useMantineTheme,
|
||||
Select,
|
||||
} from '@mantine/core';
|
||||
import { MantineReactTable, useMantineReactTable } from 'mantine-react-table';
|
||||
import { TableHelper } from '../helpers';
|
||||
|
|
@ -34,6 +35,7 @@ import relativeTime from 'dayjs/plugin/relativeTime';
|
|||
import { Sparkline } from '@mantine/charts';
|
||||
import useStreamProfilesStore from '../store/streamProfiles';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
|
||||
dayjs.extend(duration);
|
||||
dayjs.extend(relativeTime);
|
||||
|
|
@ -75,14 +77,55 @@ const getStartDate = (uptime) => {
|
|||
};
|
||||
|
||||
// Create a separate component for each channel card to properly handle the hook
|
||||
const ChannelCard = ({ channel, clients, stopClient, stopChannel, logos }) => {
|
||||
const ChannelCard = ({ channel, clients, stopClient, stopChannel, logos, channelsByUUID }) => {
|
||||
const location = useLocation();
|
||||
const [availableStreams, setAvailableStreams] = useState([]);
|
||||
const [isLoadingStreams, setIsLoadingStreams] = useState(false);
|
||||
|
||||
// Safety check - if channel doesn't have required data, don't render
|
||||
if (!channel || !channel.channel_id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fetch available streams for this channel
|
||||
useEffect(() => {
|
||||
const fetchStreams = async () => {
|
||||
setIsLoadingStreams(true);
|
||||
try {
|
||||
// Get channel ID from UUID
|
||||
const channelId = channelsByUUID[channel.channel_id];
|
||||
if (channelId) {
|
||||
const streamData = await API.getChannelStreams(channelId);
|
||||
setAvailableStreams(streamData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching streams:", error);
|
||||
} finally {
|
||||
setIsLoadingStreams(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchStreams();
|
||||
}, [channel.channel_id, channelsByUUID]);
|
||||
|
||||
// Handle stream switching
|
||||
const handleStreamChange = async (streamId) => {
|
||||
try {
|
||||
await API.switchStream(channel.channel_id, streamId);
|
||||
notifications.show({
|
||||
title: 'Stream switching',
|
||||
message: `Switching stream for ${channel.name}`,
|
||||
color: 'blue.5',
|
||||
});
|
||||
} catch (error) {
|
||||
notifications.show({
|
||||
title: 'Error switching stream',
|
||||
message: error.toString(),
|
||||
color: 'red.5',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const clientsColumns = useMemo(
|
||||
() => [
|
||||
{
|
||||
|
|
@ -167,6 +210,12 @@ const ChannelCard = ({ channel, clients, stopClient, stopChannel, logos }) => {
|
|||
const avgBitrate = channel.avg_bitrate || '0 Kbps';
|
||||
const streamProfileName = channel.stream_profile?.name || 'Unknown Profile';
|
||||
|
||||
// Create select options for available streams
|
||||
const streamOptions = availableStreams.map(stream => ({
|
||||
value: stream.id.toString(),
|
||||
label: stream.name || `Stream #${stream.id}`
|
||||
}));
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={channel.channel_id}
|
||||
|
|
@ -217,6 +266,20 @@ const ChannelCard = ({ channel, clients, stopClient, stopChannel, logos }) => {
|
|||
</Group>
|
||||
</Flex>
|
||||
|
||||
{/* Add stream selection dropdown */}
|
||||
{availableStreams.length > 0 && (
|
||||
<Select
|
||||
size="xs"
|
||||
label="Active Stream"
|
||||
placeholder={isLoadingStreams ? "Loading streams..." : "Select stream"}
|
||||
data={streamOptions}
|
||||
value={channel.stream_id ? channel.stream_id.toString() : null}
|
||||
onChange={handleStreamChange}
|
||||
disabled={isLoadingStreams}
|
||||
style={{ marginTop: '8px' }}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Group justify="space-between">
|
||||
<Group gap={4}>
|
||||
<Gauge style={{ paddingRight: 5 }} size="22" />
|
||||
|
|
@ -301,7 +364,7 @@ const ChannelsPage = () => {
|
|||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: true, // 12-hour format with AM/PM
|
||||
}); // This will give you a string like: "2025-03-14T14:00:00.000Z"
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -439,6 +502,7 @@ const ChannelsPage = () => {
|
|||
stopClient={stopClient}
|
||||
stopChannel={stopChannel}
|
||||
logos={logos} // Pass logos to the component
|
||||
channelsByUUID={channelsByUUID} // Pass channelsByUUID to fix the error
|
||||
/>
|
||||
))
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue