Home | History | Annotate | Download | only in video
      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