Example #1
0
 def _initPlayer(self, videoUrls):
     self.videoPlayers = []
     for playerId, videoUrl in enumerate(videoUrls):
         videoPlayer = VideoPlayer(playerId, videoUrl)
         self.maxFps = max(self.maxFps, videoPlayer.fps)
         self.maxFrameCount = max(self.maxFrameCount,
                                  videoPlayer.frameCount)
         self.videoPlayers.append(videoPlayer)
     self.videoWidget = VideoWidget(self.videoPlayers)
     for videoPlayer in self.videoPlayers:
         videoPlayer.setMaxFps(self.maxFps)
Example #2
0
    def __init__(self):
        super().__init__()

        assert len(self.UTILITY_SCORE) == len(self.VIDEO_BIT_RATE)
        # get video list
        vlc = video_list_collector()
        vlc.save_dir = self.VIDEO_TRACE
        vlc.load()
        self.video_list = vlc.get_trace_matrix(self.VIDEO_BIT_RATE)

        self.video_player = VideoPlayer(self.birate_list,self.video_list)
        self.buffer_thresh = self.video_player.buffer_thresh
        self.action_list = len(self.video_list)
        self.network_speed = np.zeros(self.HISTORY_SIZE)
        self.reset()
Example #3
0
 def play_video(self: 'Gui'):
     if not self.playing_video:
         self.playing_video = True
         self.video_player = VideoPlayer(self.playJpgFolder,
                                         self.playWavFile, 30)
         self.play_video_button.setText('Pause')
         self.video_player.play()
         self.play_video_button.setText('Play')
         self.playing_video = False
     else:
         self.keyboard_emulator.press('p')
         self.keyboard_emulator.release('p')
         self.video_paused = not self.video_paused
         if self.video_paused:
             self.play_video_button.setText('Play')
         else:
             self.play_video_button.setText('Pause')
Example #4
0
    def __init__(self, config_path):
        self._logger = getLogger("raspberry")
        self._logger.setLevel(INFO)
        formatter = Formatter(
            '%(asctime)s [%(name)s] %(levelname)s : %(message)s')
        stream_handler = StreamHandler()
        stream_handler.setLevel(INFO)
        stream_handler.setFormatter(formatter)
        self._logger.addHandler(stream_handler)
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

        self._logger.info("Initializing...")
        self.preference_checker = Preferences(config_path)
        self.video_player = VideoPlayer()
        self.tv_controller = TVController()

        self._logger.info("Ready")
Example #5
0
class TVApp:
    def __init__(self, config_path):
        self._logger = getLogger("raspberry")
        self._logger.setLevel(INFO)
        formatter = Formatter(
            '%(asctime)s [%(name)s] %(levelname)s : %(message)s')
        stream_handler = StreamHandler()
        stream_handler.setLevel(INFO)
        stream_handler.setFormatter(formatter)
        self._logger.addHandler(stream_handler)
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

        self._logger.info("Initializing...")
        self.preference_checker = Preferences(config_path)
        self.video_player = VideoPlayer()
        self.tv_controller = TVController()

        self._logger.info("Ready")

    def run(self):
        self._logger.info(
            "Waiting 1 min if you want to stop me before I go full screen...")
        time.sleep(60)

        self._logger.info("Starting all components now...")
        self.tv_controller.start(self.preference_checker.time_on_off)
        self.video_player.start(self.preference_checker.video_list)
        self.preference_checker.start()

        while True:
            time.sleep(120)

    def exit_gracefully(self, signum, frame):
        self._logger.info("Key pressed, exiting")
        self.tv_controller.stop()
        self.video_player.stop()
        self.preference_checker.stop()

        self._logger.info("End")
Example #6
0
    def _reload(self, load):
        if self.player != None:
            self.player.close()

        self.player = VideoPlayer()
        self.player.set_window_id(self.gui_controller.get_video_window_id())
        self.player.activate_video_callback(
            self.gui_controller.activate_video_area)
        self.player.open(self.exercise.get_video_path())
        self.player.set_callback(self._time_callback)
        self.paused = False
        self.gui_controller.activate_video_area(False)
        self.gui_controller.activate("loaded")
        self._update_word_list()
        self.timeUpdateThreadId = thread.start_new_thread(
            self.time_update_thread, ())

        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()
        else:
            self.pause()
Example #7
0
class Viewer(object):
    '''
    A high-level class for viewing any supported media type.
    Delegates viewing to the browser or video player depending on media
    type. The displaying is performed in a separate thread, so
    shutdown() must be called before killing the program to avoid
    errors upon program termination.
    '''

    DISPLAY_TIME_GRANULARITY = 1  # seconds
    BROWSER = Browser()
    PLAYER = VideoPlayer()

    VIEWERS = {
        Media.IMAGE: BROWSER,
        Media.WEB_PAGE: BROWSER,
        Media.VIDEO: PLAYER
    }

    def display_content(self, content, is_interrupted_func):
        self.logger = logging.getLogger(__name__)
        self.logger.debug('Viewer received content %s', content)
        viewer = self.VIEWERS[content.content_type]

        displayed_time = 0
        viewer.display_content(content)
        self.running = True

        while self.running and displayed_time < content.view_time:
            if is_interrupted_func(content):
                break
            time.sleep(self.DISPLAY_TIME_GRANULARITY)
            displayed_time += self.DISPLAY_TIME_GRANULARITY
            self.keep_alive(viewer, content)

        viewer.hide()
        self.logger.debug('Viewer finished displaying content %s', content)

    def keep_alive(self, viewer, content):
        if not viewer.is_alive():
            self.logger.debug('Resurrecting viewer for content %s', content)
            viewer.display_content(content)

    def shutdown(self):
        self.logger.debug('Viewer shutdown requested')
        self.running = False
        self.BROWSER.shutdown()
        self.PLAYER.shutdown()
        self.logger.debug('Viewer shutdown complete')
Example #8
0
def main():
    video_play_thread = [1]
    is_looking_thread = IsLookingThread(video_play_thread)
    video_player = VideoPlayer("tanioka.mp4")
    is_looking_thread.start()
    while (True):
        video_player.play()
        video_player.check_state(video_play_thread[0])
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
Example #9
0
    def _reload(self, load):
        if self.player != None:
            self.player.close()

        self.player = VideoPlayer()
        self.player.set_window_id(self.gui_controller.get_video_window_id())
        self.player.activate_video_callback(self.gui_controller.activate_video_area)
        self.player.open(self.exercise.get_video_path())
        self.player.set_callback(self._time_callback)
        self.paused = False
        self.gui_controller.activate_video_area(False)
        self.gui_controller.activate("loaded")
        self._update_word_list()
        self.timeUpdateThreadId = thread.start_new_thread(self.time_update_thread, ())

        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()
        else:
            self.pause()
Example #10
0
    def _setup_player(self, mode, data_source=None):
        self.config[CONFIG_KEY_MODE] = mode
        # Set data source if specified
        if data_source is not None:
            self.config[CONFIG_KEY_DATA_SOURCE] = data_source

        # Quit current player
        if self.player is not None:
            self.player.release()
            self.player = None

        if self.player is None:
            # Create new player
            if mode in [MODE_VIDEO, MODE_STREAM]:
                from video_player import VideoPlayer
                self.player = VideoPlayer(self.config)
            elif mode == MODE_WEBPAGE:
                from web_player import WebPlayer
                self.player = WebPlayer(self.config)
        else:
            self.player.mode = mode
            self.player.data_source = self.config[CONFIG_KEY_DATA_SOURCE]
Example #11
0
from video_player import VideoPlayer

video_input = 'input/project_dataset/frames/concert'
audio_samples = 'input/project_dataset/audio/concert.wav'

player = VideoPlayer(video_input, audio_samples, 30)
player.play()
    
    #if video file input
    if len(sys.argv) > 1:
        cameras = [CameraFinder.create_file_camera(sys.argv[1])]

    # else scan for available cameras
    else:       
        cameras = CameraFinder.get_available_cameras()
        print('Found {} cameras.'.format(len(cameras)))

    if len(cameras) > 0:
        # index of the currently active camera
        cam_index = 0

        # initialize video player
        player = VideoPlayer(cameras[cam_index], WINDOW_NAME, fourcc)
        player.play()

        while player.playing:
            if player.camera_defect:
                print('ERROR: Camera not responding. Removing it from the list.')
                print('ERROR: CAMERA_BACKEND:',
                      cameras[cam_index % len(cameras)].backend)
                player.stop()
                # remove the malfunctioning camera
                cameras.remove(cameras[cam_index % len(cameras)])
                player.change_camera(cameras[cam_index % len(cameras)])
                player.play()

            # handle input
            key_pressed = cv2.waitKey(1)
Example #13
0
 def refresh_caches(self):
     global _player
     _player=VideoPlayer()
     if not _standalone:
         self._get_data_for_first_video()
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1030, 481)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.video_player_original = VideoPlayer(self.centralwidget)
        self.video_player_original.setEnabled(True)
        self.video_player_original.setGeometry(QtCore.QRect(10, 40, 500, 360))
        self.video_player_original.setObjectName("video_player_original")
        self.video_player_result = VideoPlayer(self.centralwidget)
        self.video_player_result.setGeometry(QtCore.QRect(520, 40, 500, 360))
        self.video_player_result.setObjectName("video_player_result")
        self.input_min_length = QtWidgets.QSpinBox(self.centralwidget)
        self.input_min_length.setGeometry(QtCore.QRect(210, 410, 171, 24))
        self.input_min_length.setMaximum(10000)
        self.input_min_length.setProperty("value", 100)
        self.input_min_length.setObjectName("input_min_length")
        self.input_thresh = QtWidgets.QSpinBox(self.centralwidget)
        self.input_thresh.setGeometry(QtCore.QRect(20, 410, 171, 24))
        self.input_thresh.setMinimum(-99)
        self.input_thresh.setProperty("value", -40)
        self.input_thresh.setObjectName("input_thresh")
        self.button_convert = QtWidgets.QPushButton(self.centralwidget)
        self.button_convert.setGeometry(QtCore.QRect(830, 400, 181, 32))
        self.button_convert.setObjectName("button_convert")
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setGeometry(QtCore.QRect(510, -10, 20, 391))
        self.line.setFrameShape(QtWidgets.QFrame.VLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(180, 10, 200, 20))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(710, 10, 200, 20))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.line_2 = QtWidgets.QFrame(self.centralwidget)
        self.line_2.setGeometry(QtCore.QRect(-3, 370, 1041, 20))
        self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(30, 390, 181, 16))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(220, 390, 161, 20))
        self.label_4.setObjectName("label_4")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1030, 22))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.action_2 = QtWidgets.QAction(MainWindow)
        self.action_2.setObjectName("action_2")
        self.action_3 = QtWidgets.QAction(MainWindow)
        self.action_3.setObjectName("action_3")
        self.action_4 = QtWidgets.QAction(MainWindow)
        self.action_4.setObjectName("action_4")
        self.actionGithub = QtWidgets.QAction(MainWindow)
        self.actionGithub.setObjectName("actionGithub")
        self.menu.addAction(self.action_2)
        self.menu.addAction(self.action_3)
        self.menu_2.addAction(self.action_4)
        self.menu_2.addAction(self.actionGithub)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1030, 481)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.video_player_original = VideoPlayer(self.centralwidget)
        self.video_player_original.setEnabled(True)
        self.video_player_original.setGeometry(QtCore.QRect(10, 40, 500, 360))
        self.video_player_original.setObjectName("video_player_original")
        self.video_player_result = VideoPlayer(self.centralwidget)
        self.video_player_result.setGeometry(QtCore.QRect(520, 40, 500, 360))
        self.video_player_result.setObjectName("video_player_result")
        self.input_min_length = QtWidgets.QSpinBox(self.centralwidget)
        self.input_min_length.setGeometry(QtCore.QRect(210, 410, 171, 24))
        self.input_min_length.setMaximum(10000)
        self.input_min_length.setProperty("value", 100)
        self.input_min_length.setObjectName("input_min_length")
        self.input_thresh = QtWidgets.QSpinBox(self.centralwidget)
        self.input_thresh.setGeometry(QtCore.QRect(20, 410, 171, 24))
        self.input_thresh.setMinimum(-99)
        self.input_thresh.setProperty("value", -40)
        self.input_thresh.setObjectName("input_thresh")
        self.button_convert = QtWidgets.QPushButton(self.centralwidget)
        self.button_convert.setGeometry(QtCore.QRect(830, 400, 181, 32))
        self.button_convert.setObjectName("button_convert")
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setGeometry(QtCore.QRect(510, -10, 20, 391))
        self.line.setFrameShape(QtWidgets.QFrame.VLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(180, 10, 200, 20))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(710, 10, 200, 20))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.line_2 = QtWidgets.QFrame(self.centralwidget)
        self.line_2.setGeometry(QtCore.QRect(-3, 370, 1041, 20))
        self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(30, 390, 181, 16))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(220, 390, 161, 20))
        self.label_4.setObjectName("label_4")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1030, 22))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.action_2 = QtWidgets.QAction(MainWindow)
        self.action_2.setObjectName("action_2")
        self.action_3 = QtWidgets.QAction(MainWindow)
        self.action_3.setObjectName("action_3")
        self.action_4 = QtWidgets.QAction(MainWindow)
        self.action_4.setObjectName("action_4")
        self.actionGithub = QtWidgets.QAction(MainWindow)
        self.actionGithub.setObjectName("actionGithub")
        self.menu.addAction(self.action_2)
        self.menu.addAction(self.action_3)
        self.menu_2.addAction(self.action_4)
        self.menu_2.addAction(self.actionGithub)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(
            _translate("MainWindow", "MSE Automatic Pause Cutter"))
        self.input_min_length.setSuffix(_translate("MainWindow", " мс"))
        self.input_thresh.setSuffix(_translate("MainWindow", " Дб"))
        self.button_convert.setText(_translate("MainWindow", "Преобразовать"))
        self.label.setText(_translate("MainWindow", "Исходный файл"))
        self.label_2.setText(_translate("MainWindow", "Предпросмотр"))
        self.label_3.setText(_translate("MainWindow", "Минимальный порог"))
        self.label_4.setText(_translate("MainWindow", "Минимальная длина"))
        self.menu.setTitle(_translate("MainWindow", "Файл"))
        self.menu_2.setTitle(_translate("MainWindow", "Помощь"))
        self.action_2.setText(_translate("MainWindow", "Открыть"))
        self.action_3.setText(_translate("MainWindow", "Экспортировать"))
        self.action_4.setText(_translate("MainWindow", "Об авторах"))
        self.actionGithub.setText(_translate("MainWindow", "Github"))
Example #16
0
class Env():

    BITRATE_TRACE = 'bitrate_list'
    VIDEO_TRACE = 'video_list'
    HISTORY_SIZE = 7
    BUFFER_NORM_FACTOR = 10.0
    CHUNK_TIL_VIDEO_END_CAP = 60.0
    M_IN_K = 1000.0
    REBUF_PENALTY = 10  # 1 sec rebuffering -> 3 Mbps
    SMOOTH_PENALTY = 1
    DEFAULT_QUALITY = 1  # default video quality without agent
    # video bitrate is used as a ultility reward for each bitrate level so this can be change however fit
    UTILITY_SCORE = [300,700,1200,1500,3000,4000,5000]
    VIDEO_BIT_RATE = [300,700,1200,1500,3000,4000,5000] # unit is bit
    
    birate_list = pickle.load(open(BITRATE_TRACE,'rb'))

    def __init__(self):
        super().__init__()

        assert len(self.UTILITY_SCORE) == len(self.VIDEO_BIT_RATE)
        # get video list
        vlc = video_list_collector()
        vlc.save_dir = self.VIDEO_TRACE
        vlc.load()
        self.video_list = vlc.get_trace_matrix(self.VIDEO_BIT_RATE)

        self.video_player = VideoPlayer(self.birate_list,self.video_list)
        self.buffer_thresh = self.video_player.buffer_thresh
        self.action_list = len(self.video_list)
        self.network_speed = np.zeros(self.HISTORY_SIZE)
        self.reset()

    def action_space(self):
        return self.action_list

    def reset(self, mode = 'train'):    
        next_video_chunk_size = self.video_player.reset(mode = mode)
        self.last_action = self.DEFAULT_QUALITY
        self.network_speed = np.zeros(self.HISTORY_SIZE)
        self.state = np.append(self.network_speed, 0)       #net speed , buffer
        self.state = np.append(self.state, 0)               #chunk remain
        self.state = np.append(self.state, next_video_chunk_size / 1e6) #next options
        self.state = np.append(self.state, 0)               #last action
        terminate = False
        reward = 0
        return self.state

    def process_trace(self,data):
        data = copy.deepcopy(data)
        data.pop("next_seg")
        data.pop("segment")
        terminate = data["terminate"]
        data.pop("terminate", None)
        reshape = [v for v in data.values()]
        data = np.array(reshape)
        return data, terminate
    
    def cal_reward(self, action, rebuf):
        reward = self.UTILITY_SCORE[action] / self.M_IN_K \
                    - self.REBUF_PENALTY * rebuf \
                    - self.SMOOTH_PENALTY * np.abs(self.UTILITY_SCORE[action]
                    - self.UTILITY_SCORE[self.last_action]) / self.M_IN_K

        return reward

    def get_sep_reward(self, action, rebuf):
        quality = self.UTILITY_SCORE[action] / self.M_IN_K
        rebuf_pen = self.REBUF_PENALTY * rebuf
        switch_pen = self.SMOOTH_PENALTY * np.abs(self.UTILITY_SCORE[action]
                    - self.UTILITY_SCORE[self.last_action]) / self.M_IN_K

        return quality, rebuf_pen, switch_pen


    def step(self,action, sep = False):
        last_state = self.state
        delay, sleep_time, buffer_size, rebuf, \
        video_chunk_size, next_video_chunk_sizes, \
        end_of_video, video_chunk_remain = \
            self.video_player.download(action)

        reward = self.cal_reward(action, rebuf)
        quality, rebuf_pen, switch_pen = self.get_sep_reward(action, rebuf)
        self.last_action = action
        net_speed = video_chunk_size / (delay - sleep_time)
        self.network_speed = np.roll(self.network_speed,axis = -1,shift = 1)
        self.network_speed[0] = net_speed / 1e6
        self.state = np.append(self.network_speed, buffer_size * 0.1)
        self.state = np.append(self.state, video_chunk_remain * 0.1)
        self.state = np.append(self.state, next_video_chunk_sizes / 1e7)
        self.state = np.append(self.state, self.last_action * 0.1)
        
        return self.state,reward, end_of_video, [quality,rebuf_pen,switch_pen], delay
Example #17
0
class VideoQueryGUI(ttk.Frame):
    FORCE_CREATE = False

    def __init__(self, master):
        super(VideoQueryGUI, self).__init__()
        self.master = master
        master.title("CSCI 576 Project")
        master.wm_protocol("WM_DELETE_WINDOW", self.onClose)

        self.folders = [x[0] for x in os.walk(config.DB_VID_ROOT)][1:]
        self.query_scores = None

        self.create_frames()
        self.load_db_thread = threading.Thread(target=self.load_database,
                                               name='database loader')
        self.load_db_thread.start()

    def load_database(self):
        self.update_status('>>> Loading DB videos', clear=True)
        print('Started')
        print('=' * 80)
        print('Database video list')
        print('-' * 80)
        print('\n'.join(
            ['%d. %s' % (i + 1, f) for (i, f) in enumerate(self.folders)]))
        print('=' * 80)

        self.db_vids = []
        for selected_folder in self.folders:
            self.update_status('>>> DB video selected: ' + selected_folder)
            pkl_path = glob.glob(os.path.join(selected_folder, '*.pkl'))
            if len(pkl_path) and not self.FORCE_CREATE:
                tic = time.time()
                self.update_status('>>> Loading pre-calculated features')
                with open(pkl_path[0], 'rb') as pkl_fp:
                    v = pickle.load(pkl_fp)
                self.update_status('>>> Done. Time taken: %0.4fs' %
                                   (time.time() - tic))
            else:
                tic = time.time()
                self.update_status('>>> Loading video')
                vid_path = selected_folder
                aud_path = glob.glob(os.path.join(selected_folder, '*.wav'))[0]
                v = Video(vid_path, aud_path)
                self.update_status('>>> Done. Time taken: %0.4fs' %
                                   (time.time() - tic))

                # Computing features
                tic = time.time()
                self.update_status('>>> Calculating video features')
                extract_features(v)
                self.update_status('>>> Calculated in %0.4fs' %
                                   (time.time() - tic))

                self.update_status('>>> Saving results to database')
                with open(os.path.join(selected_folder, '%s.pkl' % v.name),
                          'wb') as pkl_fp:
                    pickle.dump(v, pkl_fp)
            self.db_vids.append(v)
            self.update_status('>>> Saved results to database')

    def create_frames(self):
        # Top frame
        self.top_frame = tk.LabelFrame(self.master, text='', bg="#E9E9E9")
        self.top_frame.pack(side='top', expand=True, fill='both')

        self.load_query_button = ttk.Button(self.top_frame,
                                            text='Load Query',
                                            command=self.load_query_video)
        self.load_query_button.grid(row=0, column=0, padx=0, pady=0)

        self.find_matches_button = ttk.Button(self.top_frame,
                                              text='Find matches',
                                              command=self.run_match)
        self.find_matches_button.grid(row=1, column=0, padx=0, pady=0)

        self.match_list = tk.Listbox(self.top_frame, height=4, bd=0)
        self.yscroll = tk.Scrollbar(self.top_frame, orient=tk.VERTICAL)
        self.match_list['yscrollcommand'] = self.yscroll.set
        self.match_list.grid(row=0, column=1, rowspan=2, stick='wens')
        self.yscroll.grid(row=0, column=1, rowspan=2, sticky='nse')
        self.match_list.bind('<Double-Button-1>', self.poll_match_list)
        self.curr_selection = -1

        self.top_frame.grid_columnconfigure(0, weight=1)
        self.top_frame.grid_columnconfigure(1, weight=2)

        # Middle frame
        self.middle_frame = tk.LabelFrame(self.master, text='')
        self.middle_frame.pack(side='top', expand=True, fill='both')

        self.status_label_text = tk.StringVar()
        self.status_label_text.set('LOGS')
        self.status_label = tk.Label(self.middle_frame,
                                     textvar=self.status_label_text,
                                     justify=tk.LEFT,
                                     anchor='w',
                                     wraplength=700,
                                     bg="black",
                                     fg="#C1E0FD")
        self.status_label.grid(row=0, column=0, stick='nswe', columnspan=2)

        self.middle_frame.grid_columnconfigure(0, weight=1)
        self.middle_frame.grid_columnconfigure(1, weight=1)

        self.query_player = VideoPlayer(self.middle_frame)
        self.query_player.grid(row=1, column=0, stick='nsw')
        self.db_player = VideoPlayer(self.middle_frame)
        self.db_player.grid(row=1, column=1, stick='nse')

        # Bottom frame
        self.bottom_frame = tk.LabelFrame(self.master, text='')
        self.bottom_frame.pack(side='top', expand=True, fill='both')

        self.match_info_label_text = tk.StringVar()
        # self.match_info_label_text.set('MATCH INFORMATION')
        self.match_info_label = tk.Label(self.bottom_frame,
                                         textvar=self.match_info_label_text,
                                         justify=tk.LEFT,
                                         anchor='e')
        self.match_info_label.grid(row=0, column=0, stick='nswe')

        image = cv2.imread(
            "/Users/nikhiljohny/Documents/_CSCI576Project/codebase/master/graph_place_holder.png"
        )
        width = 365
        height = 280
        dim = (width, height)
        image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = Image.fromarray(image)
        image = ImageTk.PhotoImage(image)

        self.panelA = tk.Label(self.bottom_frame,
                               image=image,
                               width=365,
                               height=280)
        self.panelA.image = image
        self.panelA.grid(row=0, column=1, stick='nse', padx=0, pady=0)
        self.bottom_frame.grid_columnconfigure(0, weight=1)
        self.bottom_frame.grid_columnconfigure(1, weight=1)

    def load_query_video(self):
        selected_folder = None
        self.master.update()
        selected_folder = askdirectory(initialdir=config.QUERY_VID_ROOT,
                                       title='Select query folder')
        # selected_folder = askopenfilename(
        #     initialdir=config.QUERY_VID_ROOT, title='Select query folder')
        self.update_status('>>> Selected: ' + selected_folder)

        if selected_folder == '':
            return

        self.query_loader = threading.Thread(target=self.load_query,
                                             args=(selected_folder, ),
                                             name='query_loader')
        self.query_loader.start()

        # while self.query_loader.is_alive():
        #     self.update_idletasks()

    def load_query(self, selected_folder=None):
        self.update_status('>>> Loading query video', clear=True)
        if selected_folder == None:
            selected_folder = os.path.join(config.QUERY_VID_ROOT,
                                           'subclip_traffic')
            # selected_folder = askdirectory(
            #     initialdir=config.QUERY_VID_ROOT, title='Select query folder')
            # print(selected_folder)
        self.update_status('>>> Query video selected: ' + selected_folder)
        # print('Selected '+selected_folder)

        pkl_path = glob.glob(os.path.join(selected_folder, 'query_scores.pkl'))

        # print(pkl_path)

        if len(pkl_path) and not self.FORCE_CREATE:
            vid_pkl_path = [
                pth
                for pth in glob.glob(os.path.join(selected_folder, '*.pkl'))
                if not os.path.basename(pth).startswith('query_scores')
            ]
            tic = time.time()
            self.update_status('>>> Loading pre-calculated metrics')
            # print('Loading pre-calculated comparison metrics')
            with open(pkl_path[0], 'rb') as pkl_fp:
                self.query_scores = pickle.load(pkl_fp)
            with open(vid_pkl_path[0], 'rb') as pkl_fp:
                self.query_vid = pickle.load(pkl_fp)
            self.update_status('>>> Done. Time taken: %0.4fs' %
                               (time.time() - tic))
        else:
            pkl_path = [
                pth
                for pth in glob.glob(os.path.join(selected_folder, '*.pkl'))
                if not os.path.basename(pth).startswith('query_scores')
            ]

            if len(pkl_path) and not self.FORCE_CREATE:
                tic = time.time()
                self.update_status('>>> Loading pre-calculated features')
                with open(pkl_path[0], 'rb') as pkl_fp:
                    self.query_vid = pickle.load(pkl_fp)
                self.update_status('>>> Done. Time taken: %0.4fs' %
                                   (time.time() - tic))
            else:
                # Loading query video
                tic = time.time()
                vid_path = selected_folder
                aud_path = glob.glob(os.path.join(selected_folder, '*.wav'))[0]
                self.update_status('>>> Loading query video %s' %
                                   os.path.basename(vid_path))
                self.query_vid = Video(vid_path, aud_path)

                # Computing features
                tic = time.time()
                self.update_status('>>> Calculating video features')
                # print('Calculating video features')
                extract_features(self.query_vid)
                self.update_status('>>> Calculated in %0.4fs' %
                                   (time.time() - tic))
                # print('Calculated in %0.4fs' % (time.time()-tic))

                self.update_status('>>> Creating pickle file for query video')
                with open(
                        os.path.join(selected_folder,
                                     '%s.pkl' % self.query_vid.name),
                        'wb') as pkl_fp:
                    pickle.dump(self.query_vid, pkl_fp)

            self.query_scores = {}
            for i, db_vid in enumerate(self.db_vids):
                self.update_status('>>> Comparing features with %s' %
                                   db_vid.name)
                tic = time.time()
                self.query_scores[db_vid.name] = compare_features(
                    self.query_vid, db_vid)
                self.update_status(
                    '>>> Feature comparison completed in %0.4fs' %
                    (time.time() - tic))

            self.update_status('>>> Saving results to database')
            with open(os.path.join(selected_folder, 'query_scores.pkl'),
                      'wb') as pkl_fp:
                pickle.dump(self.query_scores, pkl_fp)
            self.update_status('>>> Saved results to database')

        self.query_player.load_video(self.query_vid)

    def run_match(self):
        if self.query_scores is None:
            self.update_status('>>> No query video selected', clear=True)
            return
        self.update_status('>>> Running query in database', clear=True)
        self.final_ranks = rank_features(self.query_scores)
        display_plot(
            self.final_ranks, "graph",
            "/Users/nikhiljohny/Documents/_CSCI576Project/codebase/master/graph"
        )
        generate_plots(
            self.final_ranks, "temp",
            "/Users/nikhiljohny/Documents/_CSCI576Project/codebase/master/temp"
        )

        start_fr = np.argmax(self.final_ranks[0][3])
        query_vid_len = len(self.db_vids[0].frames) - len(
            self.final_ranks[0][3]) + 1

        self.update_match_info('')
        self.update_match_info('Best Match Video: {}'.format(
            self.final_ranks[0][0]))
        self.update_match_info('Start Frame: {}'.format(start_fr))
        self.update_match_info('End Frame: {}'.format(start_fr +
                                                      query_vid_len))
        start_time = round(start_fr / config.FRAME_RATE)
        self.update_match_info('Start Time: {}'.format(start_time))
        end_time = round(float(start_fr + query_vid_len) / config.FRAME_RATE)
        self.update_match_info('End Time: {}'.format(end_time))

        self.update_status('>>> Final scores computed')
        image = cv2.imread(
            "/Users/nikhiljohny/Documents/_CSCI576Project/codebase/master/graph/graph_final.png"
        )
        width = 365
        height = 280
        dim = (width, height)
        image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = Image.fromarray(image)
        image = ImageTk.PhotoImage(image)
        self.panelA.configure(image=image)
        self.panelA.image = image

        self.update_status('>>> Ranked list of matches generated')
        self.match_list.delete(0, tk.END)
        i = 0
        matchlist = [x[0] for x in self.final_ranks]
        for match in matchlist:
            final_score = str(round(self.final_ranks[i][1], 4))
            match = '{} | {}'.format(match, final_score)
            self.match_list.insert(tk.END, match)
            i = i + 1

        self.poll_match_list()

    def poll_match_list(self, event=None):
        current = self.match_list.curselection()[0]
        # print(current)
        if current != self.curr_selection:
            self.update_status('>>> Video selected: ' +
                               self.final_ranks[current][0])
            curr_video = self.find_matching_db_vid(
                self.final_ranks[current][0])
            self.db_player.load_video(curr_video)
            plot = generate_plots(self.final_ranks[current])

            self.corr_plot = resize(plot, (100, 356, 3),
                                    preserve_range=True).astype('uint8')
            self.curr_selection = current
        self.master.after(250, self.poll_match_list)

    def find_matching_db_vid(self, vidname):
        for vid in self.db_vids:
            if vid.name == vidname:
                return vid
        else:
            return None

    def update_status(self, text, clear=False):
        if clear:
            status_text = '\t\t\t\t         LOGS\n\n%s' % text
        else:
            status_text = '%s\n%s' % (self.status_label_text.get(), text)
        lines = status_text.split('\n')
        if len(lines) < 6:
            status_text = '\n'.join(lines + [''] * (6 - len(lines)))
        elif len(lines) > 6:
            status_text = '\n'.join([lines[0]] + lines[-5:])
        self.status_label_text.set(status_text)

    def update_match_info(self, text, clear=False):
        if clear:
            match_info_text = 'MATCH INFORMATION:\n%s' % text
        else:
            match_info_text = '%s\n%s' % (self.match_info_label_text.get(),
                                          text)
        lines = match_info_text.split('\n')
        if len(lines) < 6:
            match_info_text = '\n'.join(lines + [''] * (6 - len(lines)))
        elif len(lines) > 6:
            match_info_text = '\n'.join([lines[0]] + lines[-5:])
        self.match_info_label_text.set(match_info_text)

    def onClose(self):
        self.query_player.onClose()
        self.db_player.onClose()
        self.master.quit()
Example #18
0
class Square(Scatter):
    app = ObjectProperty( None )
    geometry_id = NumericProperty(None)#location on the field where the Square sits
    #content
    id = StringProperty('')
    title = StringProperty(None)
    app_type = StringProperty(None) #'info', 'service', 'jeu'
    color = ObjectProperty( (.82,.82,.82,1) )
    color_text = ObjectProperty( (.82,.82,.82,1) )
    color_down = ObjectProperty( (1,1,0,1) )
    color_up = ObjectProperty( (.1,.1,.1,1) )
    authors = StringProperty(None)
    main_media_type = StringProperty(None) #'image' or 'video' or 'webpage'
    image_path = StringProperty(None)
    video_path = StringProperty(None)
    webpage_path = StringProperty("http://www.google.com")
    vote_feedback = NumericProperty(0) #value between 0 and 1
    #shape
    rotation_90d = NumericProperty(0)
    layout_type = StringProperty(None) #'icon'/'small'/'medium' or 'large'
    icon_size = ObjectProperty( None )
    small_size = ObjectProperty( None )
    medium_size = ObjectProperty( None )
    large_size = ObjectProperty( None )
    #internal variables
    touches = DictProperty( {} ) #current active touches on the widget
    #buttons = DictProperty( {} ) #store buttons widgets
    square_parameters = DictProperty( {} ) #initial parameters of the square
    texture_path = StringProperty("")
    layout = ObjectProperty( None )#base layout for all the widgets
    layers = DictProperty( {} )#stores background text layers of each size
    layer_texture_path = ObjectProperty( None )
    process_touch_up_forbidden = BooleanProperty(False)
    padding = NumericProperty(10) #square layout padding
    berkelium_is_installed = BooleanProperty(False)

    def __init__(self,**kwargs) :

        super(Square,self).__init__(**kwargs)

        l,h = self.size
        pad = self.padding
        self.layout = BoxLayout(orientation = 'vertical', size = (l -2*pad,h -2*pad), pos = (pad,pad) )           
        self.init_layouts() 

          
    
    def on_start(self, a):
        try :
            self.parent.mute(self.uid) #mute other parents' video players
        except:
            pass
        self.video.unmute(1) #unmute the player

    def on_unmute(self,a):
        try :
            self.parent.mute(self.uid)                
        except : 
            pass

    def mute(self):
        if self.main_media_type == 'video':
            self.video.mute(1)
 
    def on_fullscreen(self, a):
        self.video.stop(1)
        vid = self.video
        x,y = vid.pos
        self.parent.play_video_fullscreen(self.video_path, self.to_parent(x,y) , self.video.size, self.video.video.position)
        
    def on_leave_fullscreen(self, a):
        pass 

    def process_font_size(self, text, font_size):
        #in case the text is multiline, reduce the font size
        multiline = False
        for i in text : 
            if i == '\n' : multiline = True
        if not multiline : return font_size
        else : return font_size - 6            

    def init_layouts(self):

        def layers2texture(layers, berkelium):
            #convert either an image or an html webpage to texture
            #to be used as a background by the square
            converted_layers = {}
            bk = {}
            for key,path in layers.iteritems():
                #fileName, fileExtension = os.path.splitext(path)
                #if fileName[4] in ['http','file']: #fileExtension in ['.org','.com','.fr','.html','.htm'] :
                if path[:4] in ['http','file']:
                    if self.berkelium_is_installed == False : return None
                    size = (600,600)
                    bk[key] = berkelium.Webbrowser(url=path, size=size)
                    texture = bk[key]._bk.texture
                    converted_layers[key] = texture
                    #finally delete the berkelium instance
                    del bk[key]   
                else :
                    from kivy.uix.image import Image
                    img = Image(source=path)
                    texture = img.texture
                    converted_layers[key] = texture
            #print path, texture
            return converted_layers   
        
        #load berkelium
        berkelium = None
        if self.berkelium_is_installed == True : 
            from kivy.ext import load
            berkelium = load('berkelium', (1, 1))            

        #extract textures from layouts
        self.layers = layers2texture(self.layers, berkelium)

        #get current layout
        layout_type = self.layout_type
        param = self.square_parameters[layout_type] #load parameters specific to that size (small, medium, large)
        
        #color
        a,b,c,d = self.color_up
        
        ######################### LAYOUT ##########################################################
        
        self.texture_path = texture_path = str(param['texture_path']) #self.style['square_texture_path']
        #text layer
        self.layer_texture_path = self.layers[layout_type]
        """
        from kivy.uix.image import Image
        self.layer = Image(source = "apps/layers/xyz/large.png", size_hint = (1,1))
        self.layout.add_widget(self.layer)
        """         
        #top part : Title, app_type, authors
        self.box_top = BoxLayout(size_hint = param['box_top_size_hint'] )#orientation = 'horizontal', 
        font_size = self.process_font_size( self.title, int( param['title_label_font_size']) )
        text_size = (len(self.title)*font_size +100,None )
        self.title_label = Label( text=self.title, font_size = font_size, color = self.color_text, halign = 'left', valign = 'top',text_size = text_size, padding = (5,0) ) #font_name = 'DEJAVU SANS CONDENSED', bold = False
        self.box2 = BoxLayout(orientation = 'horizontal',  size_hint = (None,1) , width = self.title_label.text_size[0], pos_hint={'top': 1,'left':1} )
        #self.app_type_pic = Image(source = str(self.app_type), pos_hint={'top': 1,'right':1}, size_hint = (1,3) )
        #self.box3 = AnchorLayout( anchor_x = 'right', anchor_y = 'bottom')
        #self.authors_label = Label(text = self.authors, font_size = int( param['authors_label_font_size'] ), pos_hint ={'right':1},  color = self.color_text, halign = 'right') #, pos_hint={'bottom': 1,'right':1} )        
        self.box2.add_widget(self.title_label)
        self.box_top.add_widget(self.box2)
        #self.box3.add_widget(self.authors_label)
        #self.box_top.add_widget(self.box3)
        self.layout.add_widget( self.box_top )
        
        #middle part : Image or Video
        self.box_middle = BoxLayout(orientation = 'horizontal', size_hint = param['box_middle_size_hint'] )
        self.box_middle1 = BoxLayout(orientation = 'horizontal', size_hint = param['box_middle1_size_hint'], padding = 0, spacing = 0 )
        self.box_middle2 = BoxLayout(orientation = 'horizontal', size_hint = param['box_middle2_size_hint'], padding = 0, spacing = 0 )
        self.box_middle.add_widget( self.box_middle1 ) 
        self.box_middle.add_widget( self.box_middle2 )
 
        if self.main_media_type == 'webpage' :
            #berkelium installed was already checked by field
            try : 
                self.webpage = berkelium.Webbrowser(url=self.webpage_path, size=(50,50) )
                self.box_middle1.add_widget( self.webpage ) 
            except :
                print 'Cannot load url: '+str(self.webpage_path)
                self.main_media_type = 'image'
            
        if self.main_media_type == 'image' : 
            from kivy.uix.image import Image
            image = Image(source = self.image_path, allow_stretch = True, keep_ratio = False, size_hint = (1,1), pos_hint={'left': 1, 'top' : 1} )
            self.box_middle1.add_widget( image ) 

        elif self.main_media_type == 'video' :
            #if self.main_media_type == 'video' :
            self.video = VideoPlayer(source = self.video_path)
            self.video.bind(on_unmute =self.on_unmute)
            self.video.bind(on_start=self.on_start)
            self.video.bind(on_fullscreen = self.on_fullscreen)
            self.video.bind(on_leave_fullscreen = self.on_leave_fullscreen)
            self.box_middle1.add_widget( self.video ) 
        
        self.layout.add_widget( self.box_middle ) 

        #Bottom part : buttons
        self.box_bottom = BoxLayout(orientation = 'horizontal', size_hint = param['box_bottom_size_hint'] )
        self.subbox = BoxLayout(orientation = 'horizontal' )
        self.box_bottom.padding = int( param['box_bottom_padding'] ) #box.height*0.15 
        self.vote_button = SuperButton(background_normal = 'style/square/bouton-vote-T2-off.png', background_down = 'style/square/bouton-vote-T2-on.png', size_hint = (None,None), size=param["vote_button_size"] )
        self.vote_button.bind( on_press = self.vote ) 
        self.subbox.add_widget( self.vote_button )
        #vote feedback
        from kivy.uix.image import Image
        self.fb = Image(source = 'style/square/like'+self.convert_vote_feedback()+'.png', size_hint=(None,None), size=param["vote_feedback_size"])
        self.subbox.add_widget( self.fb )
        self.box_bottom.add_widget(self.subbox)
        self.launch_button = SuperButton(background_normal = 'style/square/bouton-lancer-T2-off.png',background_down = 'style/square/bouton-lancer-T2-on.png', size_hint = (None,None), size=param["launch_button_size"] ) 
        self.launch_button.bind( on_press = self.launch ) 
        self.box_bottom.add_widget( self.launch_button )
        self.box_bottom.spacing = (self.layout.width - self.vote_button.width - self.launch_button.width)*0.97
        self.layout.add_widget( self.box_bottom )

        self.add_widget(self.layout)
        #Clock.schedule_once(self.update_canvas, 4)

    def convert_vote_feedback(self):
        vf = self.vote_feedback
        if vf > 1 : vf =1
        elif vf < 0 : vf = 0
        vf = int(vf*6)
        return str(vf)    

    def layout_type2size(self,layout_type) :
        #print layout_type
        pad = self.padding
        if layout_type == 'large':
            l,h = self.large_size
            s = (l -2*pad,h -2*pad)
        elif layout_type == 'medium': 
            l,h = self.medium_size
            s = (l -2*pad,h -2*pad)
        elif layout_type == 'small': 
            l,h = self.small_size
            s = (l -2*pad,h -2*pad)
        elif layout_type == 'icon': 
            l,h = self.icon_size
            s = (l -2*pad,h -2*pad)
        return s     
    
    def refresh_layout(self, layout_type) :
        size = self.layout_type2size(layout_type)
        pad = self.padding
        self.layout_type = layout_type
        
        kwargs = {'duration' : 1.1,'t':'in_quart'}
        anim = Animation(pos = (pad,pad), size = size, **kwargs)
        anim.start(self.layout)
        
        #refresh background texture
        Clock.schedule_once(self.refresh_background, 1.1)
    
    def refresh_background(self, a):
        self.texture_path = str( self.square_parameters[self.layout_type]['texture_path'] )
        self.layer_texture_path = self.layers[self.layout_type]
    
    def launch(self,a):
        self.app.appview.launch_app(id, self.title)

    def vote(self,a):
        print 'vote for app ' + self.title
        self.vote_feedback += 0.05
        self.fb.source = 'style/square/like'+ self.convert_vote_feedback() +'.png'        
    
    def on_touch_down(self, touch):
        #analyse and store touches so that we know on_touch_up which
        #square was concerned by the touch_up 
        if self.collide_point(touch.x,touch.y):
            self.touches[touch.id] = touch
            #enlarge a bit
            self.reshape_when_touch_down(touch, 0)     
        super(Square, self).on_touch_down(touch)  
    
    def on_touch_up(self, touch):
        super(Square, self).on_touch_up(touch)
        if not touch.id in self.touches : return
        del self.touches[touch.id]

        if self.collide_point(touch.x,touch.y):
            #print self.rotation
            if not self.process_touch_up_forbidden : 
                self.parent.process_touch_up(self)
            #reduce size a bit
            self.reshape_when_touch_up(touch)  
            return True   
    
    def reshape_when_touch_down(self, touch, intensity):
        self.color = self.color_down
        self.pos = (self.x + intensity, self.y + intensity)
        #self.title_label.color = self.color_up
        self.texture_path = 'style/square/square_'+str(self.layout_type)+'_touch_down.png'
        #self.app_type_label.color = self.color_up
        #self.size = (self.width + 3, self.height + 3)
        #a = Animation(center = self.center, size = self.size)
        #a.start(self)

    def reshape_when_touch_up(self, touch):
        self.color = self.color_up
        #self.title_label.color = self.color_down
        #self.app_type_label.color = self.color_up
        self.texture_path = 'style/square/square_'+str(self.layout_type)+'.png'
        pass

    def update_canvas(self,a):
        self.canvas.ask_update()
Example #19
0
    def init_layouts(self):

        def layers2texture(layers, berkelium):
            #convert either an image or an html webpage to texture
            #to be used as a background by the square
            converted_layers = {}
            bk = {}
            for key,path in layers.iteritems():
                #fileName, fileExtension = os.path.splitext(path)
                #if fileName[4] in ['http','file']: #fileExtension in ['.org','.com','.fr','.html','.htm'] :
                if path[:4] in ['http','file']:
                    if self.berkelium_is_installed == False : return None
                    size = (600,600)
                    bk[key] = berkelium.Webbrowser(url=path, size=size)
                    texture = bk[key]._bk.texture
                    converted_layers[key] = texture
                    #finally delete the berkelium instance
                    del bk[key]   
                else :
                    from kivy.uix.image import Image
                    img = Image(source=path)
                    texture = img.texture
                    converted_layers[key] = texture
            #print path, texture
            return converted_layers   
        
        #load berkelium
        berkelium = None
        if self.berkelium_is_installed == True : 
            from kivy.ext import load
            berkelium = load('berkelium', (1, 1))            

        #extract textures from layouts
        self.layers = layers2texture(self.layers, berkelium)

        #get current layout
        layout_type = self.layout_type
        param = self.square_parameters[layout_type] #load parameters specific to that size (small, medium, large)
        
        #color
        a,b,c,d = self.color_up
        
        ######################### LAYOUT ##########################################################
        
        self.texture_path = texture_path = str(param['texture_path']) #self.style['square_texture_path']
        #text layer
        self.layer_texture_path = self.layers[layout_type]
        """
        from kivy.uix.image import Image
        self.layer = Image(source = "apps/layers/xyz/large.png", size_hint = (1,1))
        self.layout.add_widget(self.layer)
        """         
        #top part : Title, app_type, authors
        self.box_top = BoxLayout(size_hint = param['box_top_size_hint'] )#orientation = 'horizontal', 
        font_size = self.process_font_size( self.title, int( param['title_label_font_size']) )
        text_size = (len(self.title)*font_size +100,None )
        self.title_label = Label( text=self.title, font_size = font_size, color = self.color_text, halign = 'left', valign = 'top',text_size = text_size, padding = (5,0) ) #font_name = 'DEJAVU SANS CONDENSED', bold = False
        self.box2 = BoxLayout(orientation = 'horizontal',  size_hint = (None,1) , width = self.title_label.text_size[0], pos_hint={'top': 1,'left':1} )
        #self.app_type_pic = Image(source = str(self.app_type), pos_hint={'top': 1,'right':1}, size_hint = (1,3) )
        #self.box3 = AnchorLayout( anchor_x = 'right', anchor_y = 'bottom')
        #self.authors_label = Label(text = self.authors, font_size = int( param['authors_label_font_size'] ), pos_hint ={'right':1},  color = self.color_text, halign = 'right') #, pos_hint={'bottom': 1,'right':1} )        
        self.box2.add_widget(self.title_label)
        self.box_top.add_widget(self.box2)
        #self.box3.add_widget(self.authors_label)
        #self.box_top.add_widget(self.box3)
        self.layout.add_widget( self.box_top )
        
        #middle part : Image or Video
        self.box_middle = BoxLayout(orientation = 'horizontal', size_hint = param['box_middle_size_hint'] )
        self.box_middle1 = BoxLayout(orientation = 'horizontal', size_hint = param['box_middle1_size_hint'], padding = 0, spacing = 0 )
        self.box_middle2 = BoxLayout(orientation = 'horizontal', size_hint = param['box_middle2_size_hint'], padding = 0, spacing = 0 )
        self.box_middle.add_widget( self.box_middle1 ) 
        self.box_middle.add_widget( self.box_middle2 )
 
        if self.main_media_type == 'webpage' :
            #berkelium installed was already checked by field
            try : 
                self.webpage = berkelium.Webbrowser(url=self.webpage_path, size=(50,50) )
                self.box_middle1.add_widget( self.webpage ) 
            except :
                print 'Cannot load url: '+str(self.webpage_path)
                self.main_media_type = 'image'
            
        if self.main_media_type == 'image' : 
            from kivy.uix.image import Image
            image = Image(source = self.image_path, allow_stretch = True, keep_ratio = False, size_hint = (1,1), pos_hint={'left': 1, 'top' : 1} )
            self.box_middle1.add_widget( image ) 

        elif self.main_media_type == 'video' :
            #if self.main_media_type == 'video' :
            self.video = VideoPlayer(source = self.video_path)
            self.video.bind(on_unmute =self.on_unmute)
            self.video.bind(on_start=self.on_start)
            self.video.bind(on_fullscreen = self.on_fullscreen)
            self.video.bind(on_leave_fullscreen = self.on_leave_fullscreen)
            self.box_middle1.add_widget( self.video ) 
        
        self.layout.add_widget( self.box_middle ) 

        #Bottom part : buttons
        self.box_bottom = BoxLayout(orientation = 'horizontal', size_hint = param['box_bottom_size_hint'] )
        self.subbox = BoxLayout(orientation = 'horizontal' )
        self.box_bottom.padding = int( param['box_bottom_padding'] ) #box.height*0.15 
        self.vote_button = SuperButton(background_normal = 'style/square/bouton-vote-T2-off.png', background_down = 'style/square/bouton-vote-T2-on.png', size_hint = (None,None), size=param["vote_button_size"] )
        self.vote_button.bind( on_press = self.vote ) 
        self.subbox.add_widget( self.vote_button )
        #vote feedback
        from kivy.uix.image import Image
        self.fb = Image(source = 'style/square/like'+self.convert_vote_feedback()+'.png', size_hint=(None,None), size=param["vote_feedback_size"])
        self.subbox.add_widget( self.fb )
        self.box_bottom.add_widget(self.subbox)
        self.launch_button = SuperButton(background_normal = 'style/square/bouton-lancer-T2-off.png',background_down = 'style/square/bouton-lancer-T2-on.png', size_hint = (None,None), size=param["launch_button_size"] ) 
        self.launch_button.bind( on_press = self.launch ) 
        self.box_bottom.add_widget( self.launch_button )
        self.box_bottom.spacing = (self.layout.width - self.vote_button.width - self.launch_button.width)*0.97
        self.layout.add_widget( self.box_bottom )

        self.add_widget(self.layout)
Example #20
0
class Gui(QWidget):
    def __init__(self: 'Gui'):
        super().__init__()
        self.title = 'CSCI 576 Final Project'
        self.left = 0
        self.top = 0
        self.width = 1000
        self.height = 360

        self.jpgFolder = None
        self.rgbFolder = None
        self.wavFile = None

        self.playJpgFolder = None
        self.playWavFile = None

        self.threadpool = QThreadPool()

        self.playing_video = False
        self.video_paused = False

        self.keyboard_emulator = Controller()

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Evaluator Progress Bar
        self.evaluator_progress_bar = self.createProgressBarPercent()

        # Box Layout
        self.windowLayout = QVBoxLayout()

        # Options are to choose folders for video evaluation or play existing video
        self.online_mode_widget = self.createOnlineModeButtons()
        self.offline_mode_widget = self.createOfflineModeButtons()

        # Add buttons
        self.windowLayout.addWidget(self.online_mode_widget)
        self.windowLayout.addWidget(self.offline_mode_widget)

        # Set layout and show
        self.setLayout(self.windowLayout)
        self.show()

    def createProgressBarPercent(self: 'Gui') -> QProgressBar:
        progress_bar = QProgressBar()
        progress_bar.setMinimum(0)
        progress_bar.setMaximum(100)
        return progress_bar

    def createOnlineModeButtons(self: 'Gui') -> QGroupBox:
        onlineModeGroup = QGroupBox(
            "Choose your JPG, RGB, and WAV Files/Folders for video evaluation")
        onlineModeGroup.setFixedHeight(250)

        groupLayout = QVBoxLayout()

        pathLayout = QHBoxLayout()
        jpgBox = QVBoxLayout()
        self.jpgLabel = QLabel()
        jpgBox.addWidget(
            self.createButton('Choose JPG Folder', self.setJpgFolder))
        jpgBox.addWidget(self.jpgLabel)
        pathLayout.addLayout(jpgBox)

        rgbBox = QVBoxLayout()
        self.rgbLabel = QLabel()
        rgbBox.addWidget(
            self.createButton('Choose RGB Folder', self.setRgbFolder))
        rgbBox.addWidget(self.rgbLabel)
        pathLayout.addLayout(rgbBox)

        wavBox = QVBoxLayout()
        self.wavLabel = QLabel()
        wavBox.addWidget(self.createButton('Choose WAV File', self.setWavFile))
        wavBox.addWidget(self.wavLabel)
        pathLayout.addLayout(wavBox)
        groupLayout.addLayout(pathLayout)

        evalLayout = QHBoxLayout()
        evalBox = QVBoxLayout()
        self.evaluatorProgressLabel = QLabel()
        evalBox.addWidget(
            self.createButton('Evaluate Video', self.evaulate_video))
        evalBox.addWidget(self.evaluator_progress_bar)
        evalBox.addWidget(self.evaluatorProgressLabel)
        evalLayout.addLayout(evalBox)
        groupLayout.addLayout(evalLayout)

        playLayout = QHBoxLayout()
        playBox = QVBoxLayout()
        self.play_converted_video_button = self.createButton(
            'Play', self.play_converted_video)
        playBox.addWidget(self.play_converted_video_button)
        playLayout.addLayout(playBox)
        groupLayout.addLayout(playLayout)

        onlineModeGroup.setLayout(groupLayout)

        return onlineModeGroup

    @pyqtSlot()
    def setJpgFolder(self: 'Gui'):
        self.jpgFolder = self.getFolderPathDialog('JPG Folder') + '/'
        self.jpgLabel.setText('/'.join(self.jpgFolder.split('/')[-5:]))

    @pyqtSlot()
    def setRgbFolder(self: 'Gui'):
        self.rgbFolder = self.getFolderPathDialog('RGB Folder') + '/'
        self.rgbLabel.setText('/'.join(self.rgbFolder.split('/')[-5:]))

    @pyqtSlot()
    def setWavFile(self: 'Gui'):
        self.wavFile = self.getFilePathDialog('WAV File',
                                              'WAV Audio Files (*.wav)')
        self.wavLabel.setText('/'.join(self.wavFile.split('/')[-4:]))

    def createOfflineModeButtons(self: 'Gui') -> QGroupBox:
        groupBox = QGroupBox(
            "Or choose your JPG Folder and WAV File for Video Play")
        groupBox.setFixedHeight(100)
        layout = QHBoxLayout()

        jpgBox = QVBoxLayout()
        self.playJpgLabel = QLabel()
        jpgBox.addWidget(
            self.createButton('Choose JPG Folder', self.setPlayJpgFolder))
        jpgBox.addWidget(self.playJpgLabel)
        layout.addLayout(jpgBox)

        wavBox = QVBoxLayout()
        self.playWavLabel = QLabel()
        wavBox.addWidget(
            self.createButton('Choose WAV File', self.setPlayWavFile))
        wavBox.addWidget(self.playWavLabel)
        layout.addLayout(wavBox)

        playBox = QVBoxLayout()
        self.play_video_button = self.createButton('Play', self.play_video)
        playBox.addWidget(self.play_video_button)
        playBox.addWidget(QLabel())
        layout.addLayout(playBox)

        groupBox.setLayout(layout)

        return groupBox

    @pyqtSlot()
    def play_video(self: 'Gui'):
        if not self.playing_video:
            self.playing_video = True
            self.video_player = VideoPlayer(self.playJpgFolder,
                                            self.playWavFile, 30)
            self.play_video_button.setText('Pause')
            self.video_player.play()
            self.play_video_button.setText('Play')
            self.playing_video = False
        else:
            self.keyboard_emulator.press('p')
            self.keyboard_emulator.release('p')
            self.video_paused = not self.video_paused
            if self.video_paused:
                self.play_video_button.setText('Play')
            else:
                self.play_video_button.setText('Pause')

    @pyqtSlot()
    def setPlayJpgFolder(self: 'Gui'):
        self.playJpgFolder = self.getFolderPathDialog('JPG Folder') + '/'
        self.playJpgLabel.setText('/'.join(self.playJpgFolder.split('/')[-4:]))

    @pyqtSlot()
    def setPlayWavFile(self: 'Gui'):
        self.playWavFile = self.getFilePathDialog('WAV File',
                                                  'WAV Audio Files (*.wav)')
        self.playWavLabel.setText('/'.join(self.playWavFile.split('/')[-3:]))

    def createButton(self: 'Gui', label: str, callback) -> QPushButton:
        button = QPushButton(label, self)
        button.clicked.connect(callback)
        return button

    def getFolderPathDialog(self: 'Gui', caption: str) -> str or None:
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        options |= QFileDialog.ShowDirsOnly
        dirname = QFileDialog.getExistingDirectory(self,
                                                   caption,
                                                   directory=os.getcwd(),
                                                   options=options)
        return dirname

    def getFilePathDialog(self: 'Gui', caption: str,
                          filter: str) -> str or None:
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,
                                                  caption,
                                                  directory=os.getcwd(),
                                                  filter=filter,
                                                  options=options)
        return fileName

    @pyqtSlot()
    def evaulate_video(self: 'Gui'):
        worker = EvaluatorWorker(self.rgbFolder, self.wavFile)
        worker.signals.finished_with_results.connect(self.evaluation_complete)
        worker.signals.report_progress.connect(self.setProgress)
        self.threadpool.start(worker)

    def setProgress(self: 'Gui', information: Tuple[str, float]):
        label = information[0]
        percentComplete = information[1]
        progress = max(min(100, round(100 * percentComplete)), 0)
        print(label)
        print(progress)

        self.evaluatorProgressLabel.setText(label)

        # Trying this to prevent obscure error
        time.sleep(1)

        self.evaluator_progress_bar.setValue(progress)

    def evaluation_complete(self: 'Gui', information: Tuple[list, Wav]):
        frame_nums_to_write = information[0]
        audio = information[1]
        self.frame_nums_to_write = frame_nums_to_write
        self.audio = audio

    def play_converted_video(self: 'Gui'):
        self.converter.play()

    @pyqtSlot()
    def play_converted_video(self: 'Gui'):
        if not self.playing_video:
            self.playing_video = True
            converter = VideoConverter(self.frame_nums_to_write, self.jpgFolder, self.audio.data, 30, \
                                       self.audio.rate, self.audio.sampwidth)
            self.play_converted_video_button.setText('Pause')
            converter.play()
            self.play_converted_video_button.setText('Play')
            self.playing_video = False
        else:
            self.keyboard_emulator.press('p')
            self.keyboard_emulator.release('p')
            self.video_paused = not self.video_paused
            if self.video_paused:
                self.play_converted_video_button.setText('Play')
            else:
                self.play_converted_video_button.setText('Pause')
Example #21
0
class Core(object):
    WAIT_BEGIN = 0
    WAIT_END = 1

    def __init__(self):
        self.player = None
        self.last_save = False
        self.exercise = None
        self.config = config
        self.logger = logging.Logger("Core")
        self.logger.setLevel(defaultLoggingLevel)
        self.logger.addHandler(defaultLoggingHandler)

    #Call by the main, give an handler to the main gui
    def set_gui(self, gui):
        self.gui_controller = gui

    #Create a new exercice based on paths. load the new exercise and
    #begin to play
    def new_exercise(self, videoPath, exercisePath, translationPath, langId):
        self.exercise = Exercise()
        self.exercise.set_media_change_callback(self.media_change_call_back)
        self.exercise.new()
        self.exercise.set_language_id(langId)
        self._set_paths(videoPath, exercisePath,
                        translationPath)  # This initialize the exercise
        self._reload(True)
        self._activate_sequence()
        self.gui_controller.set_title("", True)

    #Configure the paths for the current exercice. Reload subtitles list.
    def _set_paths(self, videoPath, exercisePath, translationPath):
        self.exercise.set_video_path(videoPath)
        self.exercise.set_exercise_path(exercisePath)
        self.exercise.set_translation_path(translationPath)
        self.exercise.initialize()

    #Reload media player and begin to play (if the params is True)
    def _reload(self, load):
        if self.player != None:
            self.player.close()

        self.player = VideoPlayer()
        self.player.set_window_id(self.gui_controller.get_video_window_id())
        self.player.activate_video_callback(
            self.gui_controller.activate_video_area)
        self.player.open(self.exercise.get_video_path())
        self.player.set_callback(self._time_callback)
        self.paused = False
        self.gui_controller.activate_video_area(False)
        self.gui_controller.activate("loaded")
        self._update_word_list()
        self.timeUpdateThreadId = thread.start_new_thread(
            self.time_update_thread, ())

        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()
        else:
            self.pause()

    #play the media
    def play(self):
        self.gui_controller.set_playing(True)
        self.player.play()
        self.paused = False

    #pause the media
    def pause(self):
        self.gui_controller.set_playing(False)
        self.player.pause()
        self.paused = True

    #Modify media speed
    def set_speed(self, speed):
        self.gui_controller.set_speed(speed)
        self.player.set_speed(speed)

    #Callback call by video player to notify change of media position.
    #Stop the media at the end of uncompleted sequences
    def _time_callback(self):
        if self.state == Core.WAIT_BEGIN:
            self.player.set_next_callback_time(
                self.exercise.get_current_sequence().get_time_end() +
                self.exercise.get_play_margin_after())
            self.state = Core.WAIT_END
        elif self.state == Core.WAIT_END:
            self.state = Core.WAIT_BEGIN
            if self.exercise.get_current_sequence().is_valid():
                gtk.gdk.threads_enter()
                self.next_sequence(False)
                gtk.gdk.threads_leave()
            else:
                self.pause()

    #Repeat the currence sequence
    def repeat_sequence(self):
        if not self.exercise.is_current_sequence_repeat_limit_reach():
            #Repeat limit not reach or no limit
            self.goto_sequence_begin()
            self.play()
            self.exercise.increment_current_sequence_repeat_count()

    #Change the active sequence
    def select_sequence(self, num, load=True):
        if self.exercise.get_current_sequence_id() == num:
            return
        self.exercise.goto_sequence(num)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()
        self.set_can_save(True)

    #Goto next sequence
    def next_sequence(self, load=True):
        if self.exercise.goto_next_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Goto previous sequence
    def previous_sequence(self, load=True):
        if self.exercise.goto_previous_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Goto next valid sequence
    def next_valid_sequence(self, load=True):
        if self.exercise.goto_next_valid_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Goto previous valid sequence
    def previous_valid_sequence(self, load=True):
        if self.exercise.goto_previous_valid_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Update interface with new sequence. Configure stop media callback
    def _activate_sequence(self):
        self.state = Core.WAIT_BEGIN
        self.set_speed(1)
        self.player.set_next_callback_time(
            self.exercise.get_current_sequence().get_time_begin() -
            self.exercise.get_play_margin_before())

        self.gui_controller.set_sequence_number(
            self.exercise.get_current_sequence_id(),
            self.exercise.get_sequence_count())
        self.gui_controller.set_sequence(self.exercise.get_current_sequence())
        self.__activate_translation()
        self.__activate_previous_sequence_text()
        self._update_stats()

    #_update displayed translation on new active sequence
    def __activate_translation(self):
        if not self.exercise.get_translation_list():
            self.gui_controller.set_translation("")
        else:
            translation = ""
            currentBegin = self.exercise.get_current_sequence().get_time_begin(
            )
            currentEnd = self.exercise.get_current_sequence().get_time_end()
            for sub in self.exercise.get_translation_list():
                begin = sub.get_time_begin()
                end = sub.get_time_end()
                if (begin >= currentBegin and begin <= currentEnd) or (
                        end >= currentBegin
                        and end <= currentEnd) or (begin <= currentBegin
                                                   and end >= currentEnd):
                    translation += sub.get_text() + " "

            self.gui_controller.set_translation(translation)

    #_update displayed previous sentence text
    def __activate_previous_sequence_text(self):
        previous_sequence_text = ""
        previous_sequence = self.exercise.get_previous_sequence()
        if previous_sequence:
            for i, symbol in enumerate(previous_sequence.get_symbols()):
                previous_sequence_text += symbol
                if i < len(previous_sequence.get_words()):
                    word = previous_sequence.get_words()[i]
                    if word.is_valid():
                        previous_sequence_text += word.get_valid(lower=False)
                    else:
                        word_text = word.get_text()
                        if len(word_text):
                            previous_sequence_text += word.get_text()
                        else:
                            previous_sequence_text += "_"

        self.gui_controller.set_previous_sequence_text(previous_sequence_text)

    #Update displayed stats on new active sequence
    def _update_stats(self):
        sequenceCount = self.exercise.get_sequence_count()
        sequenceFound = 0
        wordCount = 0
        wordFound = 0
        for sequence in self.exercise.get_sequence_list():
            wordCount = wordCount + sequence.get_word_count()
            if sequence.is_valid():
                sequenceFound += 1
                wordFound += sequence.get_word_count()
            else:
                wordFound += sequence.get_word_found()
        if wordFound == 0:
            repeatRate = float(0)
        else:
            repeatRate = float(
                self.exercise.get_repeat_count()) / float(wordFound)
        self.gui_controller.set_statitics(sequenceCount, sequenceFound,
                                          wordCount, wordFound, repeatRate)

    def _update(self):
        self.gui_controller.set_sequence(self.exercise.get_current_sequence())
        self.__validate_sequence()

    #Verify if the sequence is complete
    def __validate_sequence(self):
        if self.exercise.get_current_sequence().is_valid():
            if self.exercise.get_repeat_after_completed():
                if self.exercise.get_repeat_count_limit_by_sequence() == 0:
                    #Auto start play only if repeat is not limited
                    self.repeat_sequence()
            else:
                self.next_sequence(load=False)
                if self.exercise.get_repeat_count_limit_by_sequence() == 0:
                    #Auto start play only if repeat is not limited
                    if self.player.get_seek(
                    ) > (self.exercise.get_current_sequence().get_time_begin()
                         - self.exercise.get_play_margin_before()):
                        self.goto_sequence_begin()
                        self.play()
                    else:
                        self.play()

    #Goto beginning of the current sequence. Can start to play as soon
    #as the media player is ready
    def goto_sequence_begin(self, asSoonAsReady=False):
        self.state = Core.WAIT_END
        begin_time = self.exercise.get_current_sequence().get_time_begin(
        ) - self.exercise.get_play_margin_before()
        if begin_time < 0:
            begin_time = 0
        if asSoonAsReady:
            self.player.seek_as_soon_as_ready(begin_time)
        else:
            self.player.seek(begin_time)
        self.player.set_next_callback_time(
            self.exercise.get_current_sequence().get_time_end() +
            self.exercise.get_play_margin_after())

    #Write a char in current sequence at cursor position
    def write_char(self, char):
        if self.exercise.is_character_match(char):
            self.exercise.get_current_sequence().write_char(char)
            self.exercise.get_current_sequence().update_cursor_position()
            self._update()
            self.set_can_save(True)
        else:
            self._update()

    #Goto next word in current sequence
    def next_word(self):
        self.exercise.get_current_sequence().next_word()
        self._update()

    #Goto previous word in current sequence
    def previous_word(self):
        self.exercise.get_current_sequence().previous_word()
        self._update()

    #Choose current word in current sequence
    def select_sequence_word(self, wordIndex, wordIndexPos):
        try:
            self.exercise.get_current_sequence().select_sequence_word(
                wordIndex, wordIndexPos)
        except NoCharPossible:
            self.exercise.get_current_sequence().select_sequence_word(
                wordIndex, -1)
        self._update()

    #Goto first word in current sequence
    def first_word(self):
        self.exercise.get_current_sequence().first_word()
        self._update()

    #Goto last word in current sequence
    def last_word(self):
        self.exercise.get_current_sequence().last_word()
        self._update()

    #Delete a char before the cursor in current sequence
    def delete_previous_char(self):
        self.exercise.get_current_sequence().delete_previous_char()
        self._update()
        self.set_can_save(True)

    #Delete a char after the cursor in current sequence
    def delete_next_char(self):
        self.exercise.get_current_sequence().delete_next_char()
        self._update()
        self.set_can_save(True)

    #Goto previous char in current sequence
    def previous_char(self):
        self.exercise.get_current_sequence().previous_char()
        #The sequence don't change but the cursor position is no more up to date
        self._update()

    #Goto next char in current sequence
    def next_char(self):
        self.exercise.get_current_sequence().next_char()
        #The sequence don't change but the cursor position is no more up to date
        self._update()

    #Reveal correction for word at cursor in current sequence
    def complete_word(self):
        self.exercise.get_current_sequence().show_hint()
        self._update()
        self.set_can_save(True)

    #Reveal correction for word at cursor in current sequence
    def reveal_word(self):
        self.exercise.get_current_sequence().complete_word()
        self.exercise.get_current_sequence().next_word()
        self._update()
        self.set_can_save(True)

    #Reveal correction for word at cursor in current sequence
    def reveal_sequence(self):
        self.exercise.get_current_sequence().complete_all()
        self._update()
        self.set_can_save(True)

    #reset whole exercise
    def reset_exercise_content(self):
        self.exercise.reset()
        self.exercise.goto_sequence(0)  #FIXME
        self._update()
        self.set_can_save(True)
        self.logger.debug("need to stop the current sequence")  #FIXME

    #pause or play media
    def toggle_pause(self):
        if self.player.is_paused() and self.paused:
            self.play()
        elif not self.player.is_paused() and not self.paused:
            self.pause()

    #Change position in media and play it
    def seek_sequence(self, time):
        begin_time = self.exercise.get_current_sequence().get_time_begin(
        ) - self.exercise.get_play_margin_before()
        if begin_time < 0:
            begin_time = 0

        pos = begin_time + time
        self.player.seek(pos)
        self.player.set_next_callback_time(
            self.exercise.get_current_sequence().get_time_end() +
            self.exercise.get_play_margin_after())
        self.state = Core.WAIT_END
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    #Thread to update slider position in gui
    def time_update_thread(self):
        timeUpdateThreadId = self.timeUpdateThreadId
        while timeUpdateThreadId == self.timeUpdateThreadId:
            time.sleep(0.5)
            pos_int = self.player.get_current_time()
            if pos_int != None:
                end_time = self.exercise.get_current_sequence().get_time_end()
                begin_time = self.exercise.get_current_sequence(
                ).get_time_begin() - self.exercise.get_play_margin_before()
                if begin_time < 0:
                    begin_time = 0
                duration = end_time - begin_time
                pos = pos_int - begin_time
                self.gui_controller.set_sequence_time(pos, duration)

    #Save current exercice
    def save(self, saveAs=False):
        if not self.exercise:
            self.logger.error("Save called but no exercise load")
            return

        if saveAs or self.exercise.get_output_save_path() == None:
            outputSavePath = self.gui_controller.ask_save_path()
            if not outputSavePath:
                return
            self.exercise.set_output_save_path(outputSavePath + ".perroquet")

        save_exercise(self.exercise, self.exercise.get_output_save_path())

        self.config.set("lastopenfile", self.exercise.get_output_save_path())

        #lastopenfileS
        l = self.config.get("lastopenfiles")
        path = self.exercise.get_output_save_path()
        name = self.exercise.get_name() or path
        self.config.set("lastopenfiles",
                        [[path, name]] + [p for p in l if p[0] != path][:10])

        self.set_can_save(False)

    #load the exercice at path
    def load_exercise(self, path):
        self.gui_controller.activate("closed")
        if self.exercise:
            self.save()
        try:
            self.exercise = load_exercise(path)
            self.exercise.set_media_change_callback(
                self.media_change_call_back)
        except IOError:
            self.logger.exception("No file at " + path)
            return
        if not self.exercise:
            return

        validPaths, errorList = self.exercise.is_paths_valid()
        if not validPaths:
            for error in errorList:
                self.gui_controller.signal_exercise_bad_path(error)

            self.set_can_save(False)
            self.gui_controller.activate("load_failed")
            self.gui_controller.ask_properties()
            return

        self._reload(False)
        if self.exercise.get_output_save_path() == None:
            self.set_can_save(True)
        else:
            self.set_can_save(False)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    #Change paths of current exercice and reload subtitles and video
    def _update_paths(self, videoPath, exercisePath, translationPath):
        self.exercise.set_video_path(videoPath)
        self.exercise.set_exercise_path(exercisePath)
        self.exercise.set_translation_path(translationPath)

        validPaths, errorList = self.exercise.is_paths_valid()
        if not validPaths:
            for error in errorList:
                self.gui_controller.signal_exercise_bad_path(error)
            self.gui_controller.activate("load_failed")
            self.set_can_save(False)
            return

        self._set_paths(videoPath, exercisePath, translationPath)
        self._reload(True)
        self.set_can_save(True)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    def update_properties(self):
        self.exercise.initialize()
        self._reload(True)
        self.set_can_save(True)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    #get paths of current exercise
    def get_paths(self):
        return (self.exercise.get_video_path(),
                self.exercise.get_exercise_path(),
                self.exercise.get_translation_path())

    #Udpates vocabulary list in interface
    def _update_word_list(self):
        self.gui_controller.set_word_list(self.exercise.extract_word_list())

    #Notify the user use the repeat command (for stats)
    def user_repeat(self):
        self.exercise.increment_repeat_count()
        self.set_can_save(True)

    #Signal to the gui that the exercise has unsaved changes
    def set_can_save(self, save):
        self.gui_controller.set_can_save(save)

        if self.exercise == None:
            title = ""
        elif self.exercise.get_name() != None:
            title = self.exercise.get_name()
        elif self.exercise.get_output_save_path() != None:
            title = self.exercise.get_output_save_path()
        else:
            title = _("Untitled exercise")

        self.last_save = save
        self.gui_controller.set_title(title, save)

    def get_can_save(self):
        return self.last_save

    def get_exercise(self):
        return self.exercise

    def get_player(self):
        return self.player

    def media_change_call_back(self):
        self.logger.info("new media : " + self.exercise.get_video_path())
        """self.Pause()
        self.player.open(self.exercise.get_video_path())
        """
        self._reload(True)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    def export_as_template(self):
        self.gui_controller.ask_properties_advanced()
        path = self.gui_controller.ask_export_as_template_path()
        if path:
            self.exercise.set_template(True)
            save_exercise(self.exercise, path)
            self.exercise.set_template(False)

    def export_as_package(self):
        self.gui_controller.ask_properties_advanced()
        path = self.gui_controller.ask_export_as_package_path()
        if path:
            repoManager = ExerciseRepositoryManager()
            repoManager.export_as_package(self.exercise, path)
            self.logger.info("Export done")
        else:
            self.logger.warn("No valid path to export??")

    def import_package(self):
        import_path = self.gui_controller.ask_import_package()

        if import_path is not None:
            repo_manager = ExerciseRepositoryManager()
            error = repo_manager.import_package(import_path)
            if error is None:
                self.gui_controller.display_message(
                    _("Import finish succesfully. Use the exercises manager to use the newly installed exercise."
                      ))
            else:
                self.gui_controller.display_message(
                    _("Import failed." + " " + error))
Example #22
0
class Core(object):
    WAIT_BEGIN = 0
    WAIT_END = 1

    def __init__(self):
        self.player = None
        self.last_save = False
        self.exercise = None
        self.config = config
        self.logger = logging.Logger("Core")
        self.logger.setLevel(defaultLoggingLevel)
        self.logger.addHandler(defaultLoggingHandler)

    #Call by the main, give an handler to the main gui
    def set_gui(self, gui):
        self.gui_controller = gui

    #Create a new exercice based on paths. load the new exercise and
    #begin to play
    def new_exercise(self, videoPath, exercisePath, translationPath, langId):
        self.exercise = Exercise()
        self.exercise.set_media_change_callback(self.media_change_call_back)
        self.exercise.new()
        self.exercise.set_language_id(langId)
        self._set_paths(videoPath, exercisePath, translationPath) # This initialize the exercise
        self._reload(True);
        self._activate_sequence()
        self.gui_controller.set_title("", True)

    #Configure the paths for the current exercice. Reload subtitles list.
    def _set_paths(self, videoPath, exercisePath, translationPath):
        self.exercise.set_video_path(videoPath)
        self.exercise.set_exercise_path(exercisePath)
        self.exercise.set_translation_path(translationPath)
        self.exercise.initialize()

    #Reload media player and begin to play (if the params is True)
    def _reload(self, load):
        if self.player != None:
            self.player.close()

        self.player = VideoPlayer()
        self.player.set_window_id(self.gui_controller.get_video_window_id())
        self.player.activate_video_callback(self.gui_controller.activate_video_area)
        self.player.open(self.exercise.get_video_path())
        self.player.set_callback(self._time_callback)
        self.paused = False
        self.gui_controller.activate_video_area(False)
        self.gui_controller.activate("loaded")
        self._update_word_list()
        self.timeUpdateThreadId = thread.start_new_thread(self.time_update_thread, ())

        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()
        else:
            self.pause()

    #play the media
    def play(self):
        self.gui_controller.set_playing(True)
        self.player.play()
        self.paused = False

    #pause the media
    def pause(self):
        self.gui_controller.set_playing(False)
        self.player.pause()
        self.paused = True

    #Modify media speed
    def set_speed(self, speed):
        self.gui_controller.set_speed(speed)
        self.player.set_speed(speed)

    #Callback call by video player to notify change of media position.
    #Stop the media at the end of uncompleted sequences
    def _time_callback(self):
        if self.state == Core.WAIT_BEGIN:
            self.player.set_next_callback_time(self.exercise.get_current_sequence().get_time_end() + self.exercise.get_play_margin_after())
            self.state = Core.WAIT_END
        elif self.state == Core.WAIT_END:
            self.state = Core.WAIT_BEGIN
            if self.exercise.get_current_sequence().is_valid():
                gtk.gdk.threads_enter()
                self.next_sequence(False)
                gtk.gdk.threads_leave()
            else:
                self.pause()

    #Repeat the currence sequence
    def repeat_sequence(self):
        if not self.exercise.is_current_sequence_repeat_limit_reach():
            #Repeat limit not reach or no limit
            self.goto_sequence_begin()
            self.play()
            self.exercise.increment_current_sequence_repeat_count()


    #Change the active sequence
    def select_sequence(self, num, load=True):
        if self.exercise.get_current_sequence_id() == num:
            return
        self.exercise.goto_sequence(num)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()
        self.set_can_save(True)

    #Goto next sequence
    def next_sequence(self, load=True):
        if self.exercise.goto_next_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Goto previous sequence
    def previous_sequence(self, load=True):
        if self.exercise.goto_previous_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Goto next valid sequence
    def next_valid_sequence(self, load=True):
        if self.exercise.goto_next_valid_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Goto previous valid sequence
    def previous_valid_sequence(self, load=True):
        if self.exercise.goto_previous_valid_sequence():
            self.set_can_save(True)
        self._activate_sequence()
        if load and self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.repeat_sequence()

    #Update interface with new sequence. Configure stop media callback
    def _activate_sequence(self):
        self.state = Core.WAIT_BEGIN
        self.set_speed(1)
        self.player.set_next_callback_time(self.exercise.get_current_sequence().get_time_begin() - self.exercise.get_play_margin_before())

        self.gui_controller.set_sequence_number(self.exercise.get_current_sequence_id(), self.exercise.get_sequence_count())
        self.gui_controller.set_sequence(self.exercise.get_current_sequence())
        self.__activate_translation()
        self.__activate_previous_sequence_text()
        self._update_stats()

    #_update displayed translation on new active sequence
    def __activate_translation(self):
        if not self.exercise.get_translation_list():
            self.gui_controller.set_translation("")
        else:
            translation = ""
            currentBegin = self.exercise.get_current_sequence().get_time_begin()
            currentEnd = self.exercise.get_current_sequence().get_time_end()
            for sub in self.exercise.get_translation_list():
                begin = sub.get_time_begin()
                end = sub.get_time_end()
                if (begin >= currentBegin and begin <= currentEnd) or (end >= currentBegin and end <= currentEnd) or (begin <= currentBegin and end >= currentEnd):
                    translation += sub.get_text() + " "

            self.gui_controller.set_translation(translation)

    #_update displayed previous sentence text
    def __activate_previous_sequence_text(self):
        previous_sequence_text = "";
        previous_sequence = self.exercise.get_previous_sequence()
        if previous_sequence:
            for i, symbol in enumerate(previous_sequence.get_symbols()):
                previous_sequence_text += symbol
                if i < len(previous_sequence.get_words()):
                    word = previous_sequence.get_words()[i]
                    if word.is_valid():
                        previous_sequence_text += word.get_valid(lower=False)
                    else:
                        word_text = word.get_text()
                        if len(word_text):
                            previous_sequence_text += word.get_text()
                        else:
                            previous_sequence_text += "_"

        self.gui_controller.set_previous_sequence_text(previous_sequence_text)

    #Update displayed stats on new active sequence
    def _update_stats(self):
        sequenceCount = self.exercise.get_sequence_count()
        sequenceFound = 0
        wordCount = 0
        wordFound = 0
        for sequence in self.exercise.get_sequence_list():
            wordCount = wordCount + sequence.get_word_count()
            if sequence.is_valid():
                sequenceFound += 1
                wordFound += sequence.get_word_count()
            else:
                wordFound += sequence.get_word_found()
        if wordFound == 0:
            repeatRate = float(0)
        else:
            repeatRate = float(self.exercise.get_repeat_count()) / float(wordFound)
        self.gui_controller.set_statitics(sequenceCount, sequenceFound, wordCount, wordFound, repeatRate)

    def _update(self):
        self.gui_controller.set_sequence(self.exercise.get_current_sequence())
        self.__validate_sequence()

    #Verify if the sequence is complete
    def __validate_sequence(self):
        if self.exercise.get_current_sequence().is_valid():
            if self.exercise.get_repeat_after_completed():
                if self.exercise.get_repeat_count_limit_by_sequence() == 0:
                    #Auto start play only if repeat is not limited
                    self.repeat_sequence()
            else:
                self.next_sequence(load=False)
                if self.exercise.get_repeat_count_limit_by_sequence() == 0:
                    #Auto start play only if repeat is not limited
                    if self.player.get_seek() > (self.exercise.get_current_sequence().get_time_begin() - self.exercise.get_play_margin_before()):
                        self.goto_sequence_begin()
                        self.play()
                    else:
                        self.play()


    #Goto beginning of the current sequence. Can start to play as soon
    #as the media player is ready
    def goto_sequence_begin(self, asSoonAsReady=False):
        self.state = Core.WAIT_END
        begin_time = self.exercise.get_current_sequence().get_time_begin() - self.exercise.get_play_margin_before()
        if begin_time < 0:
            begin_time = 0
        if asSoonAsReady:
            self.player.seek_as_soon_as_ready(begin_time)
        else:
            self.player.seek(begin_time)
        self.player.set_next_callback_time(self.exercise.get_current_sequence().get_time_end() + self.exercise.get_play_margin_after())


    #Write a char in current sequence at cursor position
    def write_char(self, char):
        if self.exercise.is_character_match(char):
            self.exercise.get_current_sequence().write_char(char)
            self.exercise.get_current_sequence().update_cursor_position()
            self._update()
            self.set_can_save(True)
        else:
            self._update()

    #Goto next word in current sequence
    def next_word(self):
        self.exercise.get_current_sequence().next_word()
        self._update()

    #Goto previous word in current sequence
    def previous_word(self):
        self.exercise.get_current_sequence().previous_word()
        self._update()

    #Choose current word in current sequence
    def select_sequence_word(self, wordIndex, wordIndexPos):
        try:
            self.exercise.get_current_sequence().select_sequence_word(wordIndex, wordIndexPos)
        except NoCharPossible:
            self.exercise.get_current_sequence().select_sequence_word(wordIndex, -1)
        self._update()

    #Goto first word in current sequence
    def first_word(self):
        self.exercise.get_current_sequence().first_word()
        self._update()

    #Goto last word in current sequence
    def last_word(self):
        self.exercise.get_current_sequence().last_word()
        self._update()

    #Delete a char before the cursor in current sequence
    def delete_previous_char(self):
        self.exercise.get_current_sequence().delete_previous_char()
        self._update()
        self.set_can_save(True)

    #Delete a char after the cursor in current sequence
    def delete_next_char(self):
        self.exercise.get_current_sequence().delete_next_char()
        self._update()
        self.set_can_save(True)

    #Goto previous char in current sequence
    def previous_char(self):
        self.exercise.get_current_sequence().previous_char()
        #The sequence don't change but the cursor position is no more up to date
        self._update()

    #Goto next char in current sequence
    def next_char(self):
        self.exercise.get_current_sequence().next_char()
        #The sequence don't change but the cursor position is no more up to date
        self._update()

    #Reveal correction for word at cursor in current sequence
    def complete_word(self):
        self.exercise.get_current_sequence().show_hint()
        self._update()
        self.set_can_save(True)
    
    #Reveal correction for word at cursor in current sequence
    def reveal_word(self):
        self.exercise.get_current_sequence().complete_word()
        self.exercise.get_current_sequence().next_word()
        self._update()
        self.set_can_save(True)

    #Reveal correction for word at cursor in current sequence
    def reveal_sequence(self):
        self.exercise.get_current_sequence().complete_all()
        self._update()
        self.set_can_save(True)

    #reset whole exercise
    def reset_exercise_content(self):
        self.exercise.reset()
        self.exercise.goto_sequence(0) #FIXME
        self._update()
        self.set_can_save(True)
        self.logger.debug("need to stop the current sequence") #FIXME

    #pause or play media
    def toggle_pause(self):
        if self.player.is_paused() and self.paused:
            self.play()
        elif not self.player.is_paused() and not self.paused:
            self.pause()

    #Change position in media and play it
    def seek_sequence(self, time):
        begin_time = self.exercise.get_current_sequence().get_time_begin() - self.exercise.get_play_margin_before()
        if begin_time < 0:
            begin_time = 0

        pos = begin_time + time
        self.player.seek(pos)
        self.player.set_next_callback_time(self.exercise.get_current_sequence().get_time_end() + self.exercise.get_play_margin_after())
        self.state = Core.WAIT_END
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    #Thread to update slider position in gui
    def time_update_thread(self):
        timeUpdateThreadId = self.timeUpdateThreadId
        while timeUpdateThreadId == self.timeUpdateThreadId:
            time.sleep(0.5)
            pos_int = self.player.get_current_time()
            if pos_int != None:
                end_time = self.exercise.get_current_sequence().get_time_end()
                begin_time = self.exercise.get_current_sequence().get_time_begin() - self.exercise.get_play_margin_before()
                if begin_time < 0:
                    begin_time = 0
                duration = end_time - begin_time
                pos = pos_int - begin_time
                self.gui_controller.set_sequence_time(pos, duration)

    #Save current exercice
    def save(self, saveAs=False):
        if not self.exercise:
            self.logger.error("Save called but no exercise load")
            return

        if saveAs or self.exercise.get_output_save_path() == None:
            outputSavePath = self.gui_controller.ask_save_path()
            if not outputSavePath:
                return
            self.exercise.set_output_save_path(outputSavePath + ".perroquet")

        save_exercise(self.exercise, self.exercise.get_output_save_path())

        self.config.set("lastopenfile", self.exercise.get_output_save_path())

        #lastopenfileS
        l = self.config.get("lastopenfiles")
        path = self.exercise.get_output_save_path()
        name = self.exercise.get_name() or path
        self.config.set("lastopenfiles", [[path, name]] + [p for p in l if p[0] != path][:10])

        self.set_can_save(False)

    #load the exercice at path
    def load_exercise(self, path):
        self.gui_controller.activate("closed")
        if self.exercise:
            self.save()
        try:
            self.exercise = load_exercise(path)
            self.exercise.set_media_change_callback(self.media_change_call_back)
        except IOError:
            self.logger.exception("No file at " + path)
            return
        if not self.exercise:
            return


        validPaths, errorList = self.exercise.is_paths_valid()
        if not validPaths:
            for error in errorList:
                self.gui_controller.signal_exercise_bad_path(error)

            self.set_can_save(False)
            self.gui_controller.activate("load_failed")
            self.gui_controller.ask_properties()
            return

        self._reload(False)
        if self.exercise.get_output_save_path() == None:
            self.set_can_save(True)
        else:
            self.set_can_save(False)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    #Change paths of current exercice and reload subtitles and video
    def _update_paths(self, videoPath, exercisePath, translationPath):
        self.exercise.set_video_path(videoPath)
        self.exercise.set_exercise_path(exercisePath)
        self.exercise.set_translation_path(translationPath)

        validPaths, errorList = self.exercise.is_paths_valid()
        if not validPaths:
            for error in errorList:
                self.gui_controller.signal_exercise_bad_path(error)
            self.gui_controller.activate("load_failed")
            self.set_can_save(False)
            return

        self._set_paths(videoPath, exercisePath, translationPath)
        self._reload(True)
        self.set_can_save(True)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    def update_properties(self):
        self.exercise.initialize()
        self._reload(True)
        self.set_can_save(True)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    #get paths of current exercise
    def get_paths(self):
        return (self.exercise.get_video_path(), self.exercise.get_exercise_path(), self.exercise.get_translation_path())

    #Udpates vocabulary list in interface
    def _update_word_list(self):
        self.gui_controller.set_word_list(self.exercise.extract_word_list())

    #Notify the user use the repeat command (for stats)
    def user_repeat(self):
        self.exercise.increment_repeat_count()
        self.set_can_save(True)

    #Signal to the gui that the exercise has unsaved changes
    def set_can_save(self, save):
        self.gui_controller.set_can_save(save)

        if self.exercise == None:
            title = ""
        elif self.exercise.get_name() != None:
            title = self.exercise.get_name()
        elif self.exercise.get_output_save_path() != None:
            title = self.exercise.get_output_save_path()
        else:
            title = _("Untitled exercise")

        self.last_save = save
        self.gui_controller.set_title(title, save)

    def get_can_save(self):
        return self.last_save

    def get_exercise(self):
        return self.exercise

    def get_player(self):
        return self.player

    def media_change_call_back(self):
        self.logger.info("new media : " + self.exercise.get_video_path())
        """self.Pause()
        self.player.open(self.exercise.get_video_path())
        """
        self._reload(True)
        self._activate_sequence()
        self.goto_sequence_begin(True)
        if self.exercise.get_repeat_count_limit_by_sequence() == 0:
            #Auto start play only if repeat is not limited
            self.play()

    def export_as_template(self):
        self.gui_controller.ask_properties_advanced()
        path = self.gui_controller.ask_export_as_template_path()
        if path:
            self.exercise.set_template(True)
            save_exercise(self.exercise, path)
            self.exercise.set_template(False)

    def export_as_package(self):
        self.gui_controller.ask_properties_advanced()
        path = self.gui_controller.ask_export_as_package_path()
        if path:
            repoManager = ExerciseRepositoryManager()
            repoManager.export_as_package(self.exercise, path)
            self.logger.info("Export done")
        else:
            self.logger.warn("No valid path to export??")


    def import_package(self):
        import_path = self.gui_controller.ask_import_package()

        if import_path is not None:
            repo_manager = ExerciseRepositoryManager()
            error = repo_manager.import_package(import_path)
            if error is None:
                self.gui_controller.display_message(_("Import finish succesfully. Use the exercises manager to use the newly installed exercise."))
            else:
                self.gui_controller.display_message(_("Import failed." + " " + error))
Example #23
0
    def create_frames(self):
        # Top frame
        self.top_frame = tk.LabelFrame(self.master, text='', bg="#E9E9E9")
        self.top_frame.pack(side='top', expand=True, fill='both')

        self.load_query_button = ttk.Button(self.top_frame,
                                            text='Load Query',
                                            command=self.load_query_video)
        self.load_query_button.grid(row=0, column=0, padx=0, pady=0)

        self.find_matches_button = ttk.Button(self.top_frame,
                                              text='Find matches',
                                              command=self.run_match)
        self.find_matches_button.grid(row=1, column=0, padx=0, pady=0)

        self.match_list = tk.Listbox(self.top_frame, height=4, bd=0)
        self.yscroll = tk.Scrollbar(self.top_frame, orient=tk.VERTICAL)
        self.match_list['yscrollcommand'] = self.yscroll.set
        self.match_list.grid(row=0, column=1, rowspan=2, stick='wens')
        self.yscroll.grid(row=0, column=1, rowspan=2, sticky='nse')
        self.match_list.bind('<Double-Button-1>', self.poll_match_list)
        self.curr_selection = -1

        self.top_frame.grid_columnconfigure(0, weight=1)
        self.top_frame.grid_columnconfigure(1, weight=2)

        # Middle frame
        self.middle_frame = tk.LabelFrame(self.master, text='')
        self.middle_frame.pack(side='top', expand=True, fill='both')

        self.status_label_text = tk.StringVar()
        self.status_label_text.set('LOGS')
        self.status_label = tk.Label(self.middle_frame,
                                     textvar=self.status_label_text,
                                     justify=tk.LEFT,
                                     anchor='w',
                                     wraplength=700,
                                     bg="black",
                                     fg="#C1E0FD")
        self.status_label.grid(row=0, column=0, stick='nswe', columnspan=2)

        self.middle_frame.grid_columnconfigure(0, weight=1)
        self.middle_frame.grid_columnconfigure(1, weight=1)

        self.query_player = VideoPlayer(self.middle_frame)
        self.query_player.grid(row=1, column=0, stick='nsw')
        self.db_player = VideoPlayer(self.middle_frame)
        self.db_player.grid(row=1, column=1, stick='nse')

        # Bottom frame
        self.bottom_frame = tk.LabelFrame(self.master, text='')
        self.bottom_frame.pack(side='top', expand=True, fill='both')

        self.match_info_label_text = tk.StringVar()
        # self.match_info_label_text.set('MATCH INFORMATION')
        self.match_info_label = tk.Label(self.bottom_frame,
                                         textvar=self.match_info_label_text,
                                         justify=tk.LEFT,
                                         anchor='e')
        self.match_info_label.grid(row=0, column=0, stick='nswe')

        image = cv2.imread(
            "/Users/nikhiljohny/Documents/_CSCI576Project/codebase/master/graph_place_holder.png"
        )
        width = 365
        height = 280
        dim = (width, height)
        image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = Image.fromarray(image)
        image = ImageTk.PhotoImage(image)

        self.panelA = tk.Label(self.bottom_frame,
                               image=image,
                               width=365,
                               height=280)
        self.panelA.image = image
        self.panelA.grid(row=0, column=1, stick='nse', padx=0, pady=0)
        self.bottom_frame.grid_columnconfigure(0, weight=1)
        self.bottom_frame.grid_columnconfigure(1, weight=1)