1 # Copyright 2015 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 6 import datetime, time 7 8 from autotest_lib.client.bin import utils 9 from autotest_lib.client.common_lib import error 10 from autotest_lib.client.cros.video import method_logger 11 12 13 class VideoPlayer(object): 14 """ 15 Provides interface to interact with and control video playback via js. 16 17 Specific players such as VimeoPlayer will inherit from this class and 18 customize its behavior. 19 20 """ 21 22 23 def __init__(self, tab, full_url, video_id, video_src_path='', 24 event_timeout=5, polling_wait_time=1): 25 """ 26 @param tab: object, tab to interact with the tab in the browser. 27 @param full_url: string, full url pointing to html file to load. 28 @param video_src_path: path, complete path to video used for test. 29 @param video_id: string, name of the video_id element in the html file. 30 @param time_out_for_events_s: integer, how long to wait for an event 31 before timing out 32 @param time_btwn_polling_s: integer, how long to wait between one call 33 to check a condition and the next. 34 35 """ 36 self.tab = tab 37 self.full_url = full_url 38 self.video_id = video_id 39 self.video_src_path = video_src_path 40 self.event_timeout = event_timeout 41 self.polling_wait_time = polling_wait_time 42 self.tab.Navigate(self.full_url) 43 44 45 @method_logger.log 46 def load_video(self, wait_for_canplay=True): 47 """ 48 Loads video into browser. 49 @param wait_for_canplay: video will be verified before play 50 51 """ 52 self.tab.WaitForDocumentReadyStateToBeComplete() 53 self.wait_for_script_ready() 54 time.sleep(2) 55 self.inject_source_file() 56 if wait_for_canplay: 57 self.wait_for_video_ready() 58 59 60 def inject_source_file(self): 61 """ 62 Injects source file into html file if needed. 63 64 Created for subclasses that need it 65 66 """ 67 pass 68 69 70 @method_logger.log 71 def wait_for_script_ready(self): 72 """ 73 Wait for Javascript variables and functions to be defined. 74 75 """ 76 exception_msg = 'Script did not ready in time.' 77 78 self._wait_for_event(self.is_javascript_ready, exception_msg) 79 80 81 @method_logger.log 82 def wait_for_video_ready(self): 83 """ 84 Waits for video to signal that is ready. 85 86 Each class that inherits from this will define its is_video_ready 87 function. 88 89 """ 90 exception_msg = 'Video did not signal ready in time.' 91 92 self._wait_for_event(self.is_video_ready, exception_msg) 93 94 95 @method_logger.log 96 def verify_video_can_play(self, duration=0): 97 """ 98 Plays video and ensures that reported video current time is > 0. 99 100 @param duration: duration to play a video 101 @raises: error.TestError if current time is not > 0 after time > 0s 102 103 """ 104 exception_msg = 'Expected current time >%ds.' %duration 105 106 self.play() 107 108 # check that video is playing 109 self._wait_for_event( 110 lambda : self.currentTime() > duration, exception_msg) 111 112 self.pause() 113 114 # seek back to the beginning of video 115 self.seek_to(datetime.timedelta(seconds=0)) 116 117 118 @method_logger.log 119 def seek_to(self, timestamp): 120 """ 121 Uses javascript to set currentTime property of video to desired time. 122 123 @param timestamp: timedelta, instance of time to navigate video to. 124 125 """ 126 self.seek_to(timestamp) 127 128 129 @method_logger.log 130 def wait_for_video_to_seek(self): 131 """ 132 Waits for video's currentTime to equal the time it was seeked to. 133 134 """ 135 exception_msg = 'Video did not complete seeking in time.' 136 137 self._wait_for_event(self.has_video_finished_seeking, exception_msg) 138 139 # it usually takes a little while before new frame renders, so wait 140 time.sleep(1) 141 142 143 @method_logger.log 144 def _wait_for_event(self, predicate_function, exception_msg): 145 """ 146 Helper method to wait for a desired condition. 147 148 @param predicate_function: object, function which returns true when 149 desired condition is achieved. 150 @param exception_msg: string, an exception message to show when desired 151 condition is not achieved in allowed time. 152 153 """ 154 fullmsg = exception_msg + ' Waited for %ss' % self.event_timeout 155 156 utils.poll_for_condition(predicate_function, 157 error.TestError(fullmsg), 158 self.event_timeout, 159 self.polling_wait_time) 160