NetStream
NetStream is a completely free Avalonia application for searching, downloading, and streaming movies and TV shows. It features LibVLCSharp for smooth playback, Jackett for torrent search, and libtorrent for efficient torrent downloading, providing a seamless media experience on Windows.
Install / Use
/learn @xDreamms/NetStreamREADME
NetStream
NetStream is a Windows-first media client built as a three-layer stack: a vendored libtorrent source tree, a native C++ bridge that exposes torrent operations to .NET, and an Avalonia desktop application that handles the rest of the product story: discovery, playback, subtitles, authentication, comments, watch history, and subscription payments.
This repository is set up as a monorepo on purpose. The torrent engine, the native interop layer, and the desktop application move together often enough that keeping them in one place makes day-to-day work a lot simpler.
What lives here
At the top level, the repository is split into three main code areas and one runtime payload folder:
| Path | Role | Why it exists |
| --- | --- | --- |
| libtorrent/ | Vendored torrent engine source | Native torrent functionality is built against this tree. |
| LibTorrentSharp2/ | C++ shared library | Wraps libtorrent and exposes a C-style API that the .NET app can P/Invoke. |
| NetStream/ | .NET solution folder | Contains the Avalonia shared app and the Windows desktop host. |
| copy these to build output/ | Runtime helpers | Tools and payloads that must end up next to the app at build/publish time. |
Inside the solution folder, the layout is:
NetStream/
Directory.Packages.props
NetStream.sln
NetStream/
NetStream.Desktop/
NetStream/NetStream/is the shared Avalonia application.NetStream/NetStream.Desktop/is the Windows desktop entry point.NetStream/Directory.Packages.propsmanages NuGet package versions centrally.
The architecture in one picture
graph LR
A["NetStream.Desktop<br/>Windows host"] --> B["NetStream<br/>Avalonia app"]
B --> C["LibTorrentSharp2.dll<br/>native bridge"]
C --> D["libtorrent / torrent-rasterbar"]
B --> E["TMDb API"]
B --> F["Jackett service"]
B --> G["LibVLC runtime"]
B --> H["OpenSubtitles + ffsubsync"]
B --> I["Firebase / Firestore / Cloud Storage"]
B --> J["BTCPay Server"]
If you want the short version, this is the runtime chain:
- The desktop host boots Avalonia and starts the shared application layer.
- The shared app loads secrets from
.env, prepares local folders, and initializes media playback. - Jackett is installed or started if needed.
- Metadata, subtitles, account services, and billing services come online.
- The UI either resumes the user session or drops into sign-in/sign-up.
- Torrent selection and playback flow through the native wrapper and the media toolchain.
How the app actually works
NetStream is not just a UI on top of a torrent library. The app stitches together several subsystems that each own a different part of the experience.
Discovery and metadata
Movie and TV discovery runs through TMDb. The shared app creates a TMDbClient at startup and uses it for search, popular lists, episode details, images, and language-aware metadata.
Torrent search and indexing
Jackett is used as the indexer layer. On startup, the desktop app checks whether Jackett is installed, seeds the config files under %ProgramData%\Jackett, and starts the service if necessary. Once Jackett is running, the app loads indexers and uses them to resolve torrents for movies and episodes.
Torrent engine and native interop
The actual torrent engine is libtorrent, but the Avalonia app does not talk to it directly. Instead, the .NET side calls into LibTorrentSharp2.dll, a native wrapper that exposes torrent handles, status, files, priorities, piece ranges, pause/resume, and sequential download behavior through a P/Invoke-friendly boundary.
This split matters because it keeps the Avalonia app in C# while still letting the project use a mature native torrent engine underneath.
Playback
Playback is built around LibVLC. The desktop app initializes the native VLC runtime from the build output and uses LibVLCSharp for media playback inside the Avalonia UI.
Subtitles
Subtitles are handled through OpenSubtitles and local helper tools. The app supports a primary OpenSubtitles key and a pool of fallback keys, which is useful when you are working around rate limits. The runtime payload can also include tools such as ffsubsync_wrapper.exe for subtitle alignment workflows.
Accounts, comments, storage, and watch history
Account and cloud-backed features run through Firebase and Google Cloud services:
- Firebase Auth is used for sign-in, sign-up, password flows, and email verification.
- Firestore stores user data, comments, watch history, and account-related records.
- Google Cloud Storage is used for profile photos and related assets.
Payments
Billing is wired to BTCPay Server. The app initializes a BTCPay client during startup and uses it to create invoices and check payment state for subscription plans.
Startup flow
The launch path is straightforward once you know where to look:
NetStream.Desktop/Program.csstarts Avalonia, registers the icon provider, and keeps Native AOT metadata alive for TMDb types.NetStream/App.axaml.csloads.env, initializes LibVLC, prepares directories and settings, applies language and theme defaults, and opens the splash screen.- The app installs or starts Jackett, initializes subtitle services, and loads metadata configuration.
- Firebase and BTCPay are initialized.
- The app decides whether to restore a signed-in session or show account flows.
That startup sequence is worth understanding because most "it launches but feature X is broken" problems come from one of those layers not being available yet.
Repository map
Here is the practical map most contributors end up using:
.
|- libtorrent/ # native torrent source tree
|- LibTorrentSharp2/ # C++ wrapper + native build files
| |- CMakeLists.txt
| |- LibTorrentSharp2.sln
| |- LibTorrentSharp2/
| `- x64/
|- NetStream/
| |- Directory.Packages.props # central NuGet versions
| |- NetStream.sln
| |- NetStream/ # shared Avalonia app
| | |- Assets/
| | |- Controls/
| | |- Language/
| | |- Models/
| | |- Services/
| | |- SubtitleDownloader/
| | |- ViewModels/
| | `- Views/
| `- NetStream.Desktop/ # Windows host
|- copy these to build output/ # helper binaries copied into output
|- .env.example
`- .gitignore
Prerequisites
If you want a clean build on Windows, this is the stack to have ready:
- Windows 10 or Windows 11 x64
- .NET 9 SDK
- Visual Studio 2022 or the Visual C++ build tools with the
v143toolset - CMake 3.18 or newer if you want to build the native layer through CMake
- Boost 1.87 headers and libraries if you are rebuilding
LibTorrentSharp2 - A working
libtorrentsource tree under this repository - A populated
.envfile for external services
Two practical notes before you lose time chasing build errors:
- The checked-in Visual Studio project for
LibTorrentSharp2currently uses hardcoded include/library paths for Boost. If your machine uses different paths, update the project or build through CMake with explicit arguments. - The checked-in
CMakeLists.txtshould not be trusted blindly for path discovery. PassLIBTORRENT_ROOTandBOOST_ROOTexplicitly when you use it.
Environment configuration
Secrets no longer live in source code. The app loads them from a local .env file and the repository already ignores that file.
Start by copying .env.example to .env, then fill in the values you actually use.
NETSTREAM_JACKET_API_URL=
NETSTREAM_JACKET_API_KEY=
NETSTREAM_TMDB_API_KEY=
NETSTREAM_FIREBASE_AUTH_API_KEY=
NETSTREAM_FIREBASE_SERVICE_ACCOUNT_JSON_BASE64=
NETSTREAM_BTCPAY_URL=
NETSTREAM_BTCPAY_API_KEY=
NETSTREAM_BTCPAY_STORE_ID=
NETSTREAM_OPENSUBTITLES_API_KEY=
NETSTREAM_OPENSUBTITLES_API_KEYS=
The environment loader walks upward from the current working directory and the application base directory until it finds a .env file, so the normal repository-root setup works fine for local development.
What each variable is for
| Variable | Used by | Notes |
| --- | --- | --- |
| NETSTREAM_JACKET_API_URL | Jackett integration | Usually http://127.0.0.1:9117/ unless you run Jackett elsewhere. |
| NETSTREAM_JACKET_API_KEY | Jackett integration | Used when the app talks to the local or remote Jackett instance. |
| NETSTREAM_TMDB_API_KEY | TMDb client | Required for discovery and metadata. |
| NETSTREAM_FIREBASE_AUTH_API_KEY | Firebase Auth | Required for sign-in, sign-up, and email flows. |
| NETSTREAM_FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 | Firestore and Cloud Storage | Store the entire service account JSON as base64. |
| NETSTREAM_BTCPAY_URL | BTCPay | Required for invoice creation. |
| NETSTREAM_BTCPAY_API_KEY | BTCPay | API key for the configured store. |
| NETSTREAM_BTCPAY_STORE_ID | BTCPay | Store identifier used for invoice operations. |
| NETSTREAM_OPENSUBTITLES_API_KEY | Subtitle service | Primary OpenSubtitles key. |
| NETSTREAM_OPENSUBTITLES_API_KEYS | Subtitle service | Optional fallback key pool, separated by commas, semicolons, or new lines. |
For Firebase, the service account is intentionally stored as base64 rather than raw JSON because it keeps the .env file easier to parse and transport.
Building the native layer
The desktop app expects to find the native bridge at:
LibTorrentSharp2\x64\Release\LibTorrentSharp2.dll
Because of that, the least-friction path on Windows is to build the checked-in Visual Studio project in Release|x64.
Option A: build with MSBuild
Run this from the repository root in a Developer PowerShell or Developer Command Prompt:
msbuild .\LibTorrentSharp2\LibTorrentSharp2.sln /p:Configuration=Release /p:Platform=x64
If that completes successfully, the desktop project will copy LibTorrentSharp2.dll from the expected output folder automatically.
Option B: build wit
Related Skills
node-connect
346.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
