Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: features and fixes in increment 2 #17

Closed
wants to merge 63 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
9a83fc3
feat: add management lock
Saelmala Sep 10, 2024
e210ab6
fix: build error
Saelmala Sep 10, 2024
d67930e
fix: remove left-over file, has been renamed
Saelmala Sep 10, 2024
fa006bf
feat: support media and html sources in prod and web sockets
Saelmala Aug 23, 2024
b9f4c4c
WIP! feat: add media & html websocket connections
bwallberg Aug 26, 2024
d1f6cbf
feat: support to add media player and html sources
Saelmala Sep 3, 2024
8b9d4ae
fix: fix drag and drop and lint
Saelmala Sep 4, 2024
03b6a7d
WIP! feat: add media & html websocket connections
bwallberg Aug 26, 2024
ca1f8e6
feat: support to add media player and html sources
Saelmala Sep 3, 2024
ca856ef
fix: fix drag and drop and lint
Saelmala Sep 4, 2024
6b5ee11
feat: add additional filtering
Saelmala Aug 23, 2024
474d203
fix: handle active + source filter, reduce code
Saelmala Aug 23, 2024
77ba4e1
fix: linting
Saelmala Aug 23, 2024
aaf3069
fix: add ingest type to database
Saelmala Aug 26, 2024
93f9048
feat: first commit of source-delete, with basic styling and fetches
malmen237 Aug 28, 2024
0acd37a
feat: added creation-date and function to set correct status when get…
malmen237 Aug 30, 2024
9d19b68
feat: updated server-fetch to be put, not possible to delete
malmen237 Aug 30, 2024
ae74ea9
feat: moved logic out of component to inventory-page and added purge-…
malmen237 Aug 30, 2024
ebb2d20
fix: simplified the delete-source-hook
malmen237 Aug 30, 2024
89d6ec8
fix: rebase to main
malmen237 Sep 5, 2024
f3ecb17
fix: removed created-at and used last-connected instead
malmen237 Sep 5, 2024
88ff051
fix: added better error-handling and made more logical naming of code
malmen237 Sep 5, 2024
824d700
fix: corrected misspelling
malmen237 Sep 5, 2024
0389ac5
WIP! feat: add media & html websocket connections
bwallberg Aug 26, 2024
1f579c5
fix: able to start prod w wevsocket sources
malmen237 Sep 11, 2024
0f2d040
fix: solved errors and conflicts
malmen237 Sep 11, 2024
13772e4
fix: added missing types
malmen237 Sep 11, 2024
bcdb35b
fix: lint error
malmen237 Sep 11, 2024
c60a478
fix: solved conflicts and problems with 'media-html-inputs'-branch
malmen237 Sep 12, 2024
230837f
fix: updated code, with dnd not working
malmen237 Sep 12, 2024
975bebb
fix: orders dnd correct when starting production
malmen237 Sep 12, 2024
f9fc4af
fix: add back previous functionality and empty slot card
Saelmala Sep 13, 2024
fd63506
fix: can remove html/mediaplayer during production
Saelmala Sep 13, 2024
e373e58
Feat/thumbnail fetch (#14)
LucasMaupin Sep 16, 2024
1a57886
Feat/thumbnail fetch (#14)
LucasMaupin Sep 16, 2024
5353712
feat: add management lock
Saelmala Sep 10, 2024
34f5d5e
fix: use global context instead of state
Saelmala Sep 16, 2024
e5e899d
fix: remove duplicates
Saelmala Sep 16, 2024
09002de
Merge branch 'main' into feat-add-management-lock
Saelmala Sep 16, 2024
15f2787
fix: errors after conflict solving
Saelmala Sep 17, 2024
bb9a855
fix: build error
Saelmala Sep 17, 2024
d0d4e2a
fix: remove leftover file, unused import
Saelmala Sep 17, 2024
abf5bc9
fix: delete source doesn't need to be locked
Saelmala Sep 17, 2024
ab1c93a
fix: use correct input slot
Saelmala Sep 17, 2024
4575dbc
fix: clean up input_slot definition
Saelmala Sep 17, 2024
ff5eb34
fix: update lock
Saelmala Sep 17, 2024
34a0421
Merge pull request #13 from Eyevinn/feat-add-management-lock
Saelmala Sep 17, 2024
a093a3b
fix: bug-fix black screen multiview
Saelmala Sep 18, 2024
2ece8ea
fix: move websocket reset and play/load
Saelmala Sep 18, 2024
015fcc5
fix: disable select if no selected config
Saelmala Sep 19, 2024
96e6907
Merge branch 'main' into fix/start-prod-w-websocket
Saelmala Sep 19, 2024
c669245
Feat/specify multiview layout when doing production-config(#16)
malmen237 Sep 19, 2024
0a0fb25
fix: bug-solve and addressed feedback
Saelmala Sep 20, 2024
e49f5ba
fix: test fail
Saelmala Sep 20, 2024
62ea4b4
fix: build fail
Saelmala Sep 20, 2024
963f016
fix: remove non-null assertor
Saelmala Sep 20, 2024
81831c4
fix: solve lock bug
Saelmala Sep 20, 2024
f0f99c5
Merge pull request #18 from Eyevinn/fix-lock-bug-solve
Saelmala Sep 20, 2024
6247316
fix: delete unused file
Saelmala Sep 23, 2024
07931c9
fix: code cleanup
Saelmala Sep 23, 2024
a77e252
Merge branch 'main' into fix/start-prod-w-websocket
Saelmala Sep 23, 2024
042b407
Merge pull request #15 from Eyevinn/fix/start-prod-w-websocket
Saelmala Sep 23, 2024
ba8873e
chore: merge remote-tracking branch 'upstream/main'
birme Sep 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ MONGODB_URI=${MONGODB_URI:-mongodb://api:password@localhost:27017/live-gui}
# Ateliere Live System Controlleer
LIVE_URL=${LIVE_URL:-https://localhost:8080}
LIVE_CREDENTIALS=${LIVE_CREDENTIALS:-admin:admin}
CONTROL_PANEL_WS==${}
# This ENV variable disables SSL Verification, use if the above LIVE_URL doesn't have a proper certificate
NODE_TLS_REJECT_UNAUTHORIZED=${NODE_TLS_REJECT_UNAUTHORIZED:-1}

Expand All @@ -14,3 +15,6 @@ BCRYPT_SALT_ROUNDS=${BCRYPT_SALT_ROUNDS:-10}

# i18n
UI_LANG=${UI_LANG:-en}

# Mediaplayer - path on the system controller
MEDIAPLAYER_PLACEHOLDER=/media/media_placeholder.mp4
32 changes: 31 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"pretty:format": "prettier --write .",
"typecheck": "tsc --noEmit -p tsconfig.json",
"lint": "next lint",
"dev": "./update_gui_version.sh && next dev",
"dev": "next dev",
"build": "next build",
"start": "next start",
"version:rc": "npm version prerelease --preid=rc",
Expand All @@ -32,6 +32,7 @@
"@sinclair/typebox": "^0.25.24",
"@tabler/icons": "^2.22.0",
"@tabler/icons-react": "^2.20.0",
"@types/ws": "^8.5.12",
"bcrypt": "^5.1.0",
"cron": "^2.3.1",
"date-fns": "^2.30.0",
Expand All @@ -48,7 +49,8 @@
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"tailwind-merge": "^1.13.2",
"uuid": "^9.0.0"
"uuid": "^9.0.0",
"ws": "^8.18.0"
},
"devDependencies": {
"@commitlint/cli": "^17.4.2",
Expand Down
4 changes: 3 additions & 1 deletion src/api/ateliereLive/ingest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export async function getSourceThumbnail(
process.env.LIVE_URL
),
{
next: { tags: ['image'] },
method: 'POST',
body: JSON.stringify({
encoder: 'auto',
Expand All @@ -114,7 +115,8 @@ export async function getSourceThumbnail(
width
}),
headers: {
authorization: getAuthorizationHeader()
authorization: getAuthorizationHeader(),
cache: 'no-store'
}
}
);
Expand Down
7 changes: 3 additions & 4 deletions src/api/ateliereLive/pipelines/multiviews/multiviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,12 @@ export async function createMultiviewForPipeline(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
productionSettings.pipelines[multiviewIndex].pipeline_id!;
const sources = await getSourcesByIds(
sourceRefs.map((ref) => ref._id.toString())
sourceRefs.map((ref) => (ref._id ? ref._id.toString() : ''))
);
const sourceRefsWithLabels = sourceRefs.map((ref) => {
const refId = ref._id ? ref._id.toString() : '';
if (!ref.label) {
const source = sources.find(
(source) => source._id.toString() === ref._id.toString()
);
const source = sources.find((source) => source._id.toString() === refId);
ref.label = source?.name || '';
}
return ref;
Expand Down
34 changes: 20 additions & 14 deletions src/api/ateliereLive/pipelines/streams/streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export async function createStream(
return pipeline.uuid;
})
);

const ingestUuid = await getUuidFromIngestName(
source.ingest_name,
false
Expand All @@ -79,13 +80,15 @@ export async function createStream(
source.ingest_source_name,
false
);

const audioMapping =
source.audio_stream.audio_mapping &&
source.audio_stream.audio_mapping.length > 0
? source.audio_stream.audio_mapping
: [[0, 1]];

await initDedicatedPorts();

for (const pipeline of production_settings.pipelines) {
const availablePorts = getAvailablePortsForIngest(
source.ingest_name,
Expand All @@ -101,28 +104,29 @@ export async function createStream(
Log().info(
`Allocated port ${availablePort} on '${source.ingest_name}' for ${source.ingest_source_name}`
);

const stream: PipelineStreamSettings = {
ingest_id: ingestUuid,
source_id: sourceId,
pipeline_id: pipeline.pipeline_id!,
input_slot: input_slot,
alignment_ms: pipeline.alignment_ms,
audio_format: pipeline.audio_format,
audio_sampling_frequency: pipeline.audio_sampling_frequency,
bit_depth: pipeline.bit_depth,
convert_color_range: pipeline.convert_color_range,
encoder: pipeline.encoder,
encoder_device: pipeline.encoder_device,
format: pipeline.format,
max_network_latency_ms: pipeline.max_network_latency_ms,
width: pipeline.width,
height: pipeline.height,
frame_rate_d: pipeline.frame_rate_d,
frame_rate_n: pipeline.frame_rate_n,
format: pipeline.format,
encoder: pipeline.encoder,
encoder_device: pipeline.encoder_device,
gop_length: pipeline.gop_length,
height: pipeline.height,
max_network_latency_ms: pipeline.max_network_latency_ms,
pic_mode: pipeline.pic_mode,
speed_quality_balance: pipeline.speed_quality_balance,
video_kilobit_rate: pipeline.video_kilobit_rate,
width: pipeline.width,
ingest_id: ingestUuid,
source_id: sourceId,
input_slot,
bit_depth: pipeline.bit_depth,
speed_quality_balance: pipeline.speed_quality_balance,
convert_color_range: pipeline.convert_color_range,
audio_sampling_frequency: pipeline.audio_sampling_frequency,
audio_format: pipeline.audio_format,
audio_mapping: JSON.stringify(audioMapping),
interfaces: [
{
Expand All @@ -131,6 +135,7 @@ export async function createStream(
}
]
};

try {
Log().info(
`Connecting '${source.ingest_name}/${ingestUuid}}:${source.ingest_source_name}' to '${pipeline.pipeline_name}/${pipeline.pipeline_id}'`
Expand All @@ -147,6 +152,7 @@ export async function createStream(
Log().info(
`Stream '${result.stream_uuid}' from '${source.ingest_name}/${ingestUuid}' to '${pipeline.pipeline_name}/${pipeline.pipeline_id}' connected`
);

sourceToPipelineStreams.push({
source_id: source._id.toString(),
stream_uuid: result.stream_uuid,
Expand Down
40 changes: 40 additions & 0 deletions src/api/ateliereLive/websocket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import WebSocket from 'ws';

function createWebSocket(): Promise<WebSocket> {
return new Promise((resolve, reject) => {
const ws = new WebSocket(`ws://${process.env.CONTROL_PANEL_WS}`);
ws.on('error', reject);
ws.on('open', () => {
// const send = ws.send.bind(ws);
// ws.send = (message) => {
// console.debug(`[websocket] sending message: ${message}`);
// send(message);
// };
resolve(ws);
});
});
}

export async function createControlPanelWebSocket() {
const ws = await createWebSocket();
return {
createHtml: (input: number) => {
ws.send(`html create ${input} 1920 1080`);
},
createMediaplayer: (input: number) => {
ws.send(`media create ${input} ${process.env.MEDIAPLAYER_PLACEHOLDER}`);
},
closeHtml: (input: number) => {
ws.send(`html close ${input}`);
ws.send('html reset');
},
closeMediaplayer: (input: number) => {
ws.send(`media close ${input}`);
ws.send('media reset');
},
close: () =>
setTimeout(() => {
ws.close();
}, 1000)
};
}
11 changes: 11 additions & 0 deletions src/api/manager/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export async function getMultiviewPresets(): Promise<MultiviewPreset[]> {
const db = await getDatabase();
return await db.collection<MultiviewPreset>('multiviews').find({}).toArray();
}

export async function getMultiviewPreset(
id: string
): Promise<WithId<MultiviewPreset>> {
Expand All @@ -26,6 +27,16 @@ export async function getMultiviewPreset(
.collection<MultiviewPreset>('multiviews')
.findOne({ _id: new ObjectId(id) })) as WithId<MultiviewPreset>;
}

export async function putMultiviewPreset(
newMultiviewPreset: MultiviewPreset
): Promise<void> {
const db = await getDatabase();
await db
.collection('multiviews')
.insertOne({ ...newMultiviewPreset, _id: new ObjectId() });
}

export async function putPreset(
id: string,
preset: PresetWithId
Expand Down
27 changes: 25 additions & 2 deletions src/api/manager/productions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,44 @@ export async function setProductionsIsActiveFalse(): Promise<
export async function putProduction(
id: string,
production: Production
): Promise<void> {
): Promise<Production> {
const db = await getDatabase();
const newSourceId = new ObjectId().toString();

const sources = production.sources
? production.sources.flatMap((singleSource) => {
return singleSource._id
? singleSource
: {
_id: newSourceId,
type: singleSource.type,
label: singleSource.label,
input_slot: singleSource.input_slot
};
})
: [];

await db.collection('productions').findOneAndReplace(
{ _id: new ObjectId(id) },
{
name: production.name,
isActive: production.isActive,
sources: production.sources,
sources: sources,
production_settings: production.production_settings
}
);

if (!production.isActive) {
deleteMonitoring(db, id);
}

return {
_id: new ObjectId(id).toString(),
name: production.name,
isActive: production.isActive,
sources: sources,
production_settings: production.production_settings
};
}

export async function postProduction(data: Production): Promise<ObjectId> {
Expand Down
Loading
Loading