Last active
March 18, 2021 18:45
-
-
Save Climax777/e051628b9ce08e4b009aa750cb1bf104 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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