【ラズパイ】【カメラ】WEBから動画を撮影する。

今回は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'}

さて、このままだと録画中にブラウザを閉じてしまって、録画を止める手段が無くなってしまいます。

これの対処を次回やります。

(そろそろカメラネタも無くなってきた。)