Mercurial > code > home > repos > light9
changeset 1955:9ee42b88299b
vidref now has some stats
Ignore-this: ef1184d85c09bead29fb4d1f2245f180
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Thu, 06 Jun 2019 02:56:46 +0000 |
parents | 3ae1e7f8db23 |
children | ec816fd31c83 |
files | bin/vidref light9/vidref/videorecorder.py |
diffstat | 2 files changed, 43 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/bin/vidref Thu Jun 06 02:28:28 2019 +0000 +++ b/bin/vidref Thu Jun 06 02:56:46 2019 +0000 @@ -27,6 +27,8 @@ from rdfdb.syncedgraph import SyncedGraph from cycloneerr import PrettyErrorHandler from typing import cast +from greplin import scales +from greplin.scales.cyclonehandler import StatsHandler parser = optparse.OptionParser() parser.add_option("-v", "--verbose", action="store_true", help="logging.DEBUG") @@ -34,7 +36,13 @@ log.setLevel(logging.DEBUG if options.verbose else logging.INFO) - +stats = scales.collection( + '/webServer', + scales.RecentFpsStat('liveWebsocketFrameFps'), + scales.IntStat('liveClients'), + +) + class Snapshot(cyclone.web.RequestHandler): @defer.inlineCallbacks @@ -68,13 +76,17 @@ def connectionMade(self, *args, **kwargs): pipeline.liveImages.subscribe(on_next=self.onFrame) + stats.liveClients += 1 def connectionLost(self, reason): - 0 #self.subj.dispose() + #self.subj.dispose() + stats.liveClients -= 1 def onFrame(self, cf: videorecorder.CaptureFrame): if cf is None: return + stats.liveWebsocketFrameFps.mark() + self.sendMessage( json.dumps({ 'jpeg': base64.b64encode(cf.asJpeg()).decode('ascii'), @@ -108,8 +120,9 @@ def get(self): song = Song(self.get_argument('song')) clips = [] - for vid in glob.glob(os.path.join(videorecorder.songDir(song), - b'*.mp4')): + videoPaths = glob.glob(os.path.join(videorecorder.songDir(song), + b'*.mp4')) + for vid in videoPaths: pts = [] for line in open(vid.replace(b'.mp4', b'.timing'), 'rb'): _v, vt, _eq, _song, st = line.split() @@ -159,6 +172,10 @@ "path": 'todo', }), (r'/time', Time), + (r'/stats/(.*)', StatsHandler, { + 'serverName': 'vidref' + }), + ], debug=True, ))
--- a/light9/vidref/videorecorder.py Thu Jun 06 02:28:28 2019 +0000 +++ b/light9/vidref/videorecorder.py Thu Jun 06 02:56:46 2019 +0000 @@ -14,6 +14,7 @@ from rdflib import URIRef import moviepy.editor import numpy +from greplin import scales from light9.ascoltami.musictime_client import MusicTime from light9.newtypes import Song @@ -21,6 +22,16 @@ log = logging.getLogger() +stats = scales.collection( + '/recorder', + scales.PmfStat('jpegEncode', recalcPeriod=1), + scales.IntStat('deletes'), + scales.PmfStat('waitForNextImg', recalcPeriod=1), + scales.PmfStat('crop', recalcPeriod=1), + scales.RecentFpsStat('encodeFrameFps'), + scales.RecentFpsStat('queueGstFrameFps'), + +) @dataclass class CaptureFrame: @@ -30,6 +41,7 @@ isPlaying: bool imgJpeg: Optional[bytes] = None + @stats.jpegEncode.time() def asJpeg(self): if not self.imgJpeg: output = BytesIO() @@ -57,6 +69,7 @@ path = '/'.join([w[0], w[1], 'video', f'light9.bigasterisk.com_{w[0]}_{w[1]}_{w[2]}', w[3]]) log.info(f'deleting {uri} {path}') + stats.deletes += 1 for fn in [path + '.mp4', path + '.timing']: os.remove(fn) @@ -156,6 +169,7 @@ def _bg_make_frame(self, video_time_secs): + stats.encodeFrameFps.mark() if self.nextWriteAction == 'close': raise StopIteration # the one in write_videofile elif self.nextWriteAction == 'notWritingClip': @@ -166,8 +180,10 @@ raise NotImplementedError(self.nextWriteAction) # should be a little queue to miss fewer frames + t1 = time.time() while self.nextImg is None: time.sleep(.015) + stats.waitForNextImg = time.time() - t1 cf, self.nextImg = self.nextImg, None self.frameMap.write(f'video {video_time_secs:g} = song {cf.t:g}\n') @@ -221,12 +237,13 @@ 'RGB', (caps.get_structure(0).get_value('width'), caps.get_structure(0).get_value('height')), mapinfo.data) - img = img.crop((0, 100, 640, 380)) + img = self.crop(img) finally: buf.unmap(mapinfo) # could get gst's frame time and pass it to getLatest latest = self.musicTime.getLatest() if 'song' in latest: + stats.queueGstFrameFps.mark() self.liveImages.on_next( CaptureFrame(img=img, song=Song(latest['song']), @@ -236,6 +253,10 @@ traceback.print_exc() return Gst.FlowReturn.OK + @stats.crop.time() + def crop(self, img): + return img.crop((0, 100, 640, 380)) + def setupPipelineError(self, pipe, cb): bus = pipe.get_bus()