def get_desired_zoom_level(): blackbarcomp = None blackbarcomp_raw = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "Settings.GetSettingValue", "params": {"setting": "videoplayer.errorinaspect"}, "id": 1}' ) blackbarcomp_json = json.loads(blackbarcomp_raw) if 'result' in blackbarcomp_json: if 'value' in blackbarcomp_json['result']: blackbarcomp = int(blackbarcomp_json['result']['value']) if blackbarcomp is None: return 0 aspectratio_screen = float(xbmcgui.getScreenWidth()) / float( xbmcgui.getScreenHeight()) aspectratio_video = xbmc.RenderCapture().getAspectRatio() aspectratio_compensation = aspectratio_video - (aspectratio_video * (blackbarcomp / 100.0)) ratio_correction = (aspectratio_compensation / aspectratio_screen) zoomlevel = math.ceil(ratio_correction * 100.0) / 100.0 user_compensation = int(addon.getSetting('user_compensation')) zoomlevel = zoomlevel + (user_compensation / 100.0) maximum_zoom_level = float(1.0 + int(addon.getSetting('maximum_compensation')) / 100.0) if zoomlevel > maximum_zoom_level: zoomlevel = maximum_zoom_level return zoomlevel
def main(): settings = Settings(addon) tasmota = Tasmota(settings) capture = xbmc.RenderCapture() player = PlayerMonitor(settings=settings, capture=capture) while not xbmc.abortRequested: xbmc.sleep(settings.refreshInterval) if settings.enabled and player.isPlaying(): width = capture.getWidth() height = capture.getHeight() pixels = capture.getImage(1000) r, g, b = (0, 0, 0) if len(pixels) > 0: for y in range(height): row = width * y * 4 for x in range(width): r += pixels[row + x * 4 + 2] g += pixels[row + x * 4 + 1] b += pixels[row + x * 4] pixels_per_color = len(pixels) / 4 tasmota.sendRGB(r // pixels_per_color, g // pixels_per_color, b // pixels_per_color) else: tasmota.enablePower(False) tasmota.enablePower(False)
def __init__(self, default=EDL_COMMERCIAL_BREAK): self.videoname = None self.is_open = False self.edllist = [] self.current = {} self.default = default self.capture = xbmc.RenderCapture()
def _ambiLoop(self): cap = xbmc.RenderCapture() logger.debug("_ambiLoop started") service_enabled = cache.get("script.service.hue.service_enabled") aspect_ratio = cap.getAspectRatio() self.captureSizeY = int(self.captureSize / aspect_ratio) expected_capture_size = self.captureSize * self.captureSizeY * 4 # size * 4 bytes I guess logger.debug( "aspect_ratio: {}, Capture Size: ({},{}), expected_capture_size: {}".format(aspect_ratio, self.captureSize, self.captureSizeY, expected_capture_size)) for L in self.ambiLights: self.ambiLights[L].update(prevxy=(0.0001, 0.0001)) try: while not self.monitor.abortRequested() and self.ambiRunning.is_set(): # loop until kodi tells add-on to stop or video playing flag is unset. try: cap.capture(self.captureSize, self.captureSizeY) # async capture request to underlying OS capImage = cap.getImage() # timeout to wait for OS in ms, default 1000 if capImage is None or len(capImage) < expected_capture_size: # logger.error("capImage is none or < expected. captured: {}, expected: {}".format(len(capImage), expected_capture_size)) xbmc.sleep(250) # pause before trying again continue # no image captured, try again next iteration image = Image.frombytes("RGBA", (self.captureSize, self.captureSizeY), bytes(capImage), "raw", "BGRA", 0, 1) except ValueError: logger.error("capImage: {}".format(len(capImage))) logger.exception("Value Error") self.monitor.waitForAbort(0.25) continue # returned capture is smaller than expected when player stopping. give up this loop. except Exception as exc: logger.warning("Capture exception", exc_info=1) reporting.process_exception(exc) self.monitor.waitForAbort(0.25) continue colors = self.imageProcess.img_avg(image, self.minBri, self.maxBri, self.saturation) for L in self.ambiLights: x = Thread(target=self._updateHueRGB, name="updateHue", args=( colors['rgb'][0], colors['rgb'][1], colors['rgb'][2], L, self.transitionTime, colors['bri'])) x.daemon = True x.start() if not cache.get("script.service.hue.service_enabled"): logger.info("Service disabled, stopping Ambilight") self.ambiRunning.clear() self.monitor.waitForAbort(self.updateInterval) # seconds average_process_time = kodiHue.perfAverage(PROCESS_TIMES) logger.info("Average process time: {}".format(average_process_time)) self.captureSize = ADDON.setSetting("average_process_time", str(average_process_time)) except Exception as exc: logger.exception("Exception in _ambiLoop") reporting.process_exception(exc) logger.debug("_ambiLoop stopped")
def __init__(self, settings=None, *args, **kwargs): logger.error('a settings: %r', settings) xbmc.Player.__init__(self, *args, **kwargs) logger.error('b settings: %r', settings) self.settings = settings self.playing = False self.capture = xbmc.RenderCapture() self.legacy_render_api = True
def main(self): capture = xbmc.RenderCapture() xbmc.log('START', level=-1) xbmc.log("aspect", level=-1) xbmc.log(str(capture.getAspectRatio()), level=-1) image = ImageGrab.grab() total_width, height = image.size xbmc.log('width', level=-1) xbmc.log(str(total_width), level=-1) width = int(height * capture.getAspectRatio()) xbmc.log(str(int(width)), level=-1) # use capture.getAspectRatio() aspect = str(xbmc.getInfoLabel('VideoPlayer.VideoAspect')) xbmc.log(str(aspect), level=-1) # box size box_size_x = width / 100 box_size_y = height / 100 xbmc.log("box_size", level=-1) xbmc.log(str(box_size_x), level=-1) xbmc.log(str(box_size_y), level=-1) # box position area_min_x = (total_width - width) / 2 area_max_x = total_width - area_min_x - box_size_x area_max_y = height / 10 - box_size_y xbmc.log("area_", level=-1) xbmc.log(str(area_min_x), level=-1) xbmc.log(str(area_max_x), level=-1) xbmc.log(str(area_max_y), level=-1) box_start_x, box_start_y = Script().get_box_start( area_min_x, area_max_x, area_max_y) #box_start_x = random.randint(area_min_x, area_max_x) #box_start_y = random.randint(5, area_max_y) xbmc.log("ramnd", level=-1) xbmc.log(str(box_start_x) + ' ' + str(box_start_y), level=-1) black = Script().get_black(image, box_start_x, box_start_y, box_size_x, box_size_y) if black: dialog = xbmcgui.Dialog() dialog.notification('OUTRO', 'BLACK', xbmcgui.NOTIFICATION_INFO, 1000) xbmc.log("REAL BLACK")
def run_boblight(): main = Main() xbmc_monitor = MyMonitor() player_monitor = MyPlayer() player_monitor.playing = xbmc.Player().isPlaying() if main.startup() == 0: capture = xbmc.RenderCapture() capture.capture(capture_width, capture_height, xbmc.CAPTURE_FLAG_CONTINUOUS) while not xbmc.abortRequested: xbmc.sleep(100) if not settings.bobdisable: if not settings.is_working_time(): bob.bob_set_priority(255) continue if not bob.bob_ping() or settings.reconnect: if not main.connectBoblight(): continue if settings.bob_init(): check_state() settings.reconnect = False if not settings.staticBobActive: capture.waitForCaptureStateChangeEvent(1000) if capture.getCaptureState( ) == xbmc.CAPTURE_STATE_DONE and player_monitor.isPlaying( ): width = capture.getWidth() height = capture.getHeight() pixels = capture.getImage() bob.bob_setscanrange(width, height) rgb = (c_int * 3)() for y in range(height): row = width * y * 4 for x in range(width): rgb[0] = pixels[row + x * 4 + 2] rgb[1] = pixels[row + x * 4 + 1] rgb[2] = pixels[row + x * 4] bob.bob_addpixelxy(x, y, byref(rgb)) bob.bob_set_priority(128) if not bob.bob_sendrgb(): log("error sending values: %s" % bob.bob_geterror()) return else: log('boblight disabled in Addon Settings') bob.bob_set_priority(255) continue del main #cleanup del player_monitor del xbmc_monitor
def playerStateChangedCB(self, state): if state == HyperionPlayer.GRABBING_START: self.capture = xbmc.RenderCapture() self.capture.capture(settings.capture_width, settings.capture_height) elif state == HyperionPlayer.GRABBING_STOP: if not self.hyperion.isConnected(): log("grabbing stopped but client was not connected") return self.hyperion.clear(settings.priority) log("clearing priority")
def onPlayBackStarted(self): if self.isPlayingVideo(): if os.name == 'nt': openParm = "wb" else: openParm = "w" analyzeSize = 256 capture = xbmc.RenderCapture() fmt = capture.getImageFormat() captureCount = 0 pending = False while self.isPlayingVideo() and captureCount < 10: st = capture.getCaptureState() if st == xbmc.CAPTURE_STATE_DONE or st == xbmc.CAPTURE_STATE_FAILED: if not pending: aspectRatio = capture.getAspectRatio() if aspectRatio > 0.0: if aspectRatio >= 1.0: capture.capture(analyzeSize, int(analyzeSize / aspectRatio + 0.5)) else: capture.capture(int(analyzeSize * aspectRatio + 0.5), analyzeSize) pending = True continue captureCount = captureCount + 1 pending = False if st == xbmc.CAPTURE_STATE_DONE: width = capture.getWidth() height = capture.getHeight() img = capture.getImage() xbmc.log("CaptureTest: Capture %s image with size %dx%d" % (fmt, width, height), xbmc.LOGINFO) file = open(xbmc.translatePath('special://temp/captured%02d.ppm' % captureCount), openParm) file.write("P6\n%d\n%d\n255\n" % (width, height)) n = width * height i = 0 while n: if fmt == 'RGBA': file.write('%c%c%c' % (img[i], img[i+1], img[i+2])) else: # 'BGRA' file.write('%c%c%c' % (img[i+2], img[i+1], img[i])) i = i + 4 n = n - 1 file.close() continue capture.waitForCaptureStateChangeEvent(100) displayNotification("Video captured")
def __init__(self, monitor, player, state): self.log('Init') self.capturer = xbmc.RenderCapture() self.monitor = monitor self.player = player self.state = state self.thread = None self.match_counts = {'hits': 0, 'misses': 0} self._init_hashes() self.running = False self.sigstop = False self.sigterm = False
def __init__(self, videoinfo, player): self.player = player super(CaptureThread, self).__init__(name='Capture') self.videoinfo = videoinfo self.rc = xbmc.RenderCapture() self.abort_evt = threading.Event() self.capture_monitor_thread = CaptureMonitorThread() self.resultQ = self.capture_monitor_thread.resultQ if hasattr(self.rc, 'waitForCaptureStateChangeEvent'): self.legacy = True else: self.legacy = False self.dropped = 0 self.capture_monitor_thread.start() self.dummyQ = Queue.Queue() self.lastimage = bytearray(b'')
def __init__(self, settings): BaseState.__init__(self, settings) self._hyperion = None self._capture = None self._captureState = None self._data = None self._useLegacyApi = None # try to connect to hyperion self._hyperion = Hyperion(self._settings.address, self._settings.port) # create the capture object self._capture = xbmc.RenderCapture() self._capture.capture(self._settings.capture_width, self._settings.capture_height)
def __init__(self, settings): '''Constructor - settings: Settings structure ''' log("Entering connected state") self.__settings = settings self.__hyperion = None self.__capture = None # try to connect to hyperion self.__hyperion = Hyperion(self.__settings.address, self.__settings.port) # create the capture object self.__capture = xbmc.RenderCapture() self.__capture.capture(64, 64)
def screenshot(width, height, filename=None): cap = xbmc.RenderCapture() cap.capture(width, height, 2) state = 0 while True: state = cap.getCaptureState() if state != 0: break cap.waitForCaptureStateChangeEvent() # TODO: Create the convert from BGRA to RGBA if state == 4: return None if filename is None: return cap.getImage() file(filename, 'wb').write(cap.getImage()) return True
def __init__(self, settings): '''Constructor - settings: Settings structure ''' log("Entering connected state") self.__settings = settings self.__hyperion = None self.__capture = None self.__captureState = None self.__data = None # try to connect to hyperion self.__hyperion = Hyperion(self.__settings.address, self.__settings.port) # Force clearing of priority (mainly for Orbs) self.clear_priority() # create the capture object self.__capture = xbmc.RenderCapture() self.__capture.capture(self.__settings.capture_width, self.__settings.capture_height)
def __init__(self, settings): '''Constructor - settings: Settings structure ''' log("Entering connected state") self.__settings = settings self.__hyperion = None self.__capture = None self.__captureState = None self.__data = None self.__useLegacyApi = True # try to connect to hyperion self.__hyperion = Hyperion(self.__settings.address, self.__settings.port) # create the capture object self.__capture = xbmc.RenderCapture() self.__capture.capture(self.__settings.capture_width, self.__settings.capture_height)
def process_boblight(): writeToLogFile("Starting Processing. Failed: " + str(xbmc.CAPTURE_STATE_FAILED)) capture = xbmc.RenderCapture() capture.capture(capture_width, capture_height, xbmc.CAPTURE_FLAG_CONTINUOUS) while not xbmc.abortRequested: if settings_checkForNewSettings(): settings_setup() if settings_getBobDisable(): bob_set_priority(255) time.sleep(1) continue result = capture.waitForCaptureStateChangeEvent(1000) if capture.getCaptureState() == xbmc.CAPTURE_STATE_DONE: width = capture.getWidth() height = capture.getHeight() pixels = capture.getImage() bob_setscanrange(width, height) rgb = array('l', [0, 0, 0]) message = '' for y in range(height): row = width * y * 4 for x in range(width): rgb[0] = pixels[row + x * 4 + 2] rgb[1] = pixels[row + x * 4 + 1] rgb[2] = pixels[row + x * 4] message = str(x) + ',' + str(y) + ':' + str( rgb[0]) + "," + str(rgb[1]) + "," + str(rgb[2]) + "\n" client.stdin.write(message) client.stdin.write("send\n") # set to black for y in range(capture_height): for x in range(capture_width): client.stdin.write(str(x) + ',' + str(y) + ":0,0,0\n") client.stdin.write("send\n") client.stdin.write("send\n") client.stdin.write("send\n")
def onPlayBackStarted(self): capture = xbmc.RenderCapture() captureHeight = captureWidth / capture.getAspectRatio() capture.capture(int(captureWidth), int(captureHeight), xbmc.CAPTURE_FLAG_CONTINUOUS) while self.isPlayingVideo() and not xbmc.abortRequested: capture.waitForCaptureStateChangeEvent(1000) if capture.getCaptureState() == xbmc.CAPTURE_STATE_DONE: pixelsMessage = [] pixelsMessage.append('Image,') pixelsMessage.append('Width,%04d,' % (capture.getWidth())) pixelsMessage.append('Height,%04d,' % (capture.getHeight())) pixelsMessage.append('Format,%s,' % (capture.getImageFormat())) pixelsMessage.append(str(capture.getImage())) pixelsMessage.append('\r\n') udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) udpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536) udpSocket.sendto(''.join(pixelsMessage), ('127.0.0.1', 52101)) udpSocket.close()
def onPlayBackStarted(self): if self.isPlayingVideo(): # fullWidth = self.window.getWidth() # fullHeight = self.window.getHeight() capture = xbmc.RenderCapture() # capture.capture(256, 256, xbmc.CAPTURE_FLAG_IMMEDIATELY) # capture.waitForCaptureStateChangeEvent(100) # # fmt = capture.getImageFormat() # aspectRatio = capture.getAspectRatio() # # width = fullWidth / aspectRatio # height = fullHeight # # if width < height: # height = width # width = fullWidth # # displayNotification("%s => %dx%d" % (aspectRatio, width, height)) capture.capture(self.nbLedTop, self.nbLedSide, xbmc.CAPTURE_FLAG_CONTINUOUS) fmt = capture.getImageFormat() # start = int(round(time.time() * 1000)) # count = 0 while self.isPlayingVideo(): capture.waitForCaptureStateChangeEvent(100) if capture.getCaptureState() == xbmc.CAPTURE_STATE_DONE: # count += 1 img = capture.getImage() i = 6 # left side x = 0 y = self.nbLedSide - 1 while y >= 0: pos = y * self.nbLedTop * 4 + x * 4 if fmt == 'RGBA': self.data[i] = img[pos] self.data[i + 1] = img[pos + 1] self.data[i + 2] = img[pos + 2] else: self.data[i] = img[pos + 2] self.data[i + 1] = img[pos + 1] self.data[i + 2] = img[pos] i += 3 y -= 1 # top x = 1 y = 0 while x < (self.nbLedTop - 1): pos = y * self.nbLedTop * 4 + x * 4 if fmt == 'RGBA': self.data[i] = img[pos] self.data[i + 1] = img[pos + 1] self.data[i + 2] = img[pos + 2] else: self.data[i] = img[pos + 2] self.data[i + 1] = img[pos + 1] self.data[i + 2] = img[pos] i += 3 x += 1 # right side x = self.nbLedTop - 1 y = 0 while y < self.nbLedSide: pos = y * self.nbLedTop * 4 + x * 4 if fmt == 'RGBA': self.data[i] = img[pos] self.data[i + 1] = img[pos + 1] self.data[i + 2] = img[pos + 2] else: self.data[i] = img[pos + 2] self.data[i + 1] = img[pos + 1] self.data[i + 2] = img[pos] i += 3 y += 1 self.arduino.write(self.data)
from settings import Settings from tools import get_version, xbmclog from ambilight_controller import AmbilightController from theater_controller import TheaterController from static_controller import StaticController import bridge import ui import algorithm import image xbmclog("Kodi Hue: In .(argv={}) service started, version: {}".format( sys.argv, get_version())) ev = Event() capture = xbmc.RenderCapture() fmt = capture.getImageFormat() # BGRA or RGBA fmtRGBA = fmt == 'RGBA' class MyMonitor(xbmc.Monitor): def __init__(self, settings): xbmc.Monitor.__init__(self) self.settings = settings def onSettingsChanged(self): hue.settings.readxml() xbmclog('Kodi Hue: In onSettingsChanged() {}'.format(hue.settings)) hue.update_controllers()
def run(self): monitor = xbmc.Monitor() player = xbmc.Player() capture = xbmc.RenderCapture() ad = self.atmoDriver ot = None fmt = capture.getImageFormat() if fmt == 'RGBA': imgFmt = atmodriver.IMAGE_FORMAT_RGBA else: imgFmt = atmodriver.IMAGE_FORMAT_BGRA analyzeSize = (ad.analyze_size + 1) * 64 eventWaitTime = ad.analyze_rate analyzeRateTime = ad.analyze_rate / 1000.0 videoPlaying = False pending = False nextCaptureTime = 0.0 nextConfigUpdateTime = 0.0 videoStartTime = 0.0 captureCount = 1 instantConfigured = False kodiMainWindow.setProperty(statePropertyName, 'running') displayNotificationAndLog(LOG_INFO, "Service running") while self.running > 0 or ( self.running == -1 and not monitor.abortRequested() and kodiMainWindow.getProperty(statePropertyName)): img = None if useLegacyCaptureAPI: st = capture.getCaptureState() if st != xbmc.CAPTURE_STATE_DONE and st != xbmc.CAPTURE_STATE_FAILED: capture.waitForCaptureStateChangeEvent(eventWaitTime) continue if pending and st == xbmc.CAPTURE_STATE_DONE: img = capture.getImage() elif pending and player.isPlayingVideo(): img = capture.getImage(eventWaitTime) if img == None or len(img) == 0: continue pending = False if img: self.analyzedColors = ad.analyzeImage(capture.getWidth(), capture.getHeight(), imgFmt, img) captureCount = captureCount + 1 actualTime = time.time() if actualTime < nextCaptureTime: time.sleep(nextCaptureTime - actualTime) continue if actualTime >= nextConfigUpdateTime: if self.configFileTime != os.path.getmtime(addonConfigFile): log(LOG_INFO, "update of configuration detected") if self.setConfig(xbmcaddon.Addon(), True): if videoPlaying: if ad != self.outputDriver: self.outputDriver.instantConfigure() ad.instantConfigure() instantConfigured = True else: if not self.configure(): return self.getConfig(xbmcaddon.Addon(), True) analyzeSize = (ad.analyze_size + 1) * 64 eventWaitTime = ad.analyze_rate analyzeRateTime = ad.analyze_rate / 1000.0 nextConfigUpdateTime = actualTime + CONFIG_UPDATE_TIME continue if player.isPlayingVideo(): if not videoPlaying: log( LOG_INFO, "start playing video: aspect ratio: %.4f" % capture.getAspectRatio()) videoPlaying = True videoStartTime = time.time() captureCount = 1 self.analyzedColors = None ot = OutputThread(self, ad, self.outputDriver) ot.start() aspectRatio = capture.getAspectRatio() if aspectRatio > 0.0: if aspectRatio >= 1.0: capture.capture(analyzeSize, int(analyzeSize / aspectRatio + 0.5)) else: capture.capture(int(analyzeSize * aspectRatio + 0.5), analyzeSize) pending = True nextCaptureTime = time.time() + analyzeRateTime continue if videoPlaying: videoPlaying = False log(LOG_INFO, "stop playing video") ot.stop() ot = None log( LOG_INFO, "average capture interval: %.3f" % ((time.time() - videoStartTime) / captureCount)) if instantConfigured: instantConfigured = False if not self.configure(): return self.getConfig(xbmcaddon.Addon(), True) analyzeSize = (ad.analyze_size + 1) * 64 eventWaitTime = ad.analyze_rate analyzeRateTime = ad.analyze_rate / 1000.0 nextCaptureTime = time.time() + IDLE_WAIT_TIME continue if videoPlaying: ot.stop() ot = None log( LOG_INFO, "average capture interval: %.3f" % ((time.time() - videoStartTime) / captureCount)) kodiMainWindow.clearProperty(statePropertyName) displayNotificationAndLog(LOG_INFO, "Service stopped")
def _ambiLoop(self): cap = xbmc.RenderCapture() logger.debug("_ambiLoop started") service_enabled = cache.get("script.service.hue.service_enabled") aspect_ratio = cap.getAspectRatio() self.captureSizeY = int(self.captureSize / aspect_ratio) expected_capture_size = self.captureSize * self.captureSizeY * 4 # size * 4 bytes I guess logger.debug( "aspect_ratio: {}, Capture Size: ({},{}), expected_capture_size: {}" .format(aspect_ratio, self.captureSize, self.captureSizeY, expected_capture_size)) for L in self.ambiLights: self.ambiLights[L].update(prevxy=(0.0001, 0.0001)) try: while not self.monitor.abortRequested( ) and self.ambiRunning.is_set( ): # loop until kodi tells add-on to stop or video playing flag is unset. try: cap.capture(self.captureSize, self.captureSizeY ) # async capture request to underlying OS capImage = cap.getImage( ) # timeout to wait for OS in ms, default 1000 # logger.debug("CapSize: {}".format(len(capImage))) if capImage is None or len( capImage) < expected_capture_size: logger.error( "capImage is none or < expected. captured: {}, expected: {}" .format(len(capImage), expected_capture_size)) self.monitor.waitForAbort( 0.25) # pause before trying again continue # no image captured, try again next iteration image = Image.frombuffer( "RGBA", (self.captureSize, self.captureSizeY), buffer(capImage), "raw", "BGRA") except ValueError: logger.error("capImage: {}".format(len(capImage))) logger.exception("Value Error") self.monitor.waitForAbort(0.25) continue # returned capture is smaller than expected when player stopping. give up this loop. except Exception as exc: logger.warning("Capture exception", exc_info=1) reporting.process_exception(exc) self.monitor.waitForAbort(0.25) continue # lighRight = self.ambiLights['0'] # lighLeft = self.ambiLights['1'] # threadLeft = Thread(target=self._updateHueRGB, name="updateHue", args=( # colors2['rgb'][0], colors2['rgb'][1], colors2['rgb'][2], lighLeft, self.transitionTime, colors2['bri'])) # threadLeft.daemon = True # threadRight = Thread(target=self._updateHueRGB, name="updateHue", args=( # colors3['rgb'][0], colors3['rgb'][1], colors3['rgb'][2], lighRight, self.transitionTime, colors3['bri'])) # threadRight.daemon = True # threadLeft.start() # threadRight.start() colorZones = [] if self.zone == "1": colorZones.append( self.imageProcess.img_avg(image, self.minBri, self.maxBri, self.saturation)) elif self.zone == "2": image2 = image.crop((0, 0, 200, 225)) colorZones.append( self.imageProcess.img_avg(image2, self.minBri, self.maxBri, self.saturation)) # savepath = os.path.join(xbmc.translatePath("special://userdata/addon_data/script.service.hue/debugimages/"), str(clock) + "LEFT.png") # image2.save(savepath) image3 = image.crop((200, 0, 400, 225)) colorZones.append( self.imageProcess.img_avg(image3, self.minBri, self.maxBri, self.saturation)) # savepath = os.path.join(xbmc.translatePath("special://userdata/addon_data/script.service.hue/debugimages/"), str(clock) + "RIGHT.png") # image3.save(savepath) for L in self.ambiLights: position = self.ambiLights[L].get('position') # logger.debug("position " + position) colors = colorZones[position] x = Thread(target=self._updateHueRGB, name="updateHue", args=(colors['rgb'][0], colors['rgb'][1], colors['rgb'][2], L, self.transitionTime, colors['bri'])) x.daemon = True x.start() if not cache.get("script.service.hue.service_enabled"): logger.info("Service disabled, stopping Ambilight") self.ambiRunning.clear() self.monitor.waitForAbort(self.updateInterval) # seconds average_process_time = kodiHue.perfAverage(PROCESS_TIMES) logger.info( "Average process time: {}".format(average_process_time)) self.captureSize = ADDON.setSettingString( "average_process_time", "{}".format(average_process_time)) except Exception as exc: logger.exception("Exception in _ambiLoop") reporting.process_exception(exc) logger.debug("_ambiLoop stopped")
def run_boblight(): main = Main() xbmc_monitor = MyMonitor() player_monitor = MyPlayer() player_monitor.playing = xbmc.Player().isPlaying() if main.startup() == 0: capture = xbmc.RenderCapture() capture.capture(settings.frame_capture_width, settings.frame_capture_height, xbmc.CAPTURE_FLAG_CONTINUOUS) while not xbmc.abortRequested: xbmc.sleep(settings.frame_capture_interval) if not settings.bobdisable: if not bob.bob_ping() or settings.reconnect: if not main.connectBoblight(): continue if settings.bob_init(): check_state() settings.reconnect = False if not settings.staticBobActive: capture.waitForCaptureStateChangeEvent(1000) if capture.getCaptureState() == xbmc.CAPTURE_STATE_DONE and player_monitor.isPlaying(): width = capture.getWidth(); if width == 0: return height = capture.getHeight(); pixels = capture.getImage(); pxl_width = width * 4 range_x_min = int(width / 2 * (1 - settings.scan_range)) * 4 range_x_max = int(width / 2 * (1 + settings.scan_range)) * 4 range_y_min = int(height / 2 * (1 - settings.scan_range)) * pxl_width range_y_max = int(height / 2 * (1 + settings.scan_range)) * pxl_width found = False for yc in range(0, int(height * settings.scan_v) * pxl_width, pxl_width): for xi in range (range_x_min + yc, range_x_max + yc, 4): if pixels[xi] > settings.scan_threshold or pixels[xi + 1] > settings.scan_threshold or pixels[xi + 2] > settings.scan_threshold: found = True break if found: break yc = int(yc / pxl_width) found = False for xc in range(0, int(width * settings.scan_h) * 4, 4): for yi in range (range_y_min + xc, range_y_max + xc , pxl_width): if pixels[yi] > settings.scan_threshold or pixels[yi + 1] > settings.scan_threshold or pixels[yi + 2] > settings.scan_threshold: found = True break if found: break xc = int(xc / 4) bob.bob_setscanrange(width - xc * 2, height - yc * 2) rgb = (c_int * 3)() for y in range(yc, height - yc): for x in range(xc, width - xc): pxl = (y * width + x) * 4 rgb[0] = pixels[pxl + 2] rgb[1] = pixels[pxl + 1] rgb[2] = pixels[pxl] bob.bob_addpixelxy(x - xc, y - yc, byref(rgb)) bob.bob_set_priority(128) if not bob.bob_sendrgb(): log("error sending values: %s" % bob.bob_geterror()) return else: log('boblight disabled in Addon Settings') bob.bob_set_priority(255) continue del main #cleanup del player_monitor del xbmc_monitor
def _ambi_loop(self): AMBI_RUNNING.set() cap = xbmc.RenderCapture() xbmc.log("[script.service.hue] _ambiLoop started") aspect_ratio = cap.getAspectRatio() self.capture_size_y = int(self.capture_size_x / aspect_ratio) expected_capture_size = self.capture_size_x * self.capture_size_y * 4 # size * 4 bytes - RGBA xbmc.log( f"[script.service.hue] aspect_ratio: {aspect_ratio}, Capture Size: ({self.capture_size_x},{self.capture_size_y}), expected_capture_size: {expected_capture_size}" ) cap.capture( self.capture_size_x, self.capture_size_y ) # start the capture process https://github.com/xbmc/xbmc/pull/8613#issuecomment-165699101 for L in list(self.ambi_lights): self.ambi_lights[L].update(prev_xy=(0.0001, 0.0001)) while not self.monitor.abortRequested() and AMBI_RUNNING.is_set( ) and self.hue_connection.connected: # loop until kodi tells add-on to stop or video playing flag is unset. try: cap_image = cap.getImage( ) # timeout to wait for OS in ms, default 1000 if cap_image is None or len(cap_image) < expected_capture_size: xbmc.log( "[script.service.hue] capImage is none or < expected. captured: {}, expected: {}" .format(len(cap_image), expected_capture_size)) self.monitor.waitForAbort( 0.25) # pause before trying again continue # no image captured, try again next iteration image = Image.frombytes( "RGBA", (self.capture_size_x, self.capture_size_y), bytes(cap_image), "raw", "BGRA", 0, 1) # Kodi always returns a BGRA image. except ValueError: xbmc.log(f"[script.service.hue] capImage: {len(cap_image)}") xbmc.log("[script.service.hue] Value Error") self.monitor.waitForAbort(0.25) continue # returned capture is smaller than expected, but this happens when player is stopping so fail silently. give up this loop. colors = self.image_process.img_avg(image, self.min_bri, self.max_bri, self.saturation) for L in list(self.ambi_lights): t = Thread(target=self._update_hue_rgb, name="_update_hue_rgb", args=(colors['rgb'][0], colors['rgb'][1], colors['rgb'][2], L, self.transition_time, colors['bri']), daemon=True) t.start() self.monitor.waitForAbort(self.update_interval) # seconds if not self.monitor.abortRequested( ): # ignore writing average process time if Kodi is shutting down average_process_time = self._perf_average(PROCESS_TIMES) xbmc.log( f"[script.service.hue] Average process time: {average_process_time}" ) ADDON.setSetting("average_process_time", str(average_process_time)) xbmc.log("[script.service.hue] _ambiLoop stopped")
def main(self): skip = False capture = xbmc.RenderCapture() image = ImageGrab.grab() total_width, height = image.size width = int(height * capture.getAspectRatio()) # use capture.getAspectRatio() aspect = str(xbmc.getInfoLabel('VideoPlayer.VideoAspect')) xbmc.log(str(aspect), level=-1) width_list = [0.25, 0.5, 0.75] list = [] for j in width_list: vid_height = height vid_width = width # get perc. x-ord (1/4, 1/2, 3/4) box_start_x = int(vid_width * j) box_start_y = int(vid_height * 0.1) box_size_x = int(math.fabs(float(j) * 100)) box_size_y = box_size_x list.append({ 'name': 'box', 'sc_height': vid_height, 'sc_width': vid_width, 'box_start_x': box_start_x, 'box_start_y': box_start_y, 'box_size_x': box_size_x, 'box_size_y': box_size_y }) # endfor cnt_black = 0 cnt_box = 0 for box in list: cnt_box += 1 xbmc.log("BOX: " + str(cnt_box), level=-1) box_start_x = box['box_start_x'] box_start_y = box['box_start_y'] box_size_x = box['box_size_x'] box_size_y = box['box_size_y'] black = Outro().get_black(image, box_start_x, box_start_y, box_size_x, box_size_y) xbmc.log("test: " + str(box_start_x) + ' ' + str(box_start_y) + ' ' + str(box_size_x) + ' ' + str(box_size_y) + ' ' + str(black), level=-1) if black: cnt_black += 1 else: # got non-black pixel, break loop, this is not the outro break if cnt_black == len(list): # only got black pixels from (three) boxes, let's check again cnt_black = 0 dialog.notification('OUTRO', 'BLACK-1', xbmcgui.NOTIFICATION_INFO, 1000) xbmc.sleep(3000) # grab image image = ImageGrab.grab() for box in list: box_start_x = box['box_start_x'] box_start_y = box['box_start_y'] box_size_x = box['box_size_x'] box_size_y = box['box_size_y'] black = Outro().get_black(image, box_start_x, box_start_y, box_size_x, box_size_y) xbmc.log("test_b2: " + str(box_start_x) + ' ' + str(box_start_y) + ' ' + str(box_size_x) + ' ' + str(box_size_y) + ' ' + str(black), level=-1) if black: cnt_black += 1 else: # got non black pixel, exit loop, this is not the outro break # endfor if cnt_black == len(list): cnt_black = 0 dialog.notification('OUTRO', 'BLACK-2', xbmcgui.NOTIFICATION_INFO, 1000) xbmc.sleep(3000) # grab image image = ImageGrab.grab() for box in list: box_start_x = box['box_start_x'] box_start_y = box['box_start_y'] box_size_x = box['box_size_x'] box_size_y = box['box_size_y'] black = Outro().get_black(image, box_start_x, box_start_y, box_size_x, box_size_y) xbmc.log("test_b3: " + str(box_start_x) + ' ' + str(box_start_y) + ' ' + str(box_size_x) + ' ' + str(box_size_y) + ' ' + str(black), level=-1) if black: cnt_black += 1 else: # got non black pixel, exit loop, this is not the outro break if cnt_black == len(list): # just black pixels, this must be the outro skip = True else: # dialog.notification('OUTRO', 'FOUND COLORED PIXEL in vorgang 1', xbmcgui.NOTIFICATION_INFO, 100) # return because found colored pixel in a box return if skip: xbmc.Player().playnext()
def __init__(self, *args, **kwargs): self.hyperion = Hyperion(settings) self.reconnectTries = 0 self.capture = xbmc.RenderCapture() self.currentSettingsRev = settings.rev