Compare commits

...

2 Commits

Author SHA1 Message Date
Elnu 341f67c80b Initial proof of concept
7 months ago
Elnu 85c91f3052 Rename repo
7 months ago

@ -1,5 +1,5 @@
{
"rust-analyzer.linkedProjects": [
"./helloworld/Cargo.toml",
"./webcam-streamer/Cargo.toml",
]
}

1251
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -1,3 +1,3 @@
[workspace]
members = ["helloworld"]
members = ["webcam-streamer"]
resolver = "2"

@ -0,0 +1,96 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1699099776,
"narHash": "sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "85f1ba3e51676fa8cc604a3d863d729026a6b8eb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1681358109,
"narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1699236891,
"narHash": "sha256-J0uhoYlufJncIFbM/pAoggzHK/qERB9KfQRkmYD56yo=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "a7f9bf91dc5065d470cd57169a9f2ebdbdfe1f24",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

@ -1,20 +1,9 @@
/*
TODO
1. Find and replace "helloworld" with your package name for **ALL FILES IN REPOSITORY**
2. Add a flake description that describes the workspace on line 27
3. Add a package description on line 70
4. (optional) uncomment `nativeBuildInputs` and `buildInputs` on lines 43 and 44 if you need openssl
5. (optional) set your project homepage, license, and maintainers list on lines 48-51
6. (optional) uncomment the NixOS module and update it for your needs
7. Delete this comment block
*/
/*
Some utility commands:
- `nix flake update --commit-lock-file`
- `nix flake lock update-input <input>`
- `nix build .#helloworld` or `nix build .`
- `nix run .#helloworld` or `nix run .`
- `nix build .#webcam-streamer` or `nix build .`
- `nix run .#webcam-streamer` or `nix run .`
*/
{
@ -34,15 +23,14 @@ Some utility commands:
};
rustSettings = with pkgs; {
src = ./.;
#nativeBuildInputs = [ pkg-config ];
#buildInputs = [ openssl ];
buildInputs = with pkgs; [ ffmpeg ];
cargoHash = nixpkgs.lib.fakeHash;
};
meta = with nixpkgs.lib; {
#homepage = "https://example.com";
#license = [ licenses.gpl3 ];
homepage = "https://git.elnu.com/ElnuDev/webcam-streamer";
license = [ licenses.gpl3 ];
platforms = [ system ];
#maintainers = with maintainers; [ ];
maintainers = with maintainers; [ elnudev ];
};
in {
devShells.${system}.default = with pkgs; mkShell {
@ -53,14 +41,14 @@ Some utility commands:
cargo-edit
bacon
];
inputsFrom = with self.packages.${system}; [ helloworld ];
inputsFrom = with self.packages.${system}; [ webcam-streamer ];
};
packages.${system} = {
default = self.packages.${system}.helloworld;
helloworld = pkgs.rustPlatform.buildRustPackage (rustSettings // {
pname = "helloworld";
default = self.packages.${system}.webcam-streamer;
webcam-streamer = pkgs.rustPlatform.buildRustPackage (rustSettings // {
pname = "webcam-streamer";
version = "0.1.0";
buildAndTestSubdir = "helloworld";
buildAndTestSubdir = "webcam-streamer";
cargoHash = "sha256-+TaGIiKf+Pz2bTABeG8aCZz0/ZTCKl5398+qbas4Nvo=";
meta = meta // {
description = "";
@ -71,14 +59,14 @@ Some utility commands:
nixosModules.default = { config, ... }: let
lib = nixpkgs.lib;
in {
options.services.helloworld = {
enable = lib.mkEnableOption (lib.mdDoc "helloworld service");
options.services.webcam-streamer = {
enable = lib.mkEnableOption (lib.mdDoc "webcam-streamer service");
package = lib.mkOption {
type = lib.types.package;
default = self.packages.${system}.helloworld;
defaultText = "pkgs.helloworld";
default = self.packages.${system}.webcam-streamer;
defaultText = "pkgs.webcam-streamer";
description = lib.mdDoc ''
The helloworld package that should be used.
The webcam-streamer package that should be used.
'';
};
port = lib.mkOption {
@ -89,16 +77,16 @@ Some utility commands:
'';
};
};
config.systemd.services.helloworld = let
cfg = config.services.helloworld;
pkg = self.packages.${system}.helloworld;
config.systemd.services.webcam-streamer = let
cfg = config.services.webcam-streamer;
pkg = self.packages.${system}.webcam-streamer;
in lib.mkIf cfg.enable {
description = pkg.meta.description;
after = [ "network.target" ];
wantedBy = [ "network.target" ];
serviceConfig = {
ExecStart = ''
${cfg.package}/bin/helloworld --port ${builtins.toString cfg.port}
${cfg.package}/bin/webcam-streamer --port ${builtins.toString cfg.port}
'';
Restart = "always";
DynamicUser = true;

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}

@ -1,8 +1,11 @@
[package]
name = "helloworld"
name = "webcam-streamer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "4.4.0"
lazy_static = "1.4.0"
rscam = { version = "0.5.5", features = ["no_wrapper"] }

@ -0,0 +1,59 @@
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
use lazy_static::lazy_static;
use rscam::Camera;
use std::{
sync::Mutex,
thread,
};
const FPS: u32 = 30;
lazy_static! {
static ref CAMERA: Camera = {
let mut camera = rscam::new("/dev/video0").unwrap();
camera
.start(&rscam::Config {
interval: (1, FPS),
resolution: (1280, 720),
format: b"MJPG",
..Default::default()
})
.unwrap();
camera
};
static ref CURRENT_FRAME: Mutex<Vec<u8>> = Mutex::new(Vec::new());
}
#[get("/feed.jpg")]
async fn get_feed() -> impl Responder {
HttpResponse::Ok()
.content_type("image/jpeg")
.body(CURRENT_FRAME.lock().unwrap().clone())
}
#[get("/")]
async fn get_index() -> impl Responder {
HttpResponse::Ok().content_type("text/html").body(format!(
"
<img src=\"feed.jpg\">
<script>
const img = document.querySelector(\"img\");
setInterval(() => {{
img.src = \"feed.jpg?\" + new Date().getTime();
}}, {});
</script>
",
1000.0 / FPS as f32
))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
thread::spawn(move || loop {
*CURRENT_FRAME.lock().unwrap() = CAMERA.capture().unwrap()[..].to_owned();
});
HttpServer::new(|| App::new().service(get_index).service(get_feed))
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Loading…
Cancel
Save