Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import io 

2import time 

3import threading 

4from logging import getLogger 

5from PIL import Image 

6 

7 

8class screencast(threading.Thread): 

9 def __init__(self, drvobj, crop, interval=1.0, thumbnail=None): 

10 super().__init__() 

11 self.drvobj = drvobj 

12 if crop is None: 

13 self.crop = crop 

14 else: 

15 self.crop = tuple(crop) 

16 self.thumbnail = thumbnail 

17 self.log = getLogger(self.name) 

18 self.stop = False 

19 self.interval = interval 

20 self.frames = [] 

21 

22 def run(self): 

23 self.start_ts = time.time() 

24 while not self.stop: 

25 t1 = time.time() 

26 with self.drvobj.lock: 

27 p = self.drvobj.saveshot() 

28 self.log.info("shot: %d bytes, %f sec", len(p), time.time() - t1) 

29 if len(p) != 0: 

30 img = Image.open(io.BytesIO(p)) 

31 if self.crop is not None: 

32 self.log.info("crop %s, %f sec", self.crop, time.time() - t1) 

33 img = img.crop(self.crop) 

34 if self.thumbnail is not None: 

35 img.thumbnail(self.thumbnail, Image.ANTIALIAS) 

36 self.frames.append(img) 

37 td = time.time() - t1 

38 if self.interval is not None and self.interval > td: 

39 self.log.info("sleep %f - %f", self.interval, td) 

40 time.sleep(self.interval - td) 

41 self.finished_ts = time.time() 

42 

43 def savefile(self, output_fn, optimize=False, loop=0, speed=1.0): 

44 if len(self.frames) == 0: 

45 raise Exception("no image found") 

46 d = 1000 * (self.finished_ts - self.start_ts) / len(self.frames) / speed 

47 self.log.info("%d frames, %d sec. duration=%f(ms)", len( 

48 self.frames), self.finished_ts - self.start_ts, d) 

49 self.frames[0].save(output_fn, save_all=True, duration=d, optimize=optimize, 

50 loop=loop, append_images=self.frames[1:]) 

51 

52 

53scr_th = None 

54 

55 

56def Base_screencast(self, param): 

57 """ 

58 - name: start screencast 

59 screencast: 

60 interval: 0.5 

61 thumbnail: [100, 100] 

62 - name: sleep 

63 sleep: 3 

64 - name: save screencast 

65 screencast: output.gif 

66 """ 

67 global scr_th 

68 if isinstance(param, dict) and "output" not in param: 

69 if scr_th is not None: 

70 raise Exception("screencast already working") 

71 scr_th = screencast(self, param.get("crop"), param.get("interval"), 

72 param.get("thumbnail")) 

73 scr_th.start() 

74 return "started" 

75 if scr_th is None: 

76 raise Exception("screencast is not working") 

77 self.log.debug("stop cast") 

78 scr_th.stop = True 

79 scr_th.join(2) 

80 if scr_th.is_alive(): 

81 self.log.warn("cannot stop screencast thread.") 

82 else: 

83 self.log.debug("done join. saving") 

84 if isinstance(param, str): 

85 self.log.info("save to %s", param) 

86 scr_th.savefile(param) 

87 elif isinstance(param, dict): 

88 output = param.get("output") 

89 assert output is not None 

90 self.log.info("save to %s", output) 

91 scr_th.savefile(output, 

92 optimize=param.get("optimize", False), 

93 loop=param.get("loop", 0), 

94 speed=param.get("speed", 1.0)) 

95 scr_th = None 

96 return "finished"