今回はWebのプレビュー画面から動画の撮影を行いたいと思います。
赤丸のボタンを設置し、押すと録画開始、もう一度押すと録画停止という感じです。
まずはサーバ側。
すでに動画を撮影する方法は知っているので、これを使用します。
POSTリクエストを受け付ける処理を書いていきます。
def do_POST(self):
global thread
global aviFilename
global capture
global out
content_len = int(self.headers.get('content-length'))
requestBody = json.loads(self.rfile.read(content_len).decode('utf-8'))
if requestBody['contents']['command'] == 1:
_, img = cap.read()
dt_now = datetime.datetime.now()
filename = dt_now.strftime('%Y%m%d_%H%M%S')+".jpg"
cv2.imwrite(filename, img)
response = {
'status' : 200,
'path': "http://pi4.local:8000/" + filename
}
if requestBody['contents']['command'] == 2:
dt_now = datetime.datetime.now()
aviFilename = dt_now.strftime('%Y%m%d_%H%M%S')+".avi"
out = cv2.VideoWriter(aviFilename, fourcc, 20.0, (640,480))
capture = True
thread = threading.Thread(target=videoCapture)
thread.start()
response = {
'status' : 200,
}
if requestBody['contents']['command'] == 3:
capture = False
thread.join()
out.release()
out = None
response = {
'status' : 200,
'path': "http://pi4.local:8000/" + aviFilename
}
else:
response = {
'status' : 200
}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
responseBody = json.dumps(response)
self.wfile.write(responseBody.encode('utf-8'))
録画開始(command=2)を受信した場合、VideoWriterを作成し、動画を保存するスレッドを起動します。
録画停止(command=3)を受信した場合は、このスレッドを停止するように動作します。
実際のスレッド処理はこんな感じです。
def videoCapture():
while capture:
_, img = cap.read()
out.write(img)
captureフラグがTrueのときは延々とカメラの映像を動画ファイルに保存します。
録画停止時にcaptureフラグをFalseに変更し、このスレッドが終了するのをjoinで待ってから、作成された動画ファイルのパスを返信します。
動画のダウンロードですが、たぶん、content-typeを用意しないと行けないので、Dictionaryに追加しています。
CONTENT_TYPE = {'.html': 'text/html; charset=utf-8', '.txt': 'text/plain; charset=utf-8', '.js': 'text/javascript', '.json': 'application/json',
'.jpeg': 'image/jpeg', '.jpg': 'image/jpeg', '.png': 'image/png', '.gif': 'image/gif',
'.css':'text/css', '.avi': 'video/x-msvideo'}
さて、このままだと録画中にブラウザを閉じてしまって、録画を止める手段が無くなってしまいます。
これの対処を次回やります。
(そろそろカメラネタも無くなってきた。)