mirror of
https://gitlab.com/vyla-entertainment/documentation.git
synced 2026-11-09 20:17:20 -05:00
UI updated
This commit is contained in:
@@ -1,177 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en" class="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Our Architecture — Vyla</title>
|
||||
<meta name="description"
|
||||
<meta name="keywords"
|
||||
content="Vyla architecture, Vyla Home, Vyla SDK, Stream API, system design, media stack, deployment patterns, self-hosted media" />
|
||||
<link rel="canonical" href="https://vyla.cc/architecture.html" />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://vyla.cc/architecture.html" />
|
||||
<meta property="og:title" content="Our Architecture — Vyla" />
|
||||
<meta property="og:description"
|
||||
content="How Vyla Home, SDK, and Stream API relate, and where each responsibility belongs." />
|
||||
<meta property="og:image" content="https://vyla.cc/assets/images/thumbnail.png" />
|
||||
<meta property="og:site_name" content="Vyla" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content="https://vyla.cc/architecture.html" />
|
||||
<meta property="twitter:title" content="Our Architecture — Vyla" />
|
||||
<meta property="twitter:description"
|
||||
content="How Vyla Home, SDK, and Stream API relate, and where each responsibility belongs." />
|
||||
<meta property="twitter:image" content="https://vyla.cc/assets/images/thumbnail.png" />
|
||||
<meta property="twitter:site" content="@vylaentertainment" />
|
||||
|
||||
<!-- Additional SEO -->
|
||||
<meta name="robots" content="index, follow" />
|
||||
<meta name="author" content="Vyla" />
|
||||
content="How Vyla Home, SDK, and Stream API relate, and where each responsibility belongs." />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/assets/base.css" />
|
||||
<link rel="stylesheet" href="/assets/highlight.css" />
|
||||
<link rel="stylesheet" href="/assets/mintlify-overrides.css" />
|
||||
<script>
|
||||
(function () {
|
||||
var saved = localStorage.getItem('vyla-theme');
|
||||
var isDark = saved ? saved === 'dark' : true;
|
||||
document.documentElement.classList.toggle('dark', isDark);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="banner">
|
||||
<span>Vyla is self-hosted. Run Vyla Home, embed the SDK, or deploy Stream API on infrastructure you control. Rights
|
||||
holders can request source removal — <a href="/misc/dmca">DMCA policy</a>.</span>
|
||||
<button id="banner-close" onclick="dismissBanner()" aria-label="Dismiss">✕</button>
|
||||
</div>
|
||||
|
||||
<header id="navbar">
|
||||
<div class="nav-top">
|
||||
<a class="brand" href="/"><img src="/assets/images/logo.png" alt="Vyla" id="brand-logo"></a>
|
||||
<button id="search-trigger" type="button" onclick="openSearch()" aria-label="Search"></button>
|
||||
<div class="links">
|
||||
<button id="theme-toggle" type="button" onclick="toggleThemeMenu(event)" aria-label="Theme"></button>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="tabs">
|
||||
<a class="tab-link" href="/">Vyla</a>
|
||||
<a class="tab-link" href="/sdk">SDK</a>
|
||||
<a class="tab-link active" href="/stream-api/overview">Stream API</a>
|
||||
<a class="tab-link" href="/guides/integrations">Resources</a>
|
||||
<a class="tab-link" href="/misc/credit">Misc</a>
|
||||
</nav>
|
||||
</header>
|
||||
<div id="layout">
|
||||
<nav id="sidebar">
|
||||
<div class="group">
|
||||
<p class="group-title">Start here</p>
|
||||
<ul>
|
||||
<li><a class="active" href="/">Introduction</a></li></li>
|
||||
<li><a class="active" href="/architecture">Architecture</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="group">
|
||||
<p class="group-title">Products</p>
|
||||
<ul>
|
||||
<li><a class="" href="/home">Home</a></li>
|
||||
<li><a class="" href="/go">Go</a></li>
|
||||
<li><a class="" href="/tv">Tv</a></li>
|
||||
<li><a class="" href="/player">Player</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="group">
|
||||
<p class="group-title">Concepts</p>
|
||||
<ul>
|
||||
<li><a class="" href="/concepts/providers">Providers</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="content-col">
|
||||
<main class="prose">
|
||||
<h1>Our Architecture</h1>
|
||||
<p class="page-description">How Vyla Home, SDK, and Stream API relate, and where each responsibility belongs.
|
||||
</p>
|
||||
<h2 id="the-vyla-stack">The Vyla stack</h2>
|
||||
<p>Vyla separates local application management, provider resolution, and client-facing delivery. That separation
|
||||
lets each layer be used on its own while keeping the integration points clear.</p>
|
||||
<h3 id="vyla-home">Vyla Home</h3>
|
||||
<p>Home is responsible for a desktop session: local configuration, encrypted local credentials, update
|
||||
coordination, managed processes, and the embedded interface. It is the right layer for launching and
|
||||
supervising a local experience.</p>
|
||||
<h3 id="vyla-sdk">Vyla SDK</h3>
|
||||
<p>The SDK contains the provider-facing work: source configuration, stream resolution, subtitle retrieval,
|
||||
download lookup, and health probes. It is the right layer when your Node.js application needs to decide how
|
||||
requests are authorized, cached, selected, and returned.</p>
|
||||
<h3 id="stream-api">Stream API</h3>
|
||||
<p>Stream API wraps the SDK in a self-hosted HTTP service. Its movie and TV endpoints use Server-Sent Events so
|
||||
metadata can arrive first and usable sources can be delivered progressively. It also provides subtitle,
|
||||
download, health, test, and optional debug routes.</p>
|
||||
<h2 id="common-deployment-patterns">Common deployment patterns</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Pattern</th>
|
||||
<th>Best for</th>
|
||||
<th>Key decision</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Home only</td>
|
||||
<td>a managed local desktop experience</td>
|
||||
<td>Home owns the lifecycle of bundled local services</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>App + SDK</td>
|
||||
<td>a Node.js backend with a custom product API</td>
|
||||
<td>your app owns authentication, policy, and response design</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Player + Stream API</td>
|
||||
<td>browser or mobile clients that need a stable HTTP contract</td>
|
||||
<td>deploy Stream API and place it behind TLS when exposed remotely</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Home + Stream API</td>
|
||||
<td>a local player backed by a local service</td>
|
||||
<td>keep the service bound and access-controlled for the local environment</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2 id="data-flow-for-playback">Data flow for playback</h2>
|
||||
<ol>
|
||||
<li>A client provides a TMDB media ID (plus season and episode for TV).</li>
|
||||
<li>Stream API, or your own SDK-based backend, asks active providers for candidates.</li>
|
||||
<li>Candidates are checked and successful sources are returned progressively.</li>
|
||||
<li>The player begins with the first compatible candidate and keeps later candidates as fallbacks.</li>
|
||||
<li>Subtitle and download lookups are separate operations; neither should block first playback.</li>
|
||||
</ol>
|
||||
<p>Provider availability varies by source and network environment. Build the player experience around fallbacks
|
||||
and empty-result states, as described in <a href="/guides/error-handling">Error handling</a>.</p>
|
||||
</main>
|
||||
<aside id="toc">
|
||||
<p class="toc-title">On this page</p>
|
||||
<ul>
|
||||
<li><a href="#the-vyla-stack">The Vyla stack</a></li>
|
||||
<li><a href="#common-deployment-patterns">Common deployment patterns</a></li>
|
||||
<li><a href="#data-flow-for-playback">Data flow for playback</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
<footer id="site-footer">
|
||||
<a href="https://discord.gg/5eqRhKeywG" target="_blank" rel="noopener">Discord</a>
|
||||
<a href="https://gitlab.com/vyla-entertainment/" target="_blank" rel="noopener">GitLab</a>
|
||||
</footer>
|
||||
<script src="/assets/app.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -81,7 +81,7 @@ function buildThemeControls() {
|
||||
seg.innerHTML = modes.map(function (m) {
|
||||
return '<button type="button" data-mode="' + m + '" aria-label="' + m + '">' + icon(m) + "</button>";
|
||||
}).join("");
|
||||
links.appendChild(seg);
|
||||
(document.querySelector("#sidebar .side-links") || links).appendChild(seg);
|
||||
[menu, seg].forEach(function (el) {
|
||||
el.addEventListener("click", function (e) {
|
||||
var b = e.target.closest("button");
|
||||
@@ -185,7 +185,9 @@ function buildMobileBar() {
|
||||
var newSidebar = doc.querySelector("#sidebar");
|
||||
if (newSidebar) {
|
||||
var groups = newSidebar.querySelectorAll(".group");
|
||||
var sideHead = sidebar.querySelector(".side-head");
|
||||
sidebar.innerHTML = "";
|
||||
if (sideHead) sidebar.appendChild(sideHead);
|
||||
if (mobileTabs) sidebar.appendChild(mobileTabs);
|
||||
groups.forEach(function (group) {
|
||||
sidebar.appendChild(group.cloneNode(true));
|
||||
@@ -202,6 +204,18 @@ function buildMobileBar() {
|
||||
});
|
||||
});
|
||||
}
|
||||
var head = document.createElement("div");
|
||||
head.className = "side-head";
|
||||
var brand = document.querySelector("#navbar .brand");
|
||||
if (brand && sidebar) {
|
||||
var b = brand.cloneNode(true);
|
||||
b.querySelector("img").removeAttribute("id");
|
||||
var sideLinks = document.createElement("div");
|
||||
sideLinks.className = "side-links";
|
||||
head.appendChild(b);
|
||||
head.appendChild(sideLinks);
|
||||
sidebar.insertBefore(head, sidebar.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
function addEyebrow() {
|
||||
|
||||
@@ -1416,7 +1416,7 @@ html.dark .search-footer {
|
||||
|
||||
.mobile-tabs {
|
||||
display: block;
|
||||
margin-top: 50px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
body.nav-open #theme-seg {
|
||||
@@ -1445,16 +1445,16 @@ html.dark .search-footer {
|
||||
#sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: var(--sidebar-top, var(--header-height));
|
||||
top: 0;
|
||||
width: 80%;
|
||||
max-width: 340px;
|
||||
height: calc(100vh - var(--sidebar-top, var(--header-height)));
|
||||
height: calc(100dvh - var(--sidebar-top, var(--header-height)));
|
||||
padding: 20px 16px;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
padding: 0 16px 20px;
|
||||
background: var(--bg-light);
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.2s ease;
|
||||
z-index: 30;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
html.dark #sidebar {
|
||||
@@ -1498,4 +1498,37 @@ main.prose p {
|
||||
main.prose p,
|
||||
main.prose li {
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.side-head {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.side-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 60px;
|
||||
margin: 0 -16px 12px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
#sidebar .side-head .brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#sidebar .side-head .brand img {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#sidebar .side-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user