Raspberry Pi 3 B as a Camera Capture – Day and Night – Python 3

A basic python 3 script to capture wide angle video 24/7 and convert from h.264 raw video to MP4 videos every 60 seconds. Setup a time threshold for Day and Night settings. You may have to adjust based on sunrise/sunset. Good starting point if you are learning about raspberry pi, camera and motion video.

Components used:

  • Raspberry Pi 3B.

  • Seeed Studio Wide Angle Camera.

  • Python 3.5.3.

  • rclone to copy to OneDrive ( You have to setup Beta version of rclone first because it needs to trust rclone and onedrive settings).

  • Apache running as pi/pi so I can browse the files once captured.

  • Uses multiprocessing for parallel capture and conversion to avoid breaks in video capture.

  • Much trial and error so some of the comments may not make sense. If you do use it and you get stuck give me a shout.

Code to run:

…………………………………………………………..


#rpi3b-app-svr-20190410-1.8.py

#Captures video and rotates - Python3

#using the Seeed Studio fisheye camera

###Test sub threads

#import threading

import multiprocessing

import logging

import time

import os

import datetime

from datetime import timedelta

from shutil import rmtree#used to delete files and dirs

###import for running cmd apps

import subprocess

import pathlib #used for creating directory

#log file paths

PATH = '/home/pi/python-scripts/alarm/logs/'

tempCollectFileSizeInt = 0

tempCollectFileSizeCompare = 0

previousTempCollectFileSizeInt = 0

previousTempFileNameMp4Path = " "

fisheyeCamMp4SavePath=""

fisheyeCamH264SavePath=""

fileNameH264Path=""

fileNameMp4Path=""

#Define a function

def convertDay(fisheyeCamMp4SavePath,fisheyeCamH264SavePath):

#Delete raw h264 file command

fisheyeCamCommandDeleteH264 = 'sudo rm -Rf ' + fisheyeCamH264SavePath

#print("Day Daemon")

#print(fisheyeCamH264SavePath)

#print(fisheyeCamMp4SavePath)

time.sleep(1)

#Convert from h264 to mp4 - sudo apt-get install gpac

fisheyeCamCommandConvertH264Mp4 = 'sudo MP4Box -fps 30 -add ' + fisheyeCamH264SavePath+ ' ' + fisheyeCamMp4SavePath

#run raspivid command

outputFisheyeCamConvertH264Mp4Result = subprocess.getoutput(fisheyeCamCommandConvertH264Mp4)

time.sleep(1)

#run h264 file delete command

outputFisheyeCamDeleteH264Result = subprocess.getoutput(fisheyeCamCommandDeleteH264)

#Command to run rclone and sync with OneDrive

rcloneCommand = '/usr/bin/rclone -v copy '+fisheyeCamMp4SavePath+' onedrive:Documents/Personal/pi-cam/fisheye/'+now.strftime("%Y-%m-%d")+'/'

#run rclone command

outputRcloneCommandResult = subprocess.getoutput(rcloneCommand)

#print(counter,",",tempCollectFileSize,",",fileNameMp4Path,",",now.strftime("%Y-%m-%d %H:%M:%S.%f"),file=open(PATH+"fisheye-cam-"+now.strftime("%Y-%m-%d")+".fisheye-cam.log", "a"))

def convertNight(fisheyeCamMp4SavePath,fisheyeCamH264SavePath):

#Delete raw h264 file command

fisheyeCamCommandDeleteH264 = 'sudo rm -Rf ' + fisheyeCamH264SavePath

#print("Night Daemon")

#print(fisheyeCamH264SavePath)

#print(fisheyeCamMp4SavePath)

#Convert from h264 to mp4 - sudo apt-get install gpac

fisheyeCamCommandConvertH264Mp4 = 'sudo MP4Box -fps 5 -add ' + fisheyeCamH264SavePath+ ' ' + fisheyeCamMp4SavePath

#run raspivid command

outputFisheyeCamConvertH264Mp4Result = subprocess.getoutput(fisheyeCamCommandConvertH264Mp4)

#Command to run rclone and sync with OneDrive

rcloneCommand = '/usr/bin/rclone -v copy '+fisheyeCamMp4SavePath+' onedrive:Documents/Personal/pi-cam/fisheye/'+now.strftime("%Y-%m-%d")+'/'

#run rclone command

outputRcloneCommandResult = subprocess.getoutput(rcloneCommand)

#run h264 file delete command

outputFisheyeCamDeleteH264Result = subprocess.getoutput(fisheyeCamCommandDeleteH264)

#print(counter,",",tempCollectFileSize,",",fileNameMp4Path,",",now.strftime("%Y-%m-%d %H:%M:%S.%f"),file=open(PATH+"fisheye-cam-"+now.strftime("%Y-%m-%d")+".fisheye-cam.log", "a"))

#######################

#Start of main program#

#######################

if __name__ == "__main__":

print("Starting fisheye-cam program")

###multiprocessing.log_to_stderr(logging.DEBUG)

###jobs = []

#threads.append(n)

try:

counter = 1

multiprocessing.log_to_stderr(logging.DEBUG)

jobs = []

#threads.append(n)

#while counter = 1140 or check24HourToMinutes <= 300: #check24Hour <= "06" or check24Hour = 1070 or check24HourToMinutes <= 355: #check24Hour <= "06" or check24Hour <= "6"):

try:

print("Time Check - Later than 18:15 or earlier than 05:00 ",check24Hour)

#Get time and date

now = datetime.datetime.now()

#Create full path - H264

fileNameH264 = "vid-" + now.strftime("%Y-%m-%d--%H-%M-%S-%f")+".h264"

#Create full path - MP4

fileNameMp4 = "vid-" + now.strftime("%Y-%m-%d--%H-%M-%S-%f")+".mp4"

#Create full path - h264

fileNameH264Path = "/media/usb1/fisheye-cam/videos/"+now.strftime("%Y-%m-%d")+"/"+fileNameH264

#Create full path - mp4

fileNameMp4Path = "/media/usb1/fisheye-cam/videos/"+now.strftime("%Y-%m-%d")+"/"+fileNameMp4

#Create full path - motion - mp4

fileNameMp4MotionPath = "/media/usb1/fisheye-cam/videos/"+now.strftime("%Y-%m-%d")+"/"+"motion"+"/"+fileNameMp4

#fisheyeCamImageSavePath = fileNameJpgPath

fisheyeCamH264SavePath = fileNameH264Path

fisheyeCamMp4SavePath = fileNameMp4Path

#Set to rotate video and save every 15 secs

fisheyeCamH264SegmentMs = 15000

#When set to 0 ms will go for ever

fisheyeCamH264TimeDuration = 60000

fisheyeCamH264Rotation = 0

fisheyeCamCommandH264 = 'sudo raspivid -qp 25 -ss 180000 -drc high -b 0 -v -br 60 -sh 0 -sa 0 -co 0 -ex auto -ev 10 -fps 5 -t '+str(fisheyeCamH264TimeDuration)+' -rot '+str(fisheyeCamH264Rotation)+' -a '+fileNameMp4+' -o '+fisheyeCamH264SavePath

###fisheyeCamCommandH264 = 'sudo raspivid -ss 600000 -drc high -mm matrix -b 0 -n -v -ISO auto -awb auto -sh 65 -co 65 -sa 55 -br 90 -ev 10 -ex off -fps 5 -t '+str(fisheyeCamH264TimeDuration)+' -rot '+str(fisheyeCamH264Rotation)+' -a '+fileNameMp4+' -o '+fisheyeCamH264SavePath

print("fisheyeCamCommandH264 string = "+fisheyeCamCommandH264)

#Convert from h264 to mp4 - sudo apt-get install gpac

#fisheyeCamCommandConvertH264Mp4 = 'sudo MP4Box -fps 5 -add ' + fisheyeCamH264SavePath+ ' ' + fisheyeCamMp4SavePath

#Delete raw h264 file command

#fisheyeCamCommandDeleteH264 = 'sudo rm -Rf ' + fisheyeCamH264SavePath

#Command to run rclone and sync with OneDrive

#rcloneCommand = '/usr/bin/rclone -v copy '+fisheyeCamMp4SavePath+' onedrive:Documents/Personal/pi-cam/fisheye/'+now.strftime("%Y-%m-%d")+'/'

#run raspivid command

outputFisheyeCamH264Result = subprocess.getoutput(fisheyeCamCommandH264)

n = multiprocessing.Process(name=convertNight, target=convertNight, args=(fisheyeCamMp4SavePath,fisheyeCamH264SavePath,))

###n.daemon=True

n.daemon=False

jobs.append(n)

n.start()

print('Starting:', n.name, n.pid)

#print(counter,",",tempCollectFileSize,",",fileNameMp4Path,",",now.strftime("%Y-%m-%d %H:%M:%S.%f"),file=open(PATH+"fisheye-cam-"+now.strftime("%Y-%m-%d")+".fisheye-cam.log", "a"))

counter = counter+1

except:

pass

else:

try:

print("Time Check - earler than 18:15 or later than 05:00 ",check24Hour)

#Get time and date

now = datetime.datetime.now()

#Create full path - H264

fileNameH264 = "vid-" + now.strftime("%Y-%m-%d--%H-%M-%S-%f")+".h264"

#Create full path - MP4

fileNameMp4 = "vid-" + now.strftime("%Y-%m-%d--%H-%M-%S-%f")+".mp4"

#Create full path - h264

fileNameH264Path = "/media/usb1/fisheye-cam/videos/"+now.strftime("%Y-%m-%d")+"/"+fileNameH264

#Create full path - mp4

fileNameMp4Path = "/media/usb1/fisheye-cam/videos/"+now.strftime("%Y-%m-%d")+"/"+fileNameMp4

#Create full path - motion - mp4

fileNameMp4MotionPath = "/media/usb1/fisheye-cam/videos/"+now.strftime("%Y-%m-%d")+"/"+"motion"+"/"+fileNameMp4

#fisheyeCamImageSavePath = fileNameJpgPath

fisheyeCamH264SavePath = fileNameH264Path

fisheyeCamMp4SavePath = fileNameMp4Path

#Set to rotate video and save every 15 secs

fisheyeCamH264SegmentMs = 15000

#When set to 0 ms will go for ever

fisheyeCamH264TimeDuration = 60000

fisheyeCamH264Rotation = 0

### -b 0 = variable bit rate - reduces files size dramtaically

#fisheyeCamCommandH264 = 'sudo raspivid -n -v -w 1640 -h 1232 -ISO auto -ex auto -fps 10 -t '+str(fisheyeCamH264TimeDuration)+' -rot '+str(fisheyeCamH264Rotation)+' -a '+fileNameH264+' -o '+fisheyeCamH264SavePath

fisheyeCamCommandH264 = 'sudo raspivid -b 0 -n -v -ISO auto -ex auto -fps 30 -t '+str(fisheyeCamH264TimeDuration)+' -rot '+str(fisheyeCamH264Rotation)+' -a '+fileNameMp4+' -o '+fisheyeCamH264SavePath

print("fisheyeCamCommandH264 string = "+fisheyeCamCommandH264)

#Command to run rclone and sync with OneDrive

###Disable rclone for now

###rcloneCommand = '/usr/bin/rclone -v copy '+piCamImageSavePath+' onedrive:Documents/Personal/pi-cam/timelapse/'+now.strftime("%Y-%m-%d")+'/'

#run raspivid command

outputFisheyeCamH264Result = subprocess.getoutput(fisheyeCamCommandH264)

###DEBUG DAEMON START

#threads = []

#jobs = []

#n = threading.Thread(name='convertH264Mp4Night', target=convertH264Mp4Night, daemon=True, args=(fisheyeCamMp4SavePath,fisheyeCamH264SavePath,fileNameH264Path,fileNameMp4Path,))

#multiprocessing.log_to_stderr(logging.DEBUG)

d = multiprocessing.Process(name=convertDay, target=convertDay, args=(fisheyeCamMp4SavePath,fisheyeCamH264SavePath,))

###d.daemon=True

d.daemon=False

jobs.append(d)

d.start()

#d.join()

print('Starting:', d.name, d.pid)

counter = counter+1

except:

pass

except KeyboardInterrupt:

# here you put any code you want to run before the program

# exits when you press CTRL+C

print("Keyboard Interrupt", fileNameH264Path)

print(counter,",","Keyboard Interrupt Error - Full Path: ",fileNameH264Path,",",now.strftime("%Y-%m-%d %H:%M:%S.%f"),file=open(PATH+"fisheye-cam-"+now.strftime("%Y-%m-%d")+".fisheye-cam.error.log", "a"))

file.close()

#camera.close() # this ensures a clean exit

except Exception as inst:

print("Unknown Error - Program terminated....", fileNameH264Path)

print(counter,",","Unknown Error - Program terminated.... - Full Path: ",fileNameH264Path,",",now.strftime("%Y-%m-%d %H:%M:%S.%f"),file=open(PATH+"fisheye-cam-"+now.strftime("%Y-%m-%d")+".fisheye-cam.error.log", "a"))

file.close()

print(type(inst)) # the exception instance

print(inst.args) # arguments stored in .args

print(inst) # __str__ allows args to be printed directly,

# but may be overridden in exception subclasses

x, y = inst.args # unpack args

print('x =', x)

print('y =', y)

# this catches ALL other exceptions including errors.

# You won't get any error messages for debugging

# so only use it once your code is working

#camera.close() # this ensures a clean exit

finally:

print("Finally wrapping up...", fileNameH264Path)

print(counter,",","Finally wrapping up - Full Path: ",fileNameH264Path,",",now.strftime("%Y-%m-%d %H:%M:%S.%f"),file=open(PATH+"fisheye-cam-"+now.strftime("%Y-%m-%d")+".fisheye-cam.error.log", "a"))