-
AAC URL (Only Audio)
-
-
-
- {profileData?.addresses?.aac ?? "No AAC URL available"}
-
+
+
HLS URL
+
[6s~12s latency]
-
-
-
HLS URL
+
This protocol is highly compatible with a multitude of devices and services. Recommended for general use.
@@ -318,7 +381,12 @@ export default (props) => {
-
FLV URL
+
+
FLV URL
+
[2s~5s latency]
+
+
+
This protocol operates at better latency and quality than HLS, but is less compatible for most devices.
@@ -326,6 +394,21 @@ export default (props) => {
+
+
+
+
MP3 URL (Only Audio)
+
[2s ~ 5s latency]
+
+
+
This protocol will only return an audio file. The maximum quality compatible with this codec will be used (320Kbps, 48KHz)
+
+
+
+ {profileData?.addresses?.mp3 ?? "No MP3 URL available"}
+
+
+
diff --git a/packages/app/src/pages/tv/tabs/livestreamControlPanel/index.less b/packages/app/src/pages/tv/tabs/livestreamControlPanel/index.less
index 6a5bc645..702652e6 100755
--- a/packages/app/src/pages/tv/tabs/livestreamControlPanel/index.less
+++ b/packages/app/src/pages/tv/tabs/livestreamControlPanel/index.less
@@ -11,6 +11,10 @@
gap: 20px;
+ &[disabled]{
+ pointer-events: none;
+ }
+
.inline_field {
background-color: var(--background-color-accent);
@@ -133,13 +137,48 @@
width: 100%;
+ gap: 7px;
+
.title {
display: inline-flex;
flex-direction: row;
+ align-items: center;
justify-content: space-between;
+ svg {
+ font-size: 1rem;
+ margin: 0;
+ }
+
+ p {
+ margin: 0;
+ }
+
width: 100%;
+ margin: 0;
+ }
+
+ .label {
+ display: inline-flex;
+ flex-direction: row;
+
+ align-items: center;
+
+ gap: 8px;
+
+ svg {
+ font-size: 1.3rem;
+ margin: 0;
+ }
+
+ width: 100%;
+ margin: 0;
+ }
+
+ .description {
+ font-size: 0.8rem;
+ margin: 0;
}
}
}
diff --git a/packages/server/src/controllers/StreamingController/endpoints/getProfilesVisibility.js b/packages/server/src/controllers/StreamingController/endpoints/getProfilesVisibility.js
new file mode 100644
index 00000000..5d968b39
--- /dev/null
+++ b/packages/server/src/controllers/StreamingController/endpoints/getProfilesVisibility.js
@@ -0,0 +1,24 @@
+import { StreamingProfile } from "@shared-classes/DbModels"
+
+export default {
+ method: "GET",
+ route: "/profile/visibility",
+ middlewares: ["withAuthentication"],
+ fn: async (req, res) => {
+ let { ids } = req.query
+
+ if (typeof ids === "string") {
+ ids = [ids]
+ }
+
+ let visibilities = await StreamingProfile.find({
+ _id: { $in: ids }
+ })
+
+ visibilities = visibilities.map((visibility) => {
+ return [visibility._id.toString(), visibility.options.private]
+ })
+
+ return res.json(visibilities)
+ }
+}
\ No newline at end of file
diff --git a/packages/server/src/controllers/StreamingController/endpoints/getStreamingProfiles.js b/packages/server/src/controllers/StreamingController/endpoints/getStreamingProfiles.js
index c8d8bac2..f92b53b1 100644
--- a/packages/server/src/controllers/StreamingController/endpoints/getStreamingProfiles.js
+++ b/packages/server/src/controllers/StreamingController/endpoints/getStreamingProfiles.js
@@ -34,7 +34,7 @@ export default {
profile._id = profile._id.toString()
- profile.stream_key = `${req.user.username}:${profile._id}?secret=${profile.stream_key}`
+ profile.stream_key = `${req.user.username}__${profile._id}?secret=${profile.stream_key}`
return profile
})
diff --git a/packages/server/src/controllers/StreamingController/endpoints/getStreams.js b/packages/server/src/controllers/StreamingController/endpoints/getStreams.js
index b600c9e5..20546e2f 100755
--- a/packages/server/src/controllers/StreamingController/endpoints/getStreams.js
+++ b/packages/server/src/controllers/StreamingController/endpoints/getStreams.js
@@ -5,7 +5,7 @@ export default {
route: "/streams",
fn: async (req, res) => {
if (req.query.username) {
- const stream = await fetchRemoteStreams(`${req.query.username}${req.query.profile_id ? `:${req.query.profile_id}` : ""}`)
+ const stream = await fetchRemoteStreams(`${req.query.username}${req.query.profile_id ? `__${req.query.profile_id}` : ""}`)
if (!stream) {
return res.status(404).json({
diff --git a/packages/server/src/controllers/StreamingController/endpoints/handleStreamPublish.js b/packages/server/src/controllers/StreamingController/endpoints/handleStreamPublish.js
index d84a74e5..27810578 100755
--- a/packages/server/src/controllers/StreamingController/endpoints/handleStreamPublish.js
+++ b/packages/server/src/controllers/StreamingController/endpoints/handleStreamPublish.js
@@ -30,7 +30,7 @@ export default {
})
}
- const [username, profile_id] = app.split("/")[1].split(":")
+ const [username, profile_id] = app.split("/")[1].split("__")
if (user.username !== username) {
return res.status(403).json({
diff --git a/packages/server/src/controllers/StreamingController/endpoints/postStreamingProfile.js b/packages/server/src/controllers/StreamingController/endpoints/postStreamingProfile.js
index 03664217..3bedabce 100644
--- a/packages/server/src/controllers/StreamingController/endpoints/postStreamingProfile.js
+++ b/packages/server/src/controllers/StreamingController/endpoints/postStreamingProfile.js
@@ -1,6 +1,8 @@
import { StreamingProfile } from "@shared-classes/DbModels"
import NewStreamingProfile from "@services/newStreamingProfile"
+const AllowedChangesFields = ["profile_name", "info", "options"]
+
export default {
method: "POST",
route: "/streaming/profile",
@@ -34,9 +36,11 @@ export default {
if (currentProfile && profile_id) {
// update the profile
- currentProfile.profile_name = profile_name
- currentProfile.info = info
- currentProfile.options = options
+ AllowedChangesFields.forEach((field) => {
+ if (req.body[field]) {
+ currentProfile[field] = req.body[field]
+ }
+ })
await currentProfile.save()
} else {
diff --git a/packages/server/src/services/fetchRemoteStreams/index.js b/packages/server/src/services/fetchRemoteStreams/index.js
index 58ec1ebc..564ced96 100644
--- a/packages/server/src/services/fetchRemoteStreams/index.js
+++ b/packages/server/src/services/fetchRemoteStreams/index.js
@@ -17,7 +17,6 @@ export default async (stream_id) => {
url: apiURI,
params: {
stream: stream_id,
- useFetch: true,
}
}).catch((err) => {
console.error(err)
@@ -34,10 +33,8 @@ export default async (stream_id) => {
streamings = data
}
- streamings = streamings.map(async (stream) => {
- const { video, audio, clients, name } = stream
-
- const profile_id = name.split(":")[1]
+ streamings = streamings.map(async (entry) => {
+ const { stream, profile_id } = entry
let profile = await StreamingProfile.findById(profile_id)
@@ -62,13 +59,10 @@ export default async (stream_id) => {
return {
profile_id: profile._id,
info: profile.info,
- name: name,
+ name: stream,
streamUrl: `${user.username}?profile=${profile._id}`,
- user,
- video,
- audio,
- connectedClients: clients ?? 0,
sources: lodash.pick(sources, ["rtmp", "hls", "flv", "aac"]),
+ user,
}
})
diff --git a/packages/server/src/utils/compose-streaming-sources/index.js b/packages/server/src/utils/compose-streaming-sources/index.js
index c9e87d28..dca4b990 100644
--- a/packages/server/src/utils/compose-streaming-sources/index.js
+++ b/packages/server/src/utils/compose-streaming-sources/index.js
@@ -3,13 +3,13 @@ const streamingServerAPIAddress = process.env.STREAMING_API_SERVER ?? ""
const streamingServerAPIUri = `${streamingServerAPIAddress.startsWith("https") ? "https" : "http"}://${streamingServerAPIAddress.split("://")[1]}`
export default (username, profile_id) => {
- const streamId = `${username}${profile_id ? `:${profile_id}` : ""}`
+ const streamId = `${username}${profile_id ? `__${profile_id}` : ""}`
return {
ingest: process.env.STREAMING_INGEST_SERVER,
rtmp: `${streamingServerAPIUri}/${streamId}`,
- hls: `${streamingServerAPIUri}/stream/${streamId}/src.m3u8`,
- flv: `${streamingServerAPIUri}/stream/${streamId}/src.flv`,
- aac: `${streamingServerAPIUri}/stream/${streamId}/src.aac`,
+ hls: `${streamingServerAPIUri}/stream/hls/${streamId}`,
+ flv: `${streamingServerAPIUri}/stream/flv/${streamId}`,
+ mp3: `${streamingServerAPIUri}/stream/mp3/${streamId}`,
}
}
\ No newline at end of file
diff --git a/shared/classes/DbModels/streamingProfile/index.js b/shared/classes/DbModels/streamingProfile/index.js
index b07073ac..1332700c 100644
--- a/shared/classes/DbModels/streamingProfile/index.js
+++ b/shared/classes/DbModels/streamingProfile/index.js
@@ -27,6 +27,7 @@ export default {
options: {
type: Object,
default: {
+ connection_protected: true,
private: false,
chatEnabled: true,
drvEnabled: false,