src/foggycam.py
def perform_capture(self, config=None, camera=None, camera_path='', video_path=''):
        """Captures images and generates the video from them."""

        camera_buffer = defaultdict(list)

        while self.is_capturing:
            file_id = str(uuid.uuid4().hex)

            utc_date = datetime.utcnow()
            utc_millis_str = str(int(utc_date.timestamp())*1000)

            print ('Applied cache buster: ', utc_millis_str)

            image_url = self.nest_image_url.replace('#CAMERAID#', camera).replace('#CBUSTER#', utc_millis_str).replace('#WIDTH#', str(config.width))

            request = urllib.request.Request(image_url)
            request.add_header('accept', 'image/webp,image/apng,image/*,*/*;q=0.9')
            request.add_header('accept-encoding', 'gzip, deflate, br')
            request.add_header('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36')
            request.add_header('referer','https://home.nest.com/')
            request.add_header('authority','nexusapi-us1.camera.home.nest.com')

            try:
                response = self.merlin.open(request)
                time.sleep(5)

                with open(camera_path + '/' + file_id + '.jpg', 'wb') as image_file:
                    for chunk in response:
                        image_file.write(chunk)

                # Check if we need to compile a video
                if config.produce_video:
                    camera_buffer_size = len(camera_buffer[camera])
                    print ('[', threading.current_thread().name, '] INFO: Camera buffer size for ', camera, ': ', camera_buffer_size)

                    if camera_buffer_size < self.nest_camera_buffer_threshold:
                        camera_buffer[camera].append(file_id)
                    else:
                        camera_image_folder = os.path.join(self.local_path, camera_path)

                        # Build the batch of files that need to be made into a video.
                        file_declaration = ''
                        for buffer_entry in camera_buffer[camera]:
                            file_declaration = file_declaration + 'file \'' + camera_image_folder + '/' + buffer_entry + '.jpg\'\n'
                        concat_file_name = os.path.join(self.temp_dir_path, camera + '.txt')

                        # Make sure that the content is decoded

                        with open(concat_file_name, 'w') as declaration_file:
                            declaration_file.write(file_declaration)

                        # Check if we have ffmpeg locally
                        use_terminal = False
                        ffmpeg_path = ''

                        if shutil.which("ffmpeg"):
                            ffmpeg_path = 'ffmpeg'
                            use_terminal = True
                        else:
                            ffmpeg_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'tools', 'ffmpeg'))
                        
                        if use_terminal or (os.path.isfile(ffmpeg_path) and use_terminal is False):
                            print ('INFO: Found ffmpeg. Processing video!')
                            target_video_path = os.path.join(video_path, file_id + '.mp4')
                            process = Popen([ffmpeg_path, '-r', str(config.frame_rate), '-f', 'concat', '-safe', '0', '-i', concat_file_name, '-vcodec', 'libx264', '-crf', '25', '-pix_fmt', 'yuv420p', target_video_path], stdout=PIPE, stderr=PIPE)
                            process.communicate()
                            os.remove(concat_file_name)
                            print ('INFO: Video processing is complete!')

                            # Upload the video
                            storage_provider = AzureStorageProvider()

                            if bool(config.upload_to_azure):
                                print ('INFO: Uploading to Azure Storage...')
                                target_blob = 'foggycam/' + camera + '/' + file_id + '.mp4'
                                storage_provider.upload_video(account_name=config.az_account_name, sas_token=config.az_sas_token, container='foggycam', blob=target_blob, path=target_video_path)
                                print ('INFO: Upload complete.')

                            # If the user specified the need to remove images post-processing
                            # then clear the image folder from images in the buffer.
                            if config.clear_images:
                                for buffer_entry in camera_buffer[camera]:
                                    deletion_target = os.path.join(camera_path, buffer_entry + '.jpg')
                                    print ('INFO: Deleting ' + deletion_target)
                                    os.remove(deletion_target)
                        else:
                            print ('WARNING: No ffmpeg detected. Make sure the binary is in /tools.')

                        # Empty buffer, since we no longer need the file records that we're planning
                        # to compile in a video.
                        camera_buffer[camera] = []
            except urllib.request.HTTPError as err:
                if err.code == 403:
                    self.initialize_session()
                    self.login()
                    self.initialize_user()
            except Exception:
                print ('ERROR: Could not download image from URL:')
                print (image_url)

                traceback.print_exc()
Captures images and generates the video from them.
Captures images and generates the video from them.
Captures images and generates the video from them .
def perform_capture(self, config=None, camera=None, camera_path='', video_path=''):
        camera_buffer = defaultdict(list)
        while self.is_capturing:
            file_id = str(uuid.uuid4().hex)
            utc_date = datetime.utcnow()
            utc_millis_str = str(int(utc_date.timestamp())*1000)
            print ('Applied cache buster: ', utc_millis_str)
            image_url = self.nest_image_url.replace('#CAMERAID#', camera).replace('#CBUSTER#', utc_millis_str).replace('#WIDTH#', str(config.width))
            request = urllib.request.Request(image_url)
            request.add_header('accept', 'image/webp,image/apng,image/*,*/*;q=0.9')
            request.add_header('accept-encoding', 'gzip, deflate, br')
            request.add_header('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36')
            request.add_header('referer','https://home.nest.com/')
            request.add_header('authority','nexusapi-us1.camera.home.nest.com')
            try:
                response = self.merlin.open(request)
                time.sleep(5)
                with open(camera_path + '/' + file_id + '.jpg', 'wb') as image_file:
                    for chunk in response:
                        image_file.write(chunk)
                if config.produce_video:
                    camera_buffer_size = len(camera_buffer[camera])
                    print ('[', threading.current_thread().name, '] INFO: Camera buffer size for ', camera, ': ', camera_buffer_size)
                    if camera_buffer_size < self.nest_camera_buffer_threshold:
                        camera_buffer[camera].append(file_id)
                    else:
                        camera_image_folder = os.path.join(self.local_path, camera_path)
                        file_declaration = ''
                        for buffer_entry in camera_buffer[camera]:
                            file_declaration = file_declaration + 'file \'' + camera_image_folder + '/' + buffer_entry + '.jpg\'\n'
                        concat_file_name = os.path.join(self.temp_dir_path, camera + '.txt')
                        with open(concat_file_name, 'w') as declaration_file:
                            declaration_file.write(file_declaration)
                        use_terminal = False
                        ffmpeg_path = ''
                        if shutil.which("ffmpeg"):
                            ffmpeg_path = 'ffmpeg'
                            use_terminal = True
                        else:
                            ffmpeg_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'tools', 'ffmpeg'))
                        if use_terminal or (os.path.isfile(ffmpeg_path) and use_terminal is False):
                            print ('INFO: Found ffmpeg. Processing video!')
                            target_video_path = os.path.join(video_path, file_id + '.mp4')
                            process = Popen([ffmpeg_path, '-r', str(config.frame_rate), '-f', 'concat', '-safe', '0', '-i', concat_file_name, '-vcodec', 'libx264', '-crf', '25', '-pix_fmt', 'yuv420p', target_video_path], stdout=PIPE, stderr=PIPE)
                            process.communicate()
                            os.remove(concat_file_name)
                            print ('INFO: Video processing is complete!')
                            storage_provider = AzureStorageProvider()
                            if bool(config.upload_to_azure):
                                print ('INFO: Uploading to Azure Storage...')
                                target_blob = 'foggycam/' + camera + '/' + file_id + '.mp4'
                                storage_provider.upload_video(account_name=config.az_account_name, sas_token=config.az_sas_token, container='foggycam', blob=target_blob, path=target_video_path)
                                print ('INFO: Upload complete.')
                            if config.clear_images:
                                for buffer_entry in camera_buffer[camera]:
                                    deletion_target = os.path.join(camera_path, buffer_entry + '.jpg')
                                    print ('INFO: Deleting ' + deletion_target)
                                    os.remove(deletion_target)
                        else:
                            print ('WARNING: No ffmpeg detected. Make sure the binary is in /tools.')
                        camera_buffer[camera] = []
            except urllib.request.HTTPError as err:
                if err.code == 403:
                    self.initialize_session()
                    self.login()
                    self.initialize_user()
            except Exception:
                print ('ERROR: Could not download image from URL:')
                print (image_url)
                traceback.print_exc()
def perform_capture ( self , config = None , camera = None , camera_path = '' , video_path = '' ) : camera_buffer = defaultdict ( list ) while self . is_capturing : file_id = str ( uuid . uuid4 ( ) . hex ) utc_date = datetime . utcnow ( ) utc_millis_str = str ( int ( utc_date . timestamp ( ) ) * 1000 ) print ( 'Applied cache buster: ' , utc_millis_str ) image_url = self . nest_image_url . replace ( '#CAMERAID#' , camera ) . replace ( '#CBUSTER#' , utc_millis_str ) . replace ( '#WIDTH#' , str ( config . width ) ) request = urllib . request . Request ( image_url ) request . add_header ( 'accept' , 'image/webp,image/apng,image/*,*/*;q=0.9' ) request . add_header ( 'accept-encoding' , 'gzip, deflate, br' ) request . add_header ( 'user-agent' , 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36' ) request . add_header ( 'referer' , 'https://home.nest.com/' ) request . add_header ( 'authority' , 'nexusapi-us1.camera.home.nest.com' ) try : response = self . merlin . open ( request ) time . sleep ( 5 ) with open ( camera_path + '/' + file_id + '.jpg' , 'wb' ) as image_file : for chunk in response : image_file . write ( chunk ) if config . produce_video : camera_buffer_size = len ( camera_buffer [ camera ] ) print ( '[' , threading . current_thread ( ) . name , '] INFO: Camera buffer size for ' , camera , ': ' , camera_buffer_size ) if camera_buffer_size < self . nest_camera_buffer_threshold : camera_buffer [ camera ] . append ( file_id ) else : camera_image_folder = os . path . join ( self . local_path , camera_path ) file_declaration = '' for buffer_entry in camera_buffer [ camera ] : file_declaration = file_declaration + 'file \'' + camera_image_folder + '/' + buffer_entry + '.jpg\'\n' concat_file_name = os . path . join ( self . temp_dir_path , camera + '.txt' ) with open ( concat_file_name , 'w' ) as declaration_file : declaration_file . write ( file_declaration ) use_terminal = False ffmpeg_path = '' if shutil . which ( "ffmpeg" ) : ffmpeg_path = 'ffmpeg' use_terminal = True else : ffmpeg_path = os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ) , '..' , 'tools' , 'ffmpeg' ) ) if use_terminal or ( os . path . isfile ( ffmpeg_path ) and use_terminal is False ) : print ( 'INFO: Found ffmpeg. Processing video!' ) target_video_path = os . path . join ( video_path , file_id + '.mp4' ) process = Popen ( [ ffmpeg_path , '-r' , str ( config . frame_rate ) , '-f' , 'concat' , '-safe' , '0' , '-i' , concat_file_name , '-vcodec' , 'libx264' , '-crf' , '25' , '-pix_fmt' , 'yuv420p' , target_video_path ] , stdout = PIPE , stderr = PIPE ) process . communicate ( ) os . remove ( concat_file_name ) print ( 'INFO: Video processing is complete!' ) storage_provider = AzureStorageProvider ( ) if bool ( config . upload_to_azure ) : print ( 'INFO: Uploading to Azure Storage...' ) target_blob = 'foggycam/' + camera + '/' + file_id + '.mp4' storage_provider . upload_video ( account_name = config . az_account_name , sas_token = config . az_sas_token , container = 'foggycam' , blob = target_blob , path = target_video_path ) print ( 'INFO: Upload complete.' ) if config . clear_images : for buffer_entry in camera_buffer [ camera ] : deletion_target = os . path . join ( camera_path , buffer_entry + '.jpg' ) print ( 'INFO: Deleting ' + deletion_target ) os . remove ( deletion_target ) else : print ( 'WARNING: No ffmpeg detected. Make sure the binary is in /tools.' ) camera_buffer [ camera ] = [ ] except urllib . request . HTTPError as err : if err . code == 403 : self . initialize_session ( ) self . login ( ) self . initialize_user ( ) except Exception : print ( 'ERROR: Could not download image from URL:' ) print ( image_url ) traceback . print_exc ( )
Captures images and generates the video from them.
Captures images and generates the video from them .
"""Captures images and generates the video from them.""" # Check if we need to compile a video # Build the batch of files that need to be made into a video. # Make sure that the content is decoded # Check if we have ffmpeg locally # Upload the video # If the user specified the need to remove images post-processing # then clear the image folder from images in the buffer. # Empty buffer, since we no longer need the file records that we're planning # to compile in a video.
self
config
camera
camera_path
video_path