Raspberry PI Nightvision Cam (System)

$ raspi-config
-> Interfacing Options Configure connections to peripherals
-> P1 Camera Enable/Disable connection to the Raspberry Pi Camera
-> Would you like the camera interface to be enabled? -> YES !

Raspberry Cam Multiplexing - Raspivid

$ FFMPEG=/usr/bin/ffmpeg
$ raspivid -o - -t 0 -w 1280 -h 720 -fps 25 -b 1500000 -g 50 \
| $FFMPEG -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 \
-i /dev/zero -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 \
-strict experimental -f flv rtmp://yourserver/live

MJPEG with Raspberry PI Nightvision Cam

https://github.com/jacksonliam/mjpg-streamer this is a fork from the original mjpeg streamer
I am not using this anymore, if you want more users to watch your stream, this eats your hole bandwith from home, so i've to switch to a multiplexing solution.

$ sudo apt-get install git
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/
$ cd mjpg-streamer-experimental/
$ sudo apt-get install cmake python-imaging libjpeg-dev
$ make CMAKE_BUILD_TYPE=Debug
$ sudo make install
$ export LD_LIBRARY_PATH=.
$ ./mjpg_streamer -o "output_http.so -w ./www" -i "input_raspicam.so"

you can watch the steam on http://raspberrypiIP:8080

if you expect an error like : * failed to open vchiq instance you can do :
$ sudo chmod 777 /dev/vchiq


Hamster Wheel

//PINS
#define REEDSWITCH 13
#define WHEELSIZE 0.91

volatile unsigned long rotations = 0;
float meter = 0.0;
volatile unsigned long lastactive = 0;

// Debounce Vars
volatile unsigned long last_micros;
unsigned long debouncing_time = 500;              //Debouncing Time in Milliseconds

void setup()
{
  // Reed Sensor (Interrupt) 
  attachInterrupt(digitalPinToInterrupt(REEDSWITCH), debounceInterrupt, FALLING);
  //PINS
  pinMode(REEDSWITCH, INPUT);
  lastactive = millis();
}

void loop()
{ 
  if ( rotations >= 1 && ((millis() - lastactive) >= 1500) ) {
    meter = rotations * WHEELSIZE; 
    // rotations = 0;                      
    // meter = 0;
  }
}

// ----- Helper Functions 
void debounceInterrupt() {
  if ( micros() < last_micros ) {
    last_micros = micros();
  }
  if ((unsigned long)(micros() - last_micros) >= debouncing_time * 1000) {
    rotations++;
    last_micros = micros(); 
    lastactive = millis();
  }
}
  

DHT22

#include "DHTesp.h"

DHTesp dht;

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("Status\tHumidity (%)\tTemperature (C)\t(F)\tHeatIndex (C)\t(F)");

  dht.setup(12); // data pin 2
}

void loop()
{
  delay(dht.getMinimumSamplingPeriod());

  float humidity = dht.getHumidity();
  float temperature = dht.getTemperature();

  Serial.print(dht.getStatusString());
  Serial.print("\t");
  Serial.print(humidity, 1);
  Serial.print("\t\t");
  Serial.print(temperature, 1);
  Serial.print("\t\t");
  Serial.print(dht.toFahrenheit(temperature), 1);
  Serial.print("\t\t");
  Serial.print(dht.computeHeatIndex(temperature, humidity, false), 1);
  Serial.print("\t\t");
  Serial.println(dht.computeHeatIndex(dht.toFahrenheit(temperature), humidity, true), 1);
}

  

Webserver

#include < ESP8266WiFi.h>
#include < WiFiClient.h>
#include < ESP8266WebServer.h>
 
// Replace with your network credentials
const char* ssid = "Your WiFI SSID";
const char* password = "Your WiFI Password";
 
ESP8266WebServer server(80);   //instantiate server at port 80 (http port)
 
String page = "";

void setup(void){
 
  delay(1000);
  Serial.begin(115200);
  WiFi.begin(ssid, password); //begin WiFi connection
  Serial.println("");
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/", [](){
    page = "ESP8266 Webserver - hello world!";
    server.send(200, "text/html", page);
  });
  
  server.begin();
  Serial.println("Web server started!");
}
 
void loop(void){
  server.handleClient();
} 


RTMP NGINX Server

install NGINX for RTMP Server:
get latest package from http://nginx.org/download/
nginx rtmp modul :
$wget https://github.com/arut/nginx-rtmp-module/archive/master.zip
$ tar -zxvf nginx-1.13.1.tar.gz
$ unzip master.zip
$ cd nginx-1.13.1
$ ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-master
$ make
$ sudo make install
$ sudo /usr/local/nginx/sbin/nginx
configure /usr/local/nginx/conf/nginx.conf

rtmp {
  server {
    listen 1935;
	    chunk_size 4096;
	    application live {
	            live on;
	            record off;
	            push rtmp://live-ber.twitch.tv/app/live_KEY;
	            push rtmp://a.rtmp.youtube.com/live2/KEY;
	    }
	}
}

HLS.JS Video embed

I use : https://github.com/video-dev/hls.js for video embed of the hls stream from the server.

<div class="embed-responsive embed-responsive-4by3">
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<video id="video" width="250" controls></video>
<script>
  if(Hls.isSupported()) {
    var video = document.getElementById('video');
    var hls = new Hls();
    hls.loadSource('http://eeris.org:8080/live/hamster.m3u8');
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED,function() {
      video.play();
  });
 }
 // hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
 // When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) 
 // directly to the video element throught the `src` property.
 // This is using the built-in support of the plain video element, without using hls.js.
  else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = 'http://eeris.org:8080/live/hamster.m3u8';
    video.addEventListener('canplay',function() {
      video.play();
    });
  }
</script>  
</div>