Skip to content

Instantly share code, notes, and snippets.

@Climax777
Last active March 18, 2021 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Climax777/e051628b9ce08e4b009aa750cb1bf104 to your computer and use it in GitHub Desktop.
Save Climax777/e051628b9ce08e4b009aa750cb1bf104 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import sys, os, _thread, time, glob, shutil
import gi
import concurrent.futures
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib
outpath = '/mnt/flash/SecuvueFootage'
unitcameras = [
('SV02-00059/00:07:32:61:a6:84', [
'00:00:1b:07:43:bd_0',
'00:00:1b:07:63:b5_0',
'00:00:1b:07:63:b9_0',
'00:00:1b:07:63:bf_0',
'00:00:1b:07:63:c3_0',
'00:00:1b:07:63:fc_0',
'00:00:1b:07:65:00_0',
'00:00:1b:19:5d:36_0',
'00:00:1b:19:5e:37_0',
'00:00:1b:19:5e:4e_0',
'00:00:1b:19:5f:5b_0'
]),
('SV02-00060/00:07:32:61:a6:1d', [
'00:00:1b:07:43:ab_0',
'00:00:1b:07:63:b7_0',
'00:00:1b:07:63:c6_0',
'00:00:1b:07:63:d2_0',
'00:00:1b:07:63:e8_0',
'00:00:1b:07:63:ef_0',
'00:00:1b:07:63:f6_0',
'00:00:1b:07:63:f8_0',
'00:00:1b:07:64:8f_0',
'00:00:1b:19:5e:4e_0',
'de:00:c4:c6:1c:f6_0',
'ee:d6:7c:3f:1c:67_0'
]),
('SV02-00061/00:07:32:61:4e:14', [
'00:00:1b:07:41:4b_0',
'00:00:1b:07:41:eb_0',
'00:00:1b:07:63:b2_0',
'00:00:1b:07:63:d5_0',
'00:00:1b:07:63:d9_0',
'00:00:1b:07:63:da_0',
'00:00:1b:07:63:e5_0',
'00:00:1b:19:5a:a4_0',
'00:00:1b:19:5d:36_0',
'00:00:1b:19:5f:4d_0',
'1c:c3:16:25:b9:2a',
'1c:c3:16:25:b9:40'
]),
('SV02-00062/00:07:32:61:4e:1c', [
'00:00:1b:07:41:56_0',
'00:00:1b:07:41:eb_0',
'00:00:1b:07:43:22_0',
'00:00:1b:07:49:e5_0',
'00:00:1b:07:63:ce_0',
'00:00:1b:07:63:d4_0',
'00:00:1b:07:63:eb_0',
'00:00:1b:19:5f:5b_0',
'00:00:1b:19:61:32_0',
'00:00:1b:20:74:a6_0',
'1c:c3:16:26:75:10'
]),
]
namemap = {
"00:00:1b:07:63:bf": "Banking Hall",
"00:00:1b:07:63:b5": "Camera Behind Tellers 1",
"00:00:1b:19:5d:36": "ATM Pinhole 3",
"00:00:1b:19:5e:37": "Client Entrance Pinhole",
"00:00:1b:19:5e:4e": "ATM Pinhole 1",
"00:00:1b:07:63:c3": "Camera Sales Consultants",
"00:00:1b:07:63:b9": "Treasury BCTU",
"00:00:1b:07:43:bd": "Overlooking ATM Left",
"00:00:1b:07:63:c6": "ATM overlooking Drop Safe",
"00:00:1b:07:63:f8": "Overlooking Tellers",
"00:00:1b:07:63:ef": "Treasuary Overview",
"00:00:1b:07:63:d2": "ATM Line Trip Top View",
"de:00:c4:c6:1c:f6": "ATM Pinhole 2",
"00:00:1b:07:63:fc": "Client Entry Line Trip",
"00:00:1b:19:5f:5b": "Pole Pinhole",
"00:00:1b:07:43:ab": "ATMs and Door Overview",
"00:00:1b:07:64:8f": "Bulk Teller Drop Safe",
"00:00:1b:07:63:f6": "Sales Consultants",
"00:00:1b:07:63:b7": "Behind Tellers Drop Safe",
"00:00:1b:07:41:4b": "ATM Safes and Door",
"00:00:1b:07:63:d9": "Treasury Coin and Note Safes",
"00:00:1b:07:63:da": "Bulk Teller",
"00:00:1b:07:63:e5": "Camera Behind Tellers 3",
"00:00:1b:07:63:b2": "Bulk Teller Client Area",
"00:00:1b:07:63:d5": "Treasury Lobby",
"1c:c3:16:25:b9:2a": "Fish eye Front Banking Hall",
"1c:c3:16:25:b9:40": "Fish eye Back Banking Hall",
"00:00:1b:19:5f:4d": "Client Exit Pinhole",
"00:00:1b:19:5a:a4": "Small Foot Exit Pinhole",
"00:00:1b:07:41:56": "Kitchen and Emergency Exit",
"00:00:1b:07:43:22": "Intel Cab Overview",
"1c:c3:16:26:75:10": "Banking Hall 180 degree",
"00:00:1b:20:74:a6": "3rd Man BCTU Area",
"00:00:1b:07:63:ce": "Treasury Counting Table",
"00:00:1b:07:63:e8": "Camera Behind Tellers 2",
"00:00:1b:07:49:e5": "Client Emergency Exit",
"00:00:1b:07:63:eb": "Treasury Passageway (Drop Safe of Tellers)",
"00:00:1b:07:63:d4": "Treasury Passageway (Drop Safe of Bulk)",
"00:00:1b:19:61:32": "Small Foot Entrance Pinhole",
"00:00:1b:07:41:eb": "Overlooking ATM Right",
"00:00:1b:07:65:00": "Generator"
}
def findCameraName(camid):
for key in namemap.keys():
if camid.find(key) != -1:
return namemap[key]
return None
tmpdir = '/tmp/secuvue_reports/'
def copyfile(filename):
shutil.copy(filename, tmpdir)
print('File copy: ', filename)
basevideopath = '/mnt/secuvue/nas/localstorage'
datestart = "2020/01-January/16-Thursday"
dateglobs = [
"07h/50-59min/*.mp4",
"08h/**/*.mp4",
"09h/00-09min/*.mp4",
"09h/10-19min/*.mp4",
"09h/20-29min/*.mp4",
"09h/30-39min/*.mp4"
]
class my_main:
def __init__(self):
return
def start(self):
# Set up the gstreamer pipeline
for unit in unitcameras:
for camera in unit[1]:
if findCameraName(camera) is None:
print('Camera not in list')
continue
filepath = outpath + '/ABSA Southdale ' + findCameraName(camera) + '.mkv'
print('\n\n\n\nCombining footage for ', findCameraName(camera))
filelist = []
for dateglob in dateglobs:
globpattern = basevideopath + '/' + unit[0] + '/' + camera + '/' + datestart + '/' + dateglob
print('Testing: ', globpattern)
filelist += (glob.glob(globpattern, recursive=True))
if len(filelist) == 0:
print('No footage')
continue
filelist.sort()
shutil.rmtree(tmpdir, ignore_errors=True)
os.makedirs(tmpdir)
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
future_to_url = {executor.submit(copyfile, filename): filename for filename in filelist}
concurrent.futures.wait(future_to_url)
filelist = glob.glob(tmpdir + '*.mp4')
filelist.sort()
print('Building pipe')
self.player = Gst.parse_launch ("""splitmuxsrc name="demux" ! matroskamux ! filesink location="{}" sync=false""".format(filepath))
demuxer = self.player.get_by_name("demux")
demuxer.connect("format_location", lambda mux : filelist)
bus = self.player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect("message", self.on_message)
print('Starting pipe')
self.player.set_state(Gst.State.PLAYING)
while self.player != None:
time.sleep(1)
loop.quit()
def on_message(self, bus, message):
t = message.type
if t == Gst.MessageType.EOS:
if self.player is not None:
self.player.set_state(Gst.State.NULL)
self.player = None
print("EOS... ")
elif t == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print("Error: %s" % err, debug)
if self.player is not None:
self.player.set_state(Gst.State.NULL)
self.player = None
elif t == Gst.MessageType.STATE_CHANGED:
state = message.parse_state_changed()[1]
print("State: ", state)
Gst.init(None)
mainclass = my_main()
_thread.start_new_thread(mainclass.start, ())
loop = GLib.MainLoop()
loop.run()
shutil.rmtree(tmpdir, ignore_errors=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment