def get_current_rental_quality(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) uhd_sym_match = is_uhd_visible(context, frame) hdx_sym_match = is_hdx_visible(context, frame) sd_sym_match = is_sd_visible(context, frame) uhd_set = hdx_set = sd_set = set() if uhd_sym_match is not None and uhd_sym_match[0] is True: uhd_set = set(range(uhd_sym_match[1].y, uhd_sym_match[1].bottom)) if hdx_sym_match is not None and hdx_sym_match[0] is True: hdx_set = set(range(hdx_sym_match[1].y, hdx_sym_match[1].bottom)) if sd_sym_match is not None and sd_sym_match[0] is True: sd_set = set(range(sd_sym_match[1].y, sd_sym_match[1].bottom)) current_quality_match = match(frame, PURCHASE_POPUP_PRICE_20X36, region=REGION_PURCHASE_POPUP_GRID_PRICE) assert current_quality_match[0], "fail to find current purchase" curent_quality_set = set(range(current_quality_match[1].y, current_quality_match[1].bottom)) if len(list(curent_quality_set & uhd_set)) > 0: current_quality = consts.QUALITY_UHD elif len(list(curent_quality_set & hdx_set)) > 0: current_quality = consts.QUALITY_HDX elif len(list(curent_quality_set & sd_set)) > 0: current_quality = consts.QUALITY_SD else: assert False, "=== cannot find selected quality ===" return current_quality
def step_impl(context, switch): assert switch == "on" or switch == "off" press(context, keys.KEY_DOWN, 1) # to show progress bar cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) region = REGION_PROGRESS_BAR frame = cv2.imread(context.frame) mp = (3, 0.8, *get_default_match_parameter()[2::] ) # use ccorr_normed method 0 and threshold =0.65 if switch == "off": debug(f"match {playback_soft_buttons['cc off unhilite'][1]}") if match(frame, cv2.imread(playback_soft_buttons["cc off unhilite"][1]), region, match_parameter=mp)[0] is True: debug(f"closed caption is already {switch}\n\n") return elif switch == 'on': debug(f"match {playback_soft_buttons['cc on unhilite'][1]}") if match(frame, cv2.imread(playback_soft_buttons["cc on unhilite"][1]), region, match_parameter=mp)[0] is True: debug(f"closed caption is already {switch}") return debug(f"navigate_to {switch}\n\n") if navigate_to(context, "cc on" if switch == "off" else "cc off"): press(context, keys.KEY_SELECT, 1) # press(context, keys.KEY_UP, 1) press(context, keys.KEY_SELECT, 1) return assert False, f"fail to switch {switch} closed caption"
def step_impl(context): press(context, keys.KEY_DOWN, 1) # to show progress bar cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) mp = (0, 0.8, *get_default_match_parameter()[2::] ) # use ccorr_normed method 0 and threshold =0.65 video_quality = "None" result = 0.0 assert os.path.exists(playback_soft_buttons["play off unhilitefamily"][1]) found = match(frame, cv2.imread( playback_soft_buttons['family play off unhilite'][1]), REGION_PROGRESS_BAR, match_parameter=mp) if found[0] is True: debug(f"found family play off\n") return assert os.path.exists(playback_soft_buttons["family play on unhilite"][1]) found = match(frame, cv2.imread( playback_soft_buttons['family play on unhilite'][1]), REGION_PROGRESS_BAR, match_parameter=mp) if found[0] is True: debug(f"found family play on\n") return debug(f"fail to find family play on the progress barn\n") assert False, "fail to find family play on the progress bar"
def find_video_quality_on_progress_bar(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) mp = (3, 0.8, *get_default_match_parameter()[2::] ) # use ccorr_normed method 0 and threshold =0.65 video_quality = None found_uhd = match(frame, cv2.imread(playback_soft_buttons['uhd unhilite'][1]), REGION_PROGRESS_BAR, match_parameter=mp)[0] if found_uhd is True: video_quality = "uhd" debug(f"found uhd") found_hdx = match(frame, cv2.imread(playback_soft_buttons['hdx unhilite'][1]), REGION_PROGRESS_BAR, match_parameter=mp)[0] if found_hdx is True: video_quality = "hdx" debug(f"found hdx") found_sd = match(frame, cv2.imread(playback_soft_buttons['sd unhilite'][1]), REGION_PROGRESS_BAR, match_parameter=mp)[0] if found_sd is True: video_quality = "sd" debug(f"found sd") return video_quality
def step_impl(context): # read ads watch time and program time cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") start = time.time() success = 0 while True and time.time() < start + 180: press(context, keys.KEY_DOWN) # to show progress bar assert 200 == cam.get_frame(context.frame) region = Region(x=900, y=640, right=1110, bottom=720) ads = ocr(cv2.imread(context.frame), region, grayscale=True, invert_grayscale=True) debug(f"ads: {ads}") region = Region(x=1110, y=640, right=1280, bottom=720) counter = ocr(cv2.imread(context.frame), region, grayscale=True, invert_grayscale=True) debug(f"counter: {counter}") debug(f"ads/counter: {ads} / {counter}\n") if "Ad" not in ads and ":" not in counter: success += 1 if success > 3: return assert False, "ads is still playing"
def navigate_to_single_price_grid_rent(context, quality=consts.QUALITY_HDX): # new single price pop cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) assert is_single_purchase_price_rent_visible(context, frame), "Single price rent is not visible." price_selection = current_price_grid_selection(context, frame) print(f"The selected price option is: {price_selection}") print(f"Move to {quality}") if quality == consts.QUALITY_ANY: return if quality == consts.QUALITY_HDX: if price_4k in price_selection: press(context, keys.KEY_DOWN, 1) price_selection = current_price_grid_selection(context) print(f"The selected price option is: {price_selection}") # HDX + SD if consts.QUALITY_HDX in price_selection: return True elif quality == consts.QUALITY_SD: press(context, keys.KEY_DOWN, 1) press(context, keys.KEY_DOWN, 1) return True else: if price_4k in price_selection: return True assert False, f"Failed to navigate to rent {quality} option"
def step_impl(context, screen): assert screen in MENU_SCREEN_TABS, f"error: unknown {screen} tab on the menu page" if screen == MENU_SCREEN_TABS[0]: key = keys.KEY_LEFT max_try = 2 else: max_try = len(MENU_SCREEN_TABS) - 1 key = keys.KEY_RIGHT goto_vudu_home(context) # we are in menu screen now # check current selection is on spotlight cam = context.cam while max_try: context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) text_in_highlight, region = find_selection_text( cv2.imread(context.frame), cv2.imread(MAIN_MENU_SEL_LEFT), cv2.imread(MAIN_MENU_SEL_RIGHT), x_offset=10, y_offset=5, region=Region(0, 0, 1000, 80), match_parameter=get_default_match_parameter()) debug(f"current selection is {text_in_highlight} at {region}") if text_in_highlight is not None and screen.lower( ) in text_in_highlight.lower(): debug(f"found {screen}") return press(context, key, 1) max_try -= 1 assert False, f"fail to go to {screen} tab on the menu page"
def is_single_purchase_price_buy_visible(context, frame=None): if frame is None: cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) return is_single_purchase_price_focus_buy_visible(context, frame) is not None or \ is_single_purchase_price_un_focus_buy_visible(context, frame)
def step_impl(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) thank_you_purchase_title = thank_you_purchase_popup_title(context,frame) debug(f"thank you purchase popup title: {thank_you_purchase_title}") assert fuzzy_match("Thank You", thank_you_purchase_title, 0.9), f"thank you purchase popup title {thank_you_purchase_title} is not found"
def step_impl(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) confirm_purchase_title = confirm_purchase_popup_title(context,frame) debug(f"confirm purchase popup title: {confirm_purchase_title}") assert fuzzy_match("Confirm Purchase", confirm_purchase_title, 0.9) or \ fuzzy_match("Confirm Rental", confirm_purchase_title, 0.9), f"Confirm purchase popup title {confirm_purchase_title} is not found "
def step_impl(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) region = Region(0, 0, 1000, 70) match_result = ocr(cv2.imread(context.frame), region) for tab in MENU_SCREEN_TABS: #assert tab in match_result, f"{tab} not found in menu tabs" if tab not in match_result: debug(f"error: {tab} not found in menu tabs") else: debug(f"{tab} found in menu tabs")
def current_menu_selection(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) text_in_highlight, region = find_selection_text( cv2.imread(context.frame), cv2.imread(MAIN_MENU_SEL_LEFT), cv2.imread(MAIN_MENU_SEL_RIGHT), x_offset=10, y_offset=5, region=Region(0, 0, 1000, 80)) debug(f"current selection is {text_in_highlight} at {region}") return text_in_highlight
def step_impl(context, tab): assert tab in MENU_SCREEN_TABS, "error: {tab} is an unknown screen" cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) text_in_highlight, region = find_selection_text( cv2.imread(context.frame), cv2.imread(MAIN_MENU_SEL_LEFT), cv2.imread(MAIN_MENU_SEL_RIGHT), region=Region(0, 0, 1000, 80), match_parameter=get_default_match_parameter()) debug(f"current selection is {text_in_highlight} at {region}") assert tab.lower() in text_in_highlight.lower( ), f"{tab} selection not found"
def step_impl(context, tab): assert tab in settings_screen_tabs, "error: {tab} is an unknown screen" cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) text_in_highlight, region = find_selection_text( cv2.imread(context.frame), cv2.imread(SETTINGS_MENU_SEL), None, x_offset=20, region=Region(50, 170, 400, 540), match_parameter=get_default_match_parameter()) debug(f"current selection is {text_in_highlight} at {region}") assert fuzzy_match(tab, text_in_highlight), f"{tab} selection not found"
def current_price_grid_selection(context, frame=None): # sel_text = find_selection_horizontal_repeat(frame=get_frame(), # background=self.images.PURCHASE_POPUP_PRICE_GRID_PIX, # region=REGION_SINGLE_PRICE_GRID).text # print(f"=== Dump current price selection: {sel_text}") # return sel_text if frame is None: cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) mp = (3, 0.8, *get_default_match_parameter()[2::]) # use ccorr_normed method 0 and threshold =0.65 sel_text, region = find_selection_text(frame, left_bk=PURCHASE_POPUP_PRICE_GRID_SEL, right_bk=None, x_offset=10, y_offset=10, region=REGION_SINGLE_PRICE_GRID, match_parameter=mp) return sel_text
def step_impl(context): # read watch time and program time press(context, keys.KEY_DOWN) cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) counter = ocr(cv2.imread(context.frame), REGION_PROGRESS_BAR_TIME, grayscale=True, invert_grayscale=True, ocr_parameter='-c tessedit_char_whitelist=0123456789/:') debug(f"counter: {counter}\n") assert "/" in counter, "no counter found" play_time, program_time = parse_play_time_and_program_time(counter) debug(f"play time / program time: {play_time}/{program_time}") context.play_time = play_time context.program_time = program_time
def find_current_chapters(context): press(context, keys.KEY_SELECT, 1) # to show chapter grid cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) mp = (3, 0.8, *get_default_match_parameter()[2::] ) # use ccorr_normed method 0 and threshold =0.65 debug(f"match {playback_chapter['chapter']}") result = match(frame, cv2.imread(playback_chapter["chapter"]), REGION_CHAPTER_GRID, match_parameter=mp) print("\n\n") assert result[0] is True, f"fail to find current chapter" # find current chapter chapter_grids_width = REGION_CHAPTER_GRID.right - REGION_CHAPTER_GRID.x chapter_grids_height = REGION_CHAPTER_GRID.bottom - REGION_CHAPTER_GRID.top chapter_width = chapter_grids_width // CHAPTER_GRID_COLS chapter_height = chapter_grids_height // CHAPTER_GRID_ROWS chapters_regions = [] for row in range(CHAPTER_GRID_ROWS): for col in range(CHAPTER_GRID_COLS): chapters_regions.append( Region(REGION_CHAPTER_GRID.x + col * chapter_width, REGION_CHAPTER_GRID.y + row * chapter_height, REGION_CHAPTER_GRID.x + (col + 1) * chapter_width, REGION_CHAPTER_GRID.y + (row + 1) * chapter_height)) # debug(f"chapter: {len(chapters_regions) + 1}, {chapters_regions[-1]}") found_chapters = [] focused_chapter = 0 focused_chapter_area = 0 for chp in range(len(chapters_regions)): area = Region.intersect_area(result[1], chapters_regions[chp]) # debug(f"intersect area {result[1]} and {chapters_regions[chp]}, area: {area}") if area > 0: found_chapters.append((chp, area)) debug(f"chapter {chp + 1}, area: {area}") if area > focused_chapter_area: focused_chapter = chp + 1 focused_chapter_area = area return focused_chapter
def step_impl(context, result): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") move_to_search_result(context) for count in range(3): # search_region = regions.REGION_SIDE_PANEL_DICT[consts.SEARCH] assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) read_title = ocr(region=REGION_SEARCH_TITLE, frame=frame).replace('\n', " ").upper() debug("=== Read out text: {}".format(read_title)) if result in read_title: debug(f"Find result: {result}") return result else: debug(f"Didn't find the expected {result}. Move to next poster: ") press(context, keys.KEY_RIGHT, delay=2) assert False, f"Didn't find the expected {result}."
def step_impl(context, switch): press(context, keys.KEY_DOWN, 1) # to show progress bar cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) mp = (3, 0.7, *get_default_match_parameter()[2::] ) # use ccorr_normed method 0 and threshold =0.65 debug("check current switch\n") if switch == "off": debug(f"match {playback_soft_buttons['family play off unhilite'][1]}") if match(frame, cv2.imread( playback_soft_buttons["family play off unhilite"][1]), REGION_PROGRESS_BAR, match_parameter=mp)[0] is True: debug(f"family play is already {switch}\n") return elif switch == "on": debug(f"match {playback_soft_buttons['family play on unhilite'][1]}") if match(frame, cv2.imread( playback_soft_buttons["family play on unhilite"][1]), REGION_PROGRESS_BAR, match_parameter=mp)[0] is True: debug(f"family play is already {switch}\n") return debug(f"navigate_to family play {switch}\n") if navigate_to(context, "family play on" if switch == "off" else "family play off"): press(context, keys.KEY_SELECT, 1) # press(context, keys.KEY_UP, 1) press(context, keys.KEY_SELECT, 1) # dismiss family play popup press(context, keys.KEY_SELECT, 1) if switch == "on": press(context, keys.KEY_SELECT, 1) # dismiss family play popup return
def find_video_quality_on_playback_page(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) mp = (3, 0.8, *get_default_match_parameter()[2::] ) # use ccorr_normed method 0 and threshold =0.65 video_quality = "None" result = 0.0 assert os.path.exists(playback_video_quality["uhd"]) found = match(frame, cv2.imread(playback_video_quality['uhd']), REGION_PLAYBACK_PAGE_TITLE, match_parameter=mp) if found[0] is True and found[2] > result: video_quality = "uhd" result = found[2] debug(f"found uhd") found = match(frame, cv2.imread(playback_video_quality['hdx']), REGION_PLAYBACK_PAGE_TITLE, match_parameter=mp) if found[0] is True and found[2] > result: video_quality = "hdx" result = found[2] debug(f"found hdx") found = match(frame, cv2.imread(playback_video_quality['sd']), REGION_PLAYBACK_PAGE_TITLE, match_parameter=mp) if found[0] is True and found[2] > result: video_quality = "sd" result = found[2] debug(f"found sd") print("\n\n") return video_quality
def step_impl(context): # read ads watch time and program time press(context, keys.KEY_DOWN) cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(context.frame) shoppable_ads_detected = False if detect_shoppable_ads is True: shoppable_ads_detected = detect_shoppable_ads() else: shoppable_ads_detected = False region = Region(x=950, y=640, right=1110, bottom=720) ads = ocr(cv2.imread(context.frame), region, grayscale=True, invert_grayscale=True) debug(f"ads: {ads}") region = Region(x=1110, y=640, right=1280, bottom=720) counter = ocr(cv2.imread(context.frame), region, grayscale=True, invert_grayscale=True) debug(f"counter: {counter}") debug(f"ads/counter: {ads} / {counter}\n") assert "Ad" in ads or ":" in counter, "no ads found" current_ads, total_ads, ads_min, ads_sec = parse_ads_and_counter( ads, counter) if detect_shoppable_ads is True and shoppable_ads_detected is False: assert 200 == cam.get_frame(context.frame) shoppable_ads_detected = detect_shoppable_ads() debug( f"current_ads:{current_ads}, total_ads:{total_ads}, ads_min:{ads_min}, ads_sec:{ads_sec}, shoppable_ads_detected:{shoppable_ads_detected}" )
def step_impl(context, result): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") move_to_search_suggestions(context) debug("\n\n=== Read search suggestion.") mp = (3, 0.65, *get_default_match_parameter()[2::]) # use fixed method 3 and threshold =0.65 for _ in range(3): assert 200 == cam.get_frame(context.frame) frame = cv2.imread(context.frame) text_read_out, region = find_selection_text(cv2.imread(context.frame), cv2.imread(SEARCH_SUGGESTION_SEL_LEFT), cv2.imread(SEARCH_SUGGESTION_SEL_RIGHT), region=REGION_SEARCH_SUGGESTIONS, match_parameter=mp) format_read_out = text_read_out.upper() debug(f"The formatted read out: {format_read_out}") if result in format_read_out: debug("Find expected search string in search suggestion") return press(context, keys.KEY_DOWN, delay=1) time.sleep(2) raise AssertionError(f"Failed to find {result} in search menu")
def is_single_purchase_price_rent_visible(context, frame=None): if frame is None: cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) return match(context.frame, PURCHASE_POPUP_RENT)
def title(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) return ocr(frame, region=REGION_DETAILS_PAGE_TITLE)
def check_cancel_button_visible(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) return match(frame, MOVIE_PURCHASE_POPUP_CANCEL_BUTTON)
def visible(context): cam = context.cam context.frame = get_frame_name(context, f"{WORK_DIR}/_frame.png") assert 200 == cam.get_frame(path=context.frame) frame = cv2.imread(context.frame) return is_old_purchase_popup_visible(context, frame) or is_single_purchase_price_visible(context, frame)