Skip to content

Commit

Permalink
update to streaming service version 5_b7
Browse files Browse the repository at this point in the history
  • Loading branch information
srgooglo committed Dec 19, 2023
1 parent 3ce53e9 commit d398173
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 52 deletions.
147 changes: 115 additions & 32 deletions packages/app/src/pages/tv/tabs/livestreamControlPanel/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import "./index.less"

export default (props) => {
const [L_Profiles, R_Profiles, E_Profiles, M_Profiles] = app.cores.api.useRequest(Livestream.getProfiles)

const [profileData, setProfileData] = React.useState(null)
const [selectedProfileId, setSelectedProfileId] = React.useState(null)

const [isConnected, setIsConnected] = React.useState(false)
const [loadingChanges, setLoadingChanges] = React.useState(false)

React.useEffect(() => {
if (R_Profiles) {
Expand All @@ -30,23 +30,14 @@ export default (props) => {
}
}, [R_Profiles])

if (E_Profiles) {
console.error(E_Profiles)

return <antd.Result
status="error"
title="Failed to load profiles"
subTitle="Failed to load profiles, please try again later"
/>
}

if (L_Profiles) {
return <antd.Skeleton active />
}

const profileData = R_Profiles.find((profile) => profile._id === selectedProfileId)
React.useEffect(() => {
if (selectedProfileId) {
console.log(R_Profiles)
setProfileData(R_Profiles.find((profile) => profile._id === selectedProfileId))
}
}, [selectedProfileId])

const handleCreateProfile = async (profile_name) => {
async function handleCreateProfile(profile_name) {
if (!profile_name) {
return false
}
Expand All @@ -70,7 +61,7 @@ export default (props) => {
}
}

const handleCurrentProfileDataUpdate = async (newProfileData) => {
async function handleCurrentProfileDataUpdate(newProfileData) {
if (!profileData) {
return
}
Expand All @@ -95,7 +86,7 @@ export default (props) => {
}
}

const handleCurrentProfileDelete = async () => {
async function handleCurrentProfileDelete() {
if (!profileData) {
return
}
Expand Down Expand Up @@ -126,7 +117,7 @@ export default (props) => {
})
}

const onClickEditInfo = () => {
async function onClickEditInfo() {
if (!profileData) {
return
}
Expand All @@ -140,7 +131,7 @@ export default (props) => {
})
}

const regenerateStreamingKey = async () => {
async function regenerateStreamingKey() {
if (!profileData) {
return
}
Expand All @@ -163,7 +154,58 @@ export default (props) => {
})
}

return <div className="streamingControlPanel">
async function updateOption(key, value) {
if (!profileData) {
return
}

setLoadingChanges(`option:${key}`)

const result = await Livestream.postProfile({
profile_id: profileData._id,
profile_name: profileData.profile_name,
options: {
[key]: value
}
}).catch((err) => {
console.error(err)
app.message.error(`Failed to update option`)
setLoadingChanges(false)

return false
})

if (result) {
console.log("Updated options >", result)

setProfileData((prev) => {
return {
...prev,
...result,
}
})
setLoadingChanges(false)
}
}

if (E_Profiles) {
console.error(E_Profiles)

return <antd.Result
status="error"
title="Failed to load profiles"
subTitle="Failed to load profiles, please try again later"
/>
}

if (L_Profiles) {
return <antd.Skeleton active />
}

return <div
className="streamingControlPanel"
disabled={!profileData || loadingChanges}
>
<div className="streamingControlPanel_header_thumbnail">
<img
src={
Expand Down Expand Up @@ -272,23 +314,49 @@ export default (props) => {
<h2><Icons.Tool />Additional options</h2>

<div className="content">
<span>Enable DVR</span>
<p className="label">
<Icons.MdFiberDvr /> DVR
</p>

<span className="description">
This function will save a copy of your stream with its entire duration.
You can get this copy after finishing this livestream
</span>

<div className="value">
<antd.Switch
checked={profileData?.options?.dvr ?? false}
onChange={false}
disabled
/>
</div>
</div>

<div className="content">
<span>Private mode</span>
<p className="label">
<Icons.MdPrivateConnectivity /> Private mode
</p>

<span className="description">
When this is enabled, only users with the livestream url can access the stream. Your stream will not be visible on the app.
</span>

<span
className="description"
style={{
fontWeight: "bold",
}}
>
You must restart the livestream to apply the changes.
</span>

<div className="value">
<antd.Switch
checked={profileData?.options?.private ?? false}
onChange={false}
onChange={(value) => {
updateOption("private", value)
}}
loading={loadingChanges === "option:private"}
/>
</div>
</div>
Expand All @@ -298,31 +366,46 @@ export default (props) => {
<h2><Icons.Link /> URL Information</h2>

<div className="content">
<span>AAC URL (Only Audio)</span>
<div className="title">
<p>HLS URL</p>
<p>[6s~12s latency]</p>
</div>

<span className="description">This protocol is highly compatible with a multitude of devices and services. Recommended for general use.</span>

<div className="inline_field">
<span>
{profileData?.addresses?.aac ?? "No AAC URL available"}
{profileData?.addresses?.hls ?? "No HLS URL available"}
</span>
</div>
</div>

<div className="content">
<span>HLS URL</span>
<div className="title">
<p>FLV URL</p>
<p>[2s~5s latency]</p>
</div>

<span className="description">This protocol operates at better latency and quality than HLS, but is less compatible for most devices.</span>

<div className="inline_field">
<span>
{profileData?.addresses?.hls ?? "No HLS URL available"}
{profileData?.addresses?.flv ?? "No FLV URL available"}
</span>
</div>
</div>

<div className="content">
<span>FLV URL</span>
<div className="title">
<p>MP3 URL (Only Audio)</p>
<p>[2s ~ 5s latency]</p>
</div>

<span className="description">This protocol will only return an audio file. The maximum quality compatible with this codec will be used (320Kbps, 48KHz)</span>

<div className="inline_field">
<span>
{profileData?.addresses?.flv ?? "No FLV URL available"}
{profileData?.addresses?.mp3 ?? "No MP3 URL available"}
</span>
</div>
</div>
Expand Down
39 changes: 39 additions & 0 deletions packages/app/src/pages/tv/tabs/livestreamControlPanel/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

gap: 20px;

&[disabled]{
pointer-events: none;
}

.inline_field {
background-color: var(--background-color-accent);

Expand Down Expand Up @@ -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;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit d398173

Please sign in to comment.