generated from ElnuDev/rust-project
Compare commits
2 Commits
351ae0248f
...
341f67c80b
Author | SHA1 | Date |
---|---|---|
Elnu | 341f67c80b | 7 months ago |
Elnu | 85c91f3052 | 7 months ago |
@ -1,5 +1,5 @@
|
||||
{
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./helloworld/Cargo.toml",
|
||||
"./webcam-streamer/Cargo.toml",
|
||||
]
|
||||
}
|
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,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…
Reference in new issue