0

I am currently doing this project of streaming a live video into a localhost and then capturing an image after button click using a picamera. Here is my code:

For streaming:

import io
import picamera
import logging
import socketserver
from threading import Condition
from http import server
import threading, os, signal
import subprocess
from subprocess import check_call, call
import sys

ipath = "/home/pi/10-20-19/capture.py"    #CHANGE PATH TO LOCATION OF capture.py

def thread_second():
    call(["python3", ipath])

def check_kill_process(pstring):
    for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"):
        fields = line.split()
        pid = fields[0]
        os.kill(int(pid), signal.SIGKILL)

PAGE="""\
<html>
<head>
<title>The Bell</title>
</head>
<body>
<center><h1>Live Camera Feedback</h1></center>
<center><img src="stream.mjpg" width="640" height="480" /></center>
</body>
</html>
"""

class StreamingOutput(object):
    def __init__(self):
        self.frame = None
        self.buffer = io.BytesIO()
        self.condition = Condition()

    def write(self, buf):
        if buf.startswith(b'\xff\xd8'):
            # New frame, copy the existing buffer's content and notify all
            # clients it's available
            self.buffer.truncate()
            with self.condition:
                self.frame = self.buffer.getvalue()
                self.condition.notify_all()
            self.buffer.seek(0)
        return self.buffer.write(buf)

class StreamingHandler(server.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.send_response(301)
            self.send_header('Location', '/index.html')
            self.end_headers()
        elif self.path == '/index.html':
            content = PAGE.encode('utf-8')
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.send_header('Content-Length', len(content))
            self.end_headers()
            self.wfile.write(content)
        elif self.path == '/stream.mjpg':
            self.send_response(200)
            self.send_header('Age', 0)
            self.send_header('Cache-Control', 'no-cache, private')
            self.send_header('Pragma', 'no-cache')
            self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
            self.end_headers()
            try:
                while True:
                    with output.condition:
                        output.condition.wait()
                        frame = output.frame
                    self.wfile.write(b'--FRAME\r\n')
                    self.send_header('Content-Type', 'image/jpeg')
                    self.send_header('Content-Length', len(frame))
                    self.end_headers()
                    self.wfile.write(frame)
                    self.wfile.write(b'\r\n')
            except Exception as e:
                logging.warning(
                    'Removed streaming client %s: %s',
                    self.client_address, str(e))
        else:
            self.send_error(404)
            self.end_headers()
class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
    allow_reuse_address = True
    daemon_threads = True

with picamera.PiCamera(resolution='640x480', framerate=24) as camera:
    output = StreamingOutput()
    camera.rotation = 180 
    camera.start_recording(output, format='mjpeg')
    try:
        address = ('', 8000)
        server = StreamingServer(address, StreamingHandler)
        print("Streaming..")
        check_kill_process("capture.py")
        processThread = threading.Thread(target=thread_second)
        processThread.start()
        print("Waiting for button press..")
        server.serve_forever()

    finally:
        print("ERROR: Stream not able to run. Stream ended.")
        camera.stop_recording()


# print in the command line instead of file's console
if __name__ == '__main__':   
    main()

For capturing image:

import io
import threading, os, signal
import picamera
import logging
import socketserver
from select import select
from threading import Condition
from http import server
import datetime as dt
import subprocess
from subprocess import check_call, call
import sys
import glob

from gpiozero import Button, Buzzer 
from time import sleep
from mail import send_an_email, start_SMTP, quit_SMTP

ipath = "/home/pi/10-20-19/main.py"    #CHANGE THIS PATH TO THE LOCATION OF main.py

def thread_second():
    call(["python3", ipath])

def check_kill_process(pstring):
    for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"):
        fields = line.split()
        print(fields)
        pid = fields[0]
        print(pid)
        os.kill(int(pid), signal.SIGKILL)

button = Button (27)

start_SMTP()
while True:
    try:
        # wait for button press
        button.wait_for_press()

        # alert button pressed
        print('Button is pressed..')

        # end livestream
        check_kill_process('main.py')
        print("Stream ended..")

        # get last image number in usb drive
        pictures = glob.glob('/home/pi/10-20-19/*.jpg')     #CHANGE PATH TO YOUR IMAGE PATH
        pictures.sort()
        print(pictures)

        # default picture number to zero
        picNum = 0
        limit = 20

        # determine the picture number
        if not pictures == []:
            numPics = len(pictures)
            print(numPics)
            lastPic = pictures[numPics-1]
            print(lastPic)
            lastPicData = lastPic.split('/')
            sudoLen = len(lastPicData)
            jpgFile = lastPicData[sudoLen-1]
            jpgData = jpgFile.split('.')
            picNum = jpgData[0]
            picNum = int(picNum) + 1
            print(picNum)
#             pictures.sort(reverse=True)
            lastPic = pictures[0]
            print(lastPic)
            if numPics > limit-1:
                os.remove(lastPic)
        else:
            picNum = 1

        # capture image
        with picamera.PiCamera() as camera:
            camera.rotation = 180

            # annotate text to video
            camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d     %H:%M:%S')
            camera.annotate_text_size = 25

            camera.capture('/home/pi/10-20-19/' + str(picNum) + '.jpg', quality=13)

        # alert picture taken
        print('Picture taken..')

        # send an email
        image = str(picNum) + '.jpg'
        send_an_email(image)

        # run live stream again
        processThread = threading.Thread(target=thread_second)
        processThread.start()
        print("Stream running. Refresh page.")
    except KeyboardInterrupt:
        quit_SMTP()
        break

# print in the command line instead of file's cons
if __name__ == '__main__':
    main()

I do also have the script for sending email but I don't think it's relevant to my problem. What I aim to do is stream video with the option to record a clip of it and save it internally without ending the stream. As far as I know, it is possible. But I just can't find enough reference to start it.

For this question, I would simply like to know how to record the stream after running the main.py? I should be able to work it out into having an option to record at a specific time in the web page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.