Skip to content

Instantly share code, notes, and snippets.

@rbray89
Created January 6, 2017 02:50
Show Gist options
  • Save rbray89/97c4a14d4f922eb302d76748502e39c1 to your computer and use it in GitHub Desktop.
Save rbray89/97c4a14d4f922eb302d76748502e39c1 to your computer and use it in GitHub Desktop.
Scripts and such for raspberry pi camera
#for use with mpeg.py
camera:
- platform: mjpeg
mjpeg_url: http://localhost:8500/picam.mjpg
#for use with h264.py
ffmpeg:
ffmpeg_bin: /usr/bin/ffmpeg
run_test: True
camera:
platform: ffmpeg
input: tcp://localhost:8500
name: FFmpeg
extra_arguments: -q:v 2
#! /usr/bin/python
import socket
import time
import datetime as dt
import picamera
import io
import os
import signal
import sys
import gi
#gi.require_version('GstVideo', '1.0')
#from gi.repository import GstVideo
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GstRtspServer, GObject
from threading import Thread
class CamStreamer(GstRtspServer.RTSPMediaFactory):
def __init__(self, pycam):
GstRtspServer.RTSPMediaFactory.__init__(self)
self.size = 0
self.connections = pycam.connections
self.capstring = 'video/x-'+pycam.vFormat+',width='+str(pycam.vWidth) \
+',height='+str(pycam.vHeight)+',framerate=' \
+str(pycam.vFramerate)+'/1'
self.playing = False
self.paused = False
def do_create_element(self, url):
return self.pipeline
def make_pipeline(self):
self.pipeline = Gst.parse_launch("( appsrc name=source ! h264parse ! video/x-h264,stream-format=avc ! h264parse ! video/x-h264,stream-format=byte-stream ! rtph264pay name=pay0 )")
self.appsrc = self.pipeline.get_by_name("source")
self.appsrc.set_property("is-live",True)
self.gstcaps = Gst.Caps.from_string(self.capstring)
self.appsrc.set_property("caps",self.gstcaps)
def write(self,buff):
gstbuff = Gst.Buffer.new_wrapped(buff)
ret = self.appsrc.emit("push-buffer",gstbuff)
for conn in self.connections:
try:
conn.write(buff)
except Exception as e:
print e
print '5'
if isinstance(e, KeyboardInterrupt):
sys.exit()
self.connections.remove(conn)
def flush(self):
for conn in self.connections:
try:
conn.flush()
except Exception as e:
print e
print '4'
if isinstance(e, KeyboardInterrupt):
sys.exit()
self.connections.remove(conn)
def close(self):
for conn in self.connections:
try:
conn.close()
self.connections.remove(conn)
except Exception as e:
print e
print '3'
if isinstance(e, KeyboardInterrupt):
sys.exit()
self.connections.remove(conn)
def threadedOutputFunction(pyCam):
while True:
try:
pyCam.camera.start_recording(pyCam.camStreamer, format=pyCam.vFormat, bitrate=pyCam.bitrate)
frameCount = 0
while True:
if frameCount == 10:
pyCam.camera.capture('/tmp/picamstill.jpg', use_video_port=True)
frameCount = 0
pyCam.camera.wait_recording(.2)
pyCam.camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
frameCount += 1
except Exception as e:
print e
print '2'
if isinstance(e, KeyboardInterrupt):
sys.exit()
def threadedRTSP(mainloop):
mainloop.run()
class PyCam():
def __init__(self):
self.connections = [ ]
self.vHeight = 480
self.vWidth = 640
self.bitrate = 1000000
self.vFramerate = 24
self.vFormat = 'h264'
self.camStreamer = CamStreamer(self)
self.mainloop = GObject.MainLoop()
self.rtspServer = GstRtspServer.RTSPServer()
self.camStreamer.set_shared(True)
self.mounts = self.rtspServer.get_mount_points()
self.mounts.add_factory("/picam",self.camStreamer)
self.rtspServer.attach(None)
def run(self):
rtspLoop = Thread(target = threadedRTSP, args = (self.mainloop,))
rtspLoop.start()
self.camera = picamera.PiCamera()
self.camera.resolution = (self.vWidth, self.vHeight)
self.camera.framerate = self.vFramerate
self.camera.hflip = self.camera.vflip = True
camThread = Thread(target = threadedOutputFunction, args = (self,))
camThread.start()
while True:
try:
self.serverSocket = socket.socket()
self.serverSocket.bind(('localhost', 8500))
self.serverSocket.listen(3)
while True:
self.connections.append(self.serverSocket.accept()[0].makefile('wb'))
except Exception as e:
print e
print '1'
if isinstance(e, KeyboardInterrupt):
self.camera.stop_recording()
self.serverSocket.close()
sys.exit()
time.sleep(5)
Gst.init(None)
app = PyCam()
app.run()
#! /usr/bin/python
import socket
import time
import datetime as dt
import picamera as piCamera
import io
import os
import signal
import sys
import gi
from multiprocessing import Queue
#gi.require_version('GstVideo', '1.0')
#from gi.repository import GstVideo
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
from SocketServer import ThreadingMixIn
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GstRtspServer, GObject
from threading import Thread
picamera = None
httpConnections = []
class CamHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path.endswith('.mjpg'):
self.send_response(200)
self.send_header('Content-type','multipart/x-mixed-replace; boundary=--jpgboundary')
self.end_headers()
mjpegQueue = Queue(6)
try:
start=time.time()
httpConnections.append(mjpegQueue)
while True:
mjpegStream = mjpegQueue.get(True)
self.wfile.write("--jpgboundary")
self.send_header('Content-type','image/jpeg')
self.send_header('Content-length',len(mjpegStream))
self.end_headers()
self.wfile.write(mjpegStream)
except (socket.error, socket.timeout) as e:
httpConnections.remove(mjpegQueue)
return
else:
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write("""<html><head></head><body>
<img src="/cam.mjpg"/>
</body></html>""")
return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
class CamStreamer(GstRtspServer.RTSPMediaFactory):
def __init__(self, pycam):
GstRtspServer.RTSPMediaFactory.__init__(self)
self.size = 0
self.capstring = 'video/x-'+pycam.vFormat+',width='+str(pycam.vWidth) \
+',height='+str(pycam.vHeight)+',framerate=' \
+str(pycam.vFramerate)+'/1'
self.playing = False
self.paused = False
self.appsrc = None
def do_create_element(self, url):
self.pipeline = Gst.parse_launch("( appsrc name=source ! h264parse ! video/x-h264,stream-format=avc ! h264parse ! video/x-h264,stream-format=byte-stream ! rtph264pay name=pay0 )")
self.appsrc = self.pipeline.get_by_name("source")
self.appsrc.set_property("is-live",True)
self.gstcaps = Gst.Caps.from_string(self.capstring)
self.appsrc.set_property("caps",self.gstcaps)
return self.pipeline
def write(self,buff):
if self.appsrc != None:
try:
gstbuff = Gst.Buffer.new_wrapped(buff)
ret = self.appsrc.emit("push-buffer",gstbuff)
except Exception as e:
print e
if isinstance(e, KeyboardInterrupt):
sys.exit()
def flush(self):
print 'flushing...'
def close(self):
print 'closing...'
def threadedOutputFunction(pyCam):
while True:
try:
picamera.start_recording(pyCam.camStreamer, format=pyCam.vFormat, bitrate=pyCam.bitrate)
# frameCount = 0
while True:
# if frameCount == 10:
# picamera.capture('/tmp/picamstill.jpg', use_video_port=True)
# frameCount = 0
picamera.wait_recording(.2)
picamera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# frameCount += 1
except Exception as e:
print e
print '2'
if isinstance(e, KeyboardInterrupt):
sys.exit()
def threadedMjpegOutputFunction():
while True:
stream = io.BytesIO()
for foo in picamera.capture_continuous(stream,'jpeg', use_video_port=True):
for queue in httpConnections:
try:
queue.put_nowait(stream.getvalue())
except Exception as e:
if isinstance(e, KeyboardInterrupt):
sys.exit()
stream.seek(0)
stream.truncate()
time.sleep(.2)
def threadedRTSP(mainloop):
mainloop.run()
class PyCam():
def __init__(self):
self.vHeight = 480
self.vWidth = 640
self.bitrate = 1000000
self.vFramerate = 24
self.vFormat = 'h264'
self.camStreamer = CamStreamer(self)
self.mainloop = GObject.MainLoop()
self.rtspServer = GstRtspServer.RTSPServer()
self.camStreamer.set_shared(True)
self.mounts = self.rtspServer.get_mount_points()
self.mounts.add_factory("/picam",self.camStreamer)
self.rtspServer.attach(None)
def run(self):
global picamera
rtspLoop = Thread(target = threadedRTSP, args = (self.mainloop,))
rtspLoop.start()
picamera = piCamera.PiCamera()
picamera.resolution = (self.vWidth, self.vHeight)
picamera.framerate = self.vFramerate
picamera.hflip = picamera.vflip = True
camThread = Thread(target = threadedOutputFunction, args = (self,))
camThread.start()
mjpgThread = Thread(target = threadedMjpegOutputFunction)
mjpgThread.start()
try:
server = ThreadedHTTPServer(('',8500), CamHandler)
server.serve_forever()
except Exception as e:
print e
print '1'
if isinstance(e, KeyboardInterrupt):
picamera.stop_recording()
self.serverSocket.close()
sys.exit()
Gst.init(None)
app = PyCam()
app.run()
[Unit]
Description=Raspberry Pi Camera
After=network.target
Before=home-assistant.service
[Service]
Type=simple
User=hass
ExecStart=/service/picam/run.py
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment