def getImagesMjpegInterlace(self, url, *args, **kwargs):
        """ Update camera position with interlaced mjpeg frames """
        
        try:
            stream = requests.get(url, stream = True, timeout = TIMEOUT).raw
            
        except requests.RequestException as e:
            utils.log(3, e)
            self.img1.setImage(_error, useCache = False)
            return
            
        x = 0
        while not self.monitor.abortRequested() and not self.monitor.stopped() and self.monitor.previewOpened(self.camera.number):
            
            filename = os.path.join(_datapath, '%s_%s.%d.jpg') %(self.prefix, self.camera.number, x)
            filename_exists = utils.get_mjpeg_frame(stream, filename)

            if filename_exists:
                if x % 2 == 0:  #Interlacing for flicker reduction/elimination
                    self.img1.setImage(filename, useCache = False)
                else:
                    self.img2.setImage(filename, useCache = False)
                xbmcvfs.delete(os.path.join(_datapath, '%s_%s.%d.jpg') %(self.prefix, self.camera.number, x - 2))
                x += 1
                
            else:
                utils.log(3, 'Camera %s :: Error updating preview image on MJPEG' %self.camera.number)
                self.img1.setImage(_error, useCache = False)
                break

        if not not self.monitor.abortRequested() and not self.monitor.stopped():
            utils.remove_leftover_images('%s_%s.' %(self.prefix, self.camera.number))
Пример #2
0
    def getImagesMjpegInterlace(self, url, *args, **kwargs):
        """ Update camera position with interlaced mjpeg frames """

        try:
            stream = requests.get(url, stream=True, timeout=TIMEOUT).raw

        except requests.RequestException as e:
            utils.log(3, e)
            self.img1.setImage(_error, useCache=False)
            return

        x = 0
        while not self.monitor.abortRequested() and not self.monitor.stopped(
        ) and self.monitor.previewOpened(self.camera.number):

            filename = os.path.join(_datapath, '%s_%s.%d.jpg') % (
                self.prefix, self.camera.number, x)
            filename_exists = utils.get_mjpeg_frame(stream, filename)

            if filename_exists:
                if x % 2 == 0:  #Interlacing for flicker reduction/elimination
                    self.img1.setImage(filename, useCache=False)
                else:
                    self.img2.setImage(filename, useCache=False)
                xbmcvfs.delete(
                    os.path.join(_datapath, '%s_%s.%d.jpg') %
                    (self.prefix, self.camera.number, x - 2))
                x += 1

            else:
                utils.log(
                    3, 'Camera %s :: Error updating preview image on MJPEG' %
                    self.camera.number)
                self.img1.setImage(_error, useCache=False)
                break

        if not not self.monitor.abortRequested() and not self.monitor.stopped(
        ):
            utils.remove_leftover_images('%s_%s.' %
                                         (self.prefix, self.camera.number))
    def getImagesMjpeg(self, url):
        """ Update camera position with mjpeg frames """

        try:
            #            stream = requests.get(url, stream = True, timeout = TIMEOUT, auth=HTTPDigestAuth('USERNAME', 'PASSWORD')).raw #uncomment if you need digest support for mjpeg
            stream = requests.get(url, stream=True, timeout=TIMEOUT).raw
        except requests.RequestException as e:
            utils.log(3, e)
            self.img1.setImage(_error, useCache=False)
            return

        x = 0
        while not self.monitor.abortRequested() and not self.monitor.stopped(
        ) and self.monitor.previewOpened(self.camera.number):
            filename = os.path.join(_datapath, '%s_%s.%d.jpg') % (
                self.prefix, self.camera.number, x)
            filename_exists = utils.get_mjpeg_frame(stream, filename)

            if filename_exists:
                self.img1.setImage(filename, useCache=False)
                self.img2.setImage(filename, useCache=False)
                xbmcvfs.delete(
                    os.path.join(_datapath, '%s_%s.%d.jpg') %
                    (self.prefix, self.camera.number, x - 1))
                x += 1

            else:
                utils.log(
                    3, 'Camera %s :: Error updating preview image on MJPEG' %
                    self.camera.number)
                self.img1.setImage(_error, useCache=False)
                break

        if not not self.monitor.abortRequested() and not self.monitor.stopped(
        ):
            utils.remove_leftover_images('%s_%s.' %
                                         (self.prefix, self.camera.number))
    def __init__(self):
        self.isRunning = True

        # Black Background
        background_fade_animation = [
            ("WindowOpen", ("effect=fade time=200")),
            ("WindowClose", ("effect=fade time=1500")),
        ]

        img = xbmcgui.ControlImage(0, 0, 1280, 720, filename=_black, aspectRatio=0)
        self.addControl(img)
        img.setAnimations(background_fade_animation)

        # Individual Camera positions setup
        urls = []
        files = []
        imgs = []
        imgs2 = []

        coords = [(0, 0, 640, 360), (640, 0, 640, 360), (0, 360, 640, 360), (640, 360, 640, 360)]

        effect = ["slide", "slide"]
        time = [1200, 1000]
        tween = ["back", "back"]
        easing = ["Out", "InOut"]
        animations = [
            [
                (
                    "WindowOpen",
                    ("effect={0} start=-640,-360 time={1} tween={2} easing={3}").format(
                        effect[0], time[0], tween[0], easing[0]
                    ),
                ),
                (
                    "WindowClose",
                    ("effect={0} end=-640,-360 time={1} tween={2} easing={3}").format(
                        effect[1], time[1], tween[1], easing[1]
                    ),
                ),
            ],
            [
                (
                    "WindowOpen",
                    ("effect={0} start=640,-360 time={1} tween={2} easing={3}").format(
                        effect[0], time[0], tween[0], easing[0]
                    ),
                ),
                (
                    "WindowClose",
                    ("effect={0} end=640,-360 time={1} tween={2} easing={3}").format(
                        effect[1], time[1], tween[1], easing[1]
                    ),
                ),
            ],
            [
                (
                    "WindowOpen",
                    ("effect={0} start=-640,360 time={1} tween={2} easing={3}").format(
                        effect[0], time[0], tween[0], easing[0]
                    ),
                ),
                (
                    "WindowClose",
                    ("effect={0} end=-640,360 time={1} tween={2} easing={3}").format(
                        effect[1], time[1], tween[1], easing[1]
                    ),
                ),
            ],
            [
                (
                    "WindowOpen",
                    ("effect={0} start=640,360 time={1} tween={2} easing={3}").format(
                        effect[0], time[0], tween[0], easing[0]
                    ),
                ),
                (
                    "WindowClose",
                    ("effect={0} end=640,360 time={1} tween={2} easing={3}").format(
                        effect[1], time[1], tween[1], easing[1]
                    ),
                ),
            ],
        ]

        # Acquire all Enabled & Connected cameras
        enabled_cameras = settings.getAllEnabledCameras(monitor)

        # Logic to ensure enabled cameras are placed in the correct position
        threads = []
        for window_position in "1234":
            position = int(window_position) - 1

            # Sets the initial image to the loader gif
            img1 = xbmcgui.ControlImage(*coords[position], filename=_loader, aspectRatio=0)
            self.addControl(
                img1
            )  # Bug was seen here previously, hence the 'try' and this will need to be investigated in future
            img1.setAnimations(animations[position])

            # Connected and Enabled Camera
            if len(enabled_cameras) > position:
                img2 = xbmcgui.ControlImage(*coords[position], filename="", aspectRatio=0)
                self.addControl(img2)
                img2.setAnimations(animations[position])

                control = [img1, img2]

                with Camera(enabled_cameras[position]) as camera:
                    stream_type = camera.getStreamType(1)
                    url = camera.getStreamUrl(1, stream_type)
                    prefix = "AllCamera"

                    if stream_type == 0:  # MJPEG
                        t = threading.Thread(target=self.getImagesMjpeg, args=(camera, url, control, prefix))

                    elif stream_type == 2:  # MJPEG Interlaced
                        t = threading.Thread(target=self.getImagesMjpegInterlace, args=(camera, url, control, prefix))

                    else:  # Snapshot
                        t = threading.Thread(target=self.getImagesSnapshot, args=(camera, url, control, prefix))

                    threads.append(t)
                    t.start()

            # No Camera so set the place holder image
            else:
                img1.setImage(_holder, useCache=False)

        if len(threads) > 0:
            self.doModal()

            # while not monitor.abortRequested() and self.isRunning:
            #    monitor.waitForAbort(1)

            monitor.maybe_resume_previous()
            monitor.waitForAbort(1)
            utils.remove_leftover_images("AllCamera")

        else:
            utils.log(2, "Unable to start All Camera Player")
            utils.notify("Player did not start.  Check camera settings.")
Пример #5
0
class CameraPreviewWindow(xbmcgui.WindowDialog):
    """ Class is used to create the picture-in-picture window of the camera view """
    def __init__(self, camera, monitor):
        self.camera = camera
        self.monitor = monitor
        self.cond_service = settings.getSetting_int('cond_service',
                                                    self.camera.number)
        self.cond_manual = settings.getSetting_int('cond_manual',
                                                   self.camera.number)
        self.dur_service = settings.getSetting_int('dur_service',
                                                   self.camera.number)
        self.dur_manual = settings.getSetting_int('dur_manual',
                                                  self.camera.number)
        self.prefix = 'Preview'
        self.buttons = []

        # Positioning of the window
        WIDTH = 320
        HEIGHT = 180

        scaling = settings.getSetting_float('scaling', self.camera.number)

        width = int(float(WIDTH * scaling))
        height = int(float(HEIGHT * scaling))

        button_scaling = 0.5 * scaling
        button_width = int(round(Button.WIDTH * button_scaling))

        position = settings.getSetting('position', self.camera.number).lower()
        if 'bottom' in position:
            y = 720 - height
        else:
            y = 0

        if 'left' in position:
            x = 0
            start = -width
        else:
            x = 1280 - width
            start = width

        animations = [
            ('WindowOpen',
             ("effect=slide start={0:d} time=1300 tween=cubic easing=out"
              ).format(start)),
            ('WindowClose',
             ("effect=slide end={0:d} time=900 tween=back easing=inout"
              ).format(start))
        ]

        self.black = xbmcgui.ControlImage(x, y, width, height, _black)
        self.addControl(self.black)
        self.black.setAnimations(animations)

        self.img1 = xbmcgui.ControlImage(x, y, width, height, '')
        self.img2 = xbmcgui.ControlImage(x, y, width, height, '')
        self.addControl(self.img1)
        self.addControl(self.img2)
        self.img1.setAnimations(animations)
        self.img2.setAnimations(animations)

        self.close_button = Button(self,
                                   'close',
                                   x + width - button_width - 10,
                                   y + 10,
                                   scaling=button_scaling)
        self.addControl(self.close_button)
        self.close_button.setAnimations(animations)

        self.setProperty('zorder', "99")

        self.playFullscreen = False
        self.stop()  #Initializes state and makes ready to be used

    def start(self):
        url = self.monitor.get_overrideURL(
            self.camera.number)  #Request to test by @mrjd in forum
        stream_type = self.camera.getStreamType(2)

        if url == '':
            url = self.camera.getStreamUrl(2, stream_type)

        utils.log(
            2,
            'Camera %s :: Preview Window Opened - Manual: %s;  Stream Type: %d;  URL: %s'
            % (self.camera.number,
               self.monitor.openRequest_manual(
                   self.camera.number), stream_type, url))

        if stream_type == 0:
            t = threading.Thread(target=self.getImagesMjpeg, args=(url, ))
        elif stream_type == 1:
            t = threading.Thread(target=self.getImagesSnapshot, args=(url, ))
        elif stream_type == 2:
            t = threading.Thread(target=self.getImagesMjpegInterlace,
                                 args=(url, ))

        t.daemon = True

        self.monitor.openPreview(self.camera.number)
        t.start()
        self.show()
        self.wait_closeRequest()

    def stop(self, playFullscreen=False):
        self.monitor.closePreview(self.camera.number)
        self.close()
        utils.log(2, 'Camera %s :: Preview Window Closed' % self.camera.number)

        if not self.monitor.abortRequested() and not self.monitor.stopped():

            if playFullscreen:
                self.monitor.maybe_stop_current()
                fullscreenplayer = settings.getSetting_int('fullscreen_player')

                if fullscreenplayer == CAMERAWITHCONTROLS:
                    cameraplayer.play(self.camera.number)

                elif fullscreenplayer == CAMERAWITHOUTCONTROLS:
                    cameraplayer.play(self.camera.number, show_controls=False)

                elif fullscreenplayer == ALLCAMERAPLAYER:
                    allcameraplayer.play()

            self.wait_openRequest()

    def wait_openRequest(self):
        while not self.monitor.abortRequested() and not self.monitor.stopped(
        ) and not self.monitor.openRequested(self.camera.number):
            self.monitor.waitForAbort(.5)

        if not self.monitor.abortRequested() and not self.monitor.stopped():
            self.openRequest_manual = self.monitor.openRequested_manual(
                self.camera.number)
            self.start()

    def wait_closeRequest(self):
        duration = 0  # Duration is 0 if Close Condition is Manual or Alarm only, otherwise set based on source

        if not self.monitor.openRequested_manual(self.camera.number):
            if self.cond_service == CONDITION_DURATION_NO_ALARM or self.cond_service == CONDITION_DURATION:
                duration = self.dur_service
        else:
            if self.cond_manual == CONDITION_DURATION_NO_ALARM or self.cond_manual == CONDITION_DURATION:
                duration = self.dur_manual

        openDuration = time.time() + duration

        #print 'Wait for close - duration: %d;  openDuration: %d' %(duration, openDuration)

        # Loop Condition Checking
        while not self.monitor.abortRequested() and not self.monitor.stopped(
        ) and self.monitor.previewOpened(
                self.camera.number) and not self.monitor.closeRequested(
                    self.camera.number):
            if ((self.cond_service == CONDITION_DURATION_NO_ALARM and not self.monitor.openRequested_manual(self.camera.number)) or \
                (self.cond_manual == CONDITION_DURATION_NO_ALARM and self.monitor.openRequested_manual(self.camera.number))) \
                and self.monitor.alarmActive(self.camera.number):

                openDuration = time.time() + duration
                #print '%s, %s, %s, %s' %(self.cond_service, self.cond_manual, self.monitor.openRequested_manual(self.camera.number), self.monitor.alarmActive(self.camera.number))
                #print 'Wait for close Loop - duration: %d;  openDuration: %d;  time: %d' %(duration, openDuration, time.time())

            # Duration Check if Close Condition is not Manual or Alarm only
            if (duration > 0 and time.time() > openDuration):
                self.monitor.closeRequest(self.camera.number)

            # Check if close Request
            if self.monitor.closeRequested(self.camera.number):
                break

            self.monitor.waitForAbort(.5)

        self.stop()

    def onControl(self, control):
        if control == self.close_button:
            utils.log(
                2, 'Camera %s :: Closing Preview Manually - Mouse Request' %
                self.camera.number)
            self.monitor.dismissPreview(self.camera.number)
            self.stop()

    def onAction(self, action):
        if action in (ACTION_PREVIOUS_MENU, ACTION_BACKSPACE, ACTION_NAV_BACK):
            utils.log(
                2, 'Camera %s :: Closing Preview Manually - Keyboard Request' %
                self.camera.number)
            self.monitor.dismissPreview(self.camera.number)
            self.stop()

        elif action == ACTION_SELECT_ITEM:
            utils.log(
                2, 'Camera %s :: Playing Fullscreen from Preview.' %
                self.camera.number)
            self.monitor.dismissPreview(self.camera.number)
            self.stop(playFullscreen=True)

    def getImagesMjpeg(self, url):
        """ Update camera position with mjpeg frames """

        try:
            stream = requests.get(url, stream=True, timeout=TIMEOUT).raw

        except requests.RequestException as e:
            utils.log(3, e)
            self.img1.setImage(_error, useCache=False)
            return

        x = 0
        while not self.monitor.abortRequested() and not self.monitor.stopped(
        ) and self.monitor.previewOpened(self.camera.number):
            filename = os.path.join(_datapath, '%s_%s.%d.jpg') % (
                self.prefix, self.camera.number, x)
            filename_exists = utils.get_mjpeg_frame(stream, filename)

            if filename_exists:
                self.img1.setImage(filename, useCache=False)
                self.img2.setImage(filename, useCache=False)
                xbmcvfs.delete(
                    os.path.join(_datapath, '%s_%s.%d.jpg') %
                    (self.prefix, self.camera.number, x - 1))
                x += 1

            else:
                utils.log(
                    3, 'Camera %s :: Error updating preview image on MJPEG' %
                    self.camera.number)
                self.img1.setImage(_error, useCache=False)
                break

        if not not self.monitor.abortRequested() and not self.monitor.stopped(
        ):
            utils.remove_leftover_images('%s_%s.' %
                                         (self.prefix, self.camera.number))

    def getImagesSnapshot(self, url, *args, **kwargs):
        """ Update camera position with snapshots """

        x = 0
        while not self.monitor.abortRequested() and not self.monitor.stopped(
        ) and self.monitor.previewOpened(self.camera.number):

            try:
                filename = os.path.join(_datapath, '%s_%s.%d.jpg') % (
                    self.prefix, self.camera.number, x)
                urlretrieve(url, filename)

                if os.path.exists(filename):
                    self.img1.setImage(filename, useCache=False)
                    xbmcvfs.delete(
                        os.path.join(_datapath, '%s_%s.%d.jpg') %
                        (self.prefix, self.camera.number, x - 1))
                    self.img2.setImage(filename, useCache=False)
                    x += 1

            except Exception, e:
                utils.log(
                    3,
                    'Camera %s :: Error updating preview image on Snapshot: %s'
                    % (self.camera.number, e))
                self.img1.setImage(_error, useCache=False)
                break

        if not not self.monitor.abortRequested() and not self.monitor.stopped(
        ):
            utils.remove_leftover_images('%s_%s.' %
                                         (self.prefix, self.camera.number))
Пример #6
0
    def __init__(self):
        self.isRunning = True

        # Black Background
        background_fade_animation = [
                                    ('WindowOpen', ("effect=fade time=200")),
                                    ('WindowClose', ("effect=fade time=1500"))
                                    ]

        img = xbmcgui.ControlImage(0, 0, 1280, 720, filename = _black, aspectRatio = 0)
        self.addControl(img)
        img.setAnimations(background_fade_animation)

        # Individual Camera positions setup
        urls = []
        files = []
        imgs = []
        imgs2 = []
        
        coords = [  (0, 0, 640, 360),   
                    (640, 0, 640, 360),
                    (0, 360, 640, 360),
                    (640, 360, 640, 360) ]
#        coords = [  (0, 480, 426, 240),
#                    (0, 0, 850, 480), 
#                    (426, 480, 426, 240),
#                    (850, 480, 426, 240), 
#                    (850, 240, 426, 240),  
#                    (850, 0, 426, 240) ]
					

        effect = ['slide', 'slide']
        time = [1200, 1000]
        tween = ['back', 'back']
        easing = ['Out', 'InOut']
        animations = [
                        [ ('WindowOpen', ("effect={0} start=-640,-360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0])),
                          ('WindowClose', ("effect={0} end=-640,-360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
                        [ ('WindowOpen', ("effect={0} start=640,-360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
                          ('WindowClose', ("effect={0} end=640,-360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
                        [ ('WindowOpen', ("effect={0} start=-640,360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
                          ('WindowClose', ("effect={0} end=-640,360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
                        [ ('WindowOpen', ("effect={0} start=640,360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
                          ('WindowClose', ("effect={0} end=640,360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ]
                        ]
#        animations = [
#                        [ ('WindowOpen', ("effect={0} start=-640,-360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0])),
#                          ('WindowClose', ("effect={0} end=-640,-360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
#                        [ ('WindowOpen', ("effect={0} start=640,-360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
#                          ('WindowClose', ("effect={0} end=640,-360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
#                        [ ('WindowOpen', ("effect={0} start=-640,360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
#                          ('WindowClose', ("effect={0} end=-640,360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
#                        [ ('WindowOpen', ("effect={0} start=640,360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
#                          ('WindowClose', ("effect={0} end=640,360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
#                        [ ('WindowOpen', ("effect={0} start=640,360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
#                          ('WindowClose', ("effect={0} end=640,360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ],
#                        [ ('WindowOpen', ("effect={0} start=640,360 time={1} tween={2} easing={3}").format( effect[0], time[0], tween[0], easing[0] )),
#                          ('WindowClose', ("effect={0} end=640,360 time={1} tween={2} easing={3}").format( effect[1], time[1], tween[1], easing[1] )) ]
#                        ]
						
						
						
        # Acquire all Enabled & Connected cameras
        enabled_cameras = settings.getAllEnabledCameras(monitor)

        # Logic to ensure enabled cameras are placed in the correct position
        threads = []
        for window_position in '1234':
#        for window_position in '123456':
            position = int(window_position) - 1

            # Sets the initial image to the loader gif
            img1 = xbmcgui.ControlImage(*coords[position], filename = _loader, aspectRatio = 0) 
            self.addControl(img1)  #Bug was seen here previously, hence the 'try' and this will need to be investigated in future
            img1.setAnimations(animations[position])

            # Connected and Enabled Camera
            if len(enabled_cameras) > position:
                img2 = xbmcgui.ControlImage(*coords[position], filename = '', aspectRatio = 0)
                self.addControl(img2)
                img2.setAnimations(animations[position])

                control = [img1, img2]

                with Camera(enabled_cameras[position]) as camera:
                    stream_type = camera.getStreamType(1)
                    url = camera.getStreamUrl(1, stream_type)
                    prefix = 'AllCamera'

                    if stream_type == 0:    #MJPEG
                        t = threading.Thread(target = self.getImagesMjpeg, args = (camera, url, control, prefix))
                        
                    elif stream_type == 2:  #MJPEG Interlaced
                        t = threading.Thread(target = self.getImagesMjpegInterlace, args = (camera, url, control, prefix))
                        
                    else:                   #Snapshot
                        t = threading.Thread(target = self.getImagesSnapshot, args = (camera, url, control, prefix))

                    threads.append(t)
                    t.start()
                

            # No Camera so set the place holder image    
            else:
                img1.setImage(_holder, useCache = False)  
                    
        if len(threads) > 0:
            self.doModal()    

            #while not monitor.abortRequested() and self.isRunning:       
            #    monitor.waitForAbort(1)

            monitor.maybe_resume_previous()
            monitor.waitForAbort(1)
            utils.remove_leftover_images('AllCamera')
            
        else:
            utils.log(2, 'Unable to start All Camera Player')
            utils.notify('Player did not start.  Check camera settings.')