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 6import datetime, time 7 8from autotest_lib.client.bin import utils 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.cros.video import method_logger 11 12 13class 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 43 44 @method_logger.log 45 def load_video(self, wait_for_canplay=True): 46 """ 47 Loads video into browser. 48 @param wait_for_canplay: video will be verified before play 49 50 """ 51 self.tab.Navigate(self.full_url) 52 self.tab.WaitForDocumentReadyStateToBeComplete() 53 self.inject_source_file() 54 if wait_for_canplay: 55 self.wait_for_video_ready() 56 57 58 def inject_source_file(self): 59 """ 60 Injects source file into html file if needed. 61 62 Created for subclasses that need it 63 64 """ 65 pass 66 67 68 @method_logger.log 69 def wait_for_video_ready(self): 70 """ 71 Waits for video to signal that is ready. 72 73 Each class that inherits from this will define its is_video_ready 74 function. 75 76 """ 77 exception_msg = 'Video did not signal ready in time.' 78 79 self._wait_for_event(self.is_video_ready, exception_msg) 80 81 82 @method_logger.log 83 def verify_video_can_play(self): 84 """ 85 Plays video and ensures that reported video current time is > 0. 86 @raises: error.TestError if current time is not > 0 after time > 0s 87 88 """ 89 exception_msg = 'Expected current > 0 after %ds' %self.event_timeout 90 91 self.play() 92 93 # check that video is playing 94 self._wait_for_event(lambda : self.currentTime() > 0.0, exception_msg) 95 96 self.pause() 97 98 # seek back to the beginning of video 99 self.seek_to(datetime.timedelta(seconds=0)) 100 101 102 @method_logger.log 103 def seek_to(self, timestamp): 104 """ 105 Uses javascript to set currentTime property of video to desired time. 106 107 @param timestamp: timedelta, instance of time to navigate video to. 108 109 """ 110 self.seek_to(timestamp) 111 112 113 @method_logger.log 114 def wait_for_video_to_seek(self): 115 """ 116 Waits for video's currentTime to equal the time it was seeked to. 117 118 """ 119 exception_msg = 'Video did not complete seeking in time.' 120 121 self._wait_for_event(self.has_video_finished_seeking, exception_msg) 122 123 # it usually takes a little while before new frame renders, so wait 124 time.sleep(1) 125 126 127 @method_logger.log 128 def _wait_for_event(self, predicate_function, exception_msg): 129 """ 130 Helper method to wait for a desired condition. 131 132 @param predicate_function: object, function which returns true when 133 desired condition is achieved. 134 @param exception_msg: string, an exception message to show when desired 135 condition is not achieved in allowed time. 136 137 """ 138 fullmsg = exception_msg + ' Waited for %ss' % self.event_timeout 139 140 utils.poll_for_condition(predicate_function, 141 error.TestError(fullmsg), 142 self.event_timeout, 143 self.polling_wait_time) 144