Pi Camera Stream
This commit is contained in:
commit
f29ba428d6
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) SmartBuilds.io, Inc. and its affiliates.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Make you own Raspberry Pi Camera Stream
|
||||||
|
|
||||||
|
Create your own live stream from a Raspberry Pi using the Pi camera module. Build your own applications from here.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
The Pi streams the output of the camera module over the web via Flask. Devices connected to the same network would be able to access the camera stream via
|
||||||
|
|
||||||
|
```
|
||||||
|
<raspberry_pi_ip:5000>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
| ![Setup](img/readme/[].png) | ![Live Pi Camera Stream](img/readme/[].png) |
|
||||||
|
|---|---|
|
||||||
|
| Pi Setup | Pi - Live Stream |
|
||||||
|
|
||||||
|
## Preconditions
|
||||||
|
|
||||||
|
* Raspberry Pi 4, 2GB is recommended for optimal performance. However you can use a Pi 3 or older, you may see a increase in latency.
|
||||||
|
* Raspberry Pi 4 Camera Module or Pi HQ Camera Module (Newer version)
|
||||||
|
* Python 3 recommended.
|
||||||
|
|
||||||
|
## Step 1 – Cloning Raspberry Pi Camera Stream
|
||||||
|
Open up terminal and clone the Camera Stream repo:
|
||||||
|
|
||||||
|
```
|
||||||
|
bash cd /home/pi
|
||||||
|
git clone []
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2 – Launch Web Stream
|
||||||
|
|
||||||
|
Note: Creating an Autostart of the main.py script is recommended to keep the stream running on bootup.
|
||||||
|
```bash cd modules
|
||||||
|
sudo python3 /home/pi/[]/main.py
|
||||||
|
```
|
||||||
|
## Download Beta image of Raspberry Pi Camera Stream
|
||||||
|
Any troubles installing, try out the already compiled Raspberry Pi (Raspbian OS) Image of [Raspberry Pi Camera Stream](https://smartbuilds.io).
|
||||||
|
![Raspbian Camera Stream Image](img/readme/[].png)
|
|
@ -0,0 +1,28 @@
|
||||||
|
#Modified by smartbuilds.io
|
||||||
|
#Date: 27.09.20
|
||||||
|
#Desc: This scrtipt script..
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
from imutils.video.pivideostream import PiVideoStream
|
||||||
|
import imutils
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class VideoCamera(object):
|
||||||
|
def __init__(self, flip = False):
|
||||||
|
self.vs = PiVideoStream().start()
|
||||||
|
self.flip = flip
|
||||||
|
time.sleep(2.0)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.vs.stop()
|
||||||
|
|
||||||
|
def flip_if_needed(self, frame):
|
||||||
|
if self.flip:
|
||||||
|
return np.flip(frame, 0)
|
||||||
|
return frame
|
||||||
|
|
||||||
|
def get_frame(self):
|
||||||
|
frame = self.flip_if_needed(self.vs.read())
|
||||||
|
ret, jpeg = cv2.imencode('.jpg', frame)
|
||||||
|
return jpeg.tobytes()
|
|
@ -0,0 +1,189 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
overflow: hidden;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
background-color: black;
|
||||||
|
opacity:0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a {
|
||||||
|
float: left;
|
||||||
|
display: block;
|
||||||
|
color: #f2f2f2;
|
||||||
|
text-align: center;
|
||||||
|
padding: 14px 16px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a:hover {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a.active {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.camera-movement{
|
||||||
|
float: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lights-button{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.fa {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 60px;
|
||||||
|
box-shadow: 0px 0px 2px #888;
|
||||||
|
padding: 0.5em 0.6em;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 35%
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: Transparent;
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
border: none;
|
||||||
|
cursor:pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
outline:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CSS
|
||||||
|
.camera-bg {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
/* Preserve aspet ratio */
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
/* Full height */
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
|
||||||
|
/* Center and scale the image nicely */
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-right-logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 3%;
|
||||||
|
left: 2%;
|
||||||
|
font-size: 38px;
|
||||||
|
color: white;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<title>Make - PiStream</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="main" id="newpost">
|
||||||
|
<img class="camera-bg" style="width: 100%; height:80%; background-attachment: fixed;" id="bg" class="center" src="{{ url_for('video_feed') }}">
|
||||||
|
<!--<img class="camera-bg" style="width: 100%; height:80%; background-attachment: fixed;" id="bg" class="center" src="https://www.psdbox.com/wp-content/uploads/2011/01/security-camera-photoshop-effect.jpg">-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="top-right-logo">
|
||||||
|
<a></a>Raspberry Pi - Camera Stream </a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
|
||||||
|
<div class="ignoreCall">
|
||||||
|
<a id=decline class="but_def">
|
||||||
|
<button id="button">
|
||||||
|
<i style="background: red; color: white;" class="fa fa-times fa-2x" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method = "post">
|
||||||
|
|
||||||
|
<div class="camera-movement">
|
||||||
|
|
||||||
|
<a href=# id=center>
|
||||||
|
<button>
|
||||||
|
<i class="fa fa-camera fa-3x" style="color: white" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var button = document.getElementById('button');
|
||||||
|
|
||||||
|
button.onclick = function() {
|
||||||
|
var div = document.getElementById('newpost');
|
||||||
|
if (div.style.display !== 'none') {
|
||||||
|
div.style.display = 'none';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
div.style.display = 'block';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#Modified by smartbuilds.io
|
||||||
|
#Date: 27.09.20
|
||||||
|
#Desc: This scrtipt script..
|
||||||
|
# main.py
|
||||||
|
|
||||||
|
# import the necessary packages
|
||||||
|
from flask import Flask, render_template, Response
|
||||||
|
from camera import VideoCamera
|
||||||
|
app = Flask(__name__)
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
# rendering webpage
|
||||||
|
return render_template('index.html')
|
||||||
|
def gen(camera):
|
||||||
|
while True:
|
||||||
|
#get camera frame
|
||||||
|
frame = camera.get_frame()
|
||||||
|
yield (b'--frame\r\n'
|
||||||
|
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
|
||||||
|
@app.route('/video_feed')
|
||||||
|
def video_feed():
|
||||||
|
return Response(gen(VideoCamera()),
|
||||||
|
mimetype='multipart/x-mixed-replace; boundary=frame')
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# defining server ip address and port
|
||||||
|
app.run(host='0.0.0.0',port='5000', debug=False)
|
Loading…
Reference in New Issue