### ch07 程式碼下載 ###
$ cd ~/Lab
$ wget https://max543.com/debugger/class/python02/PiCamera/Lab/code/ch07.zip
$ unzip ch07.zip
### ex7-1 ###
# 啟動 RTSP Server
$ raspivid -o - -t 0 -hf --rotation 180 -w 320 -h 240 -fps 15 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554}' :demux=h264
# 找出佔用的 Port Number 的 PID
$ sudo netstat -lpn |grep 8554
# 刪除佔用的 PID
$ sudo kill -9 PID
### ex7-2 ###
# VLC media player
https://get.videolan.org/vlc/3.0.14/win64/vlc-3.0.14-win64.exe
### ex7-3 ###
# 安裝輕量級的 RTSP Server
$ cd ~
$ git clone https://github.com/mpromonet/h264_v4l2_rtspserver.git
$ sudo apt-get install liblivemedia-dev libv4l-dev cmake
$ cd h264_v4l2_rtspserver
$ cmake .
$ make -j4
$ sudo ./v4l2rtspserver -F 15 --rotation 180 -W 800 -H 600 -P 8554 /dev/video0
# 沒有支援旋轉鏡頭參數的指令,也可以用以下的指令:
$ v4l2-ctl --set-ctrl vertical_flip=1
### ex7-4 (7-1-app-hello.py) ###
from flask import Flask
app = Flask(__name__) # flask 才會知道你的 root 在何處
@app.route("/") # 定義路由路徑,/ 指的是 web root (URL)
def index(): # 一個接著要執行的 function。
return "Hello Flask"
if __name__ == "__main__": # 是直接運行的才會執行 app.run() 這個方法
app.run(host = '0.0.0.0', port = 80, debug = True)
### ex7-5 ###
# 查找哪一個 python 程序正在執行中
$ ps -fA | grep python
# 刪除 root 占用的程序
$ sudo kill -9 PID
### ex7-6 (7-2-app-route.py) ###
from flask import Flask, render_template, Response
app = Flask(__name__)
@app.route("/")
def index():
return render_template('link.html') # View 可由自訂的樣板產生
@app.route("/foo")
def foo():
extns = ['Flask', 'Jinja2', 'Awesome'] # 樣板內可塞變數
return render_template('bar.html', extns = extns)
if __name__ == "__main__":
app.run(host = '0.0.0.0', port = 80, debug = True)
### ex7-7 ###
# 新增一個資料夾 templates,與一個網頁檔 link.html
$ mkdir templates
$ nano templates/link.html
# link.html 的內容
Hello Template
foo
# 新增一個 bar.html
$ nano templates/bar.html
# bar.html 的內容
{% for ext in extns %}
- {{ ext }}
{% endfor %}
### ex7-8 (stream_pi.py) ###
from time import time
class Camera(object):
def __init__(self):
self.frames = [open("static/" + f + '.jpg', 'rb').read() for f in ['1', '2', '3']]
def get_frame(self):
return self.frames[int(time()) % 3]
### ex7-9 (7-3-app-stream.py) ###
from flask import Flask, render_template, Response
from stream_pi import Camera
app = Flask(__name__)
@app.route('/')
def index():
return render_template('stream.html')
def gen(camera):
while True:
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(Camera()),
mimetype = 'multipart/x-mixed-replace; boundary = frame')
if __name__ == "__main__":
app.run(host = '0.0.0.0', port = 80, debug = True)
### ex7-10 ###
# 新增一個 stream.html
$ nano templates/stream.html
# stream.html 的內容
Hello Stream
### ex7-11 (7-4-app-camera.py) ###
from flask import Flask, render_template, Response
from camera_pi import Camera
app = Flask(__name__)
@app.route('/')
def index():
return render_template('stream.html')
def gen(camera):
while True:
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(Camera()),
mimetype = 'multipart/x-mixed-replace; boundary = frame')
if __name__ == "__main__":
app.run(host = '0.0.0.0', port = 80, debug = True)
### ex7-12 (camera_pi.py) ###
import cv2
class Camera(object):
def __init__(self):
if cv2.__version__.startswith('2'):
PROP_FRAME_WIDTH = cv2.cv.CV_CAP_PROP_FRAME_WIDTH
PROP_FRAME_HEIGHT = cv2.cv.CV_CAP_PROP_FRAME_HEIGHT
elif cv2.__version__.startswith('3'):
PROP_FRAME_WIDTH = cv2.CAP_PROP_FRAME_WIDTH
PROP_FRAME_HEIGHT = cv2.CAP_PROP_FRAME_HEIGHT
else:
PROP_FRAME_WIDTH = cv2.CAP_PROP_FRAME_WIDTH
PROP_FRAME_HEIGHT = cv2.CAP_PROP_FRAME_HEIGHT
self.video = cv2.VideoCapture(0)
#self.video = cv2.VideoCapture(1)
#self.video.set(PROP_FRAME_WIDTH, 640)
#self.video.set(PROP_FRAME_HEIGHT, 480)
self.video.set(PROP_FRAME_WIDTH, 320)
self.video.set(PROP_FRAME_HEIGHT, 240)
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tostring()