1*9c5db199SXin Li# Copyright 2016 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Li"""Facade to access the video-related functionality.""" 6*9c5db199SXin Li 7*9c5db199SXin Liimport functools 8*9c5db199SXin Liimport glob 9*9c5db199SXin Liimport os 10*9c5db199SXin Li 11*9c5db199SXin Lifrom autotest_lib.client.bin import utils 12*9c5db199SXin Lifrom autotest_lib.client.cros.multimedia import display_facade 13*9c5db199SXin Lifrom autotest_lib.client.cros.video import builtin_html5_player 14*9c5db199SXin Li 15*9c5db199SXin Li 16*9c5db199SXin Liclass VideoFacadeLocalError(Exception): 17*9c5db199SXin Li """Error in VideoFacadeLocal.""" 18*9c5db199SXin Li pass 19*9c5db199SXin Li 20*9c5db199SXin Li 21*9c5db199SXin Lidef check_arc_resource(func): 22*9c5db199SXin Li """Decorator function for ARC related functions in VideoFacadeLocal.""" 23*9c5db199SXin Li @functools.wraps(func) 24*9c5db199SXin Li def wrapper(instance, *args, **kwargs): 25*9c5db199SXin Li """Wrapper for the methods to check _arc_resource. 26*9c5db199SXin Li 27*9c5db199SXin Li @param instance: Object instance. 28*9c5db199SXin Li 29*9c5db199SXin Li @raises: VideoFacadeLocalError if there is no ARC resource. 30*9c5db199SXin Li 31*9c5db199SXin Li """ 32*9c5db199SXin Li if not instance._arc_resource: 33*9c5db199SXin Li raise VideoFacadeLocalError('There is no ARC resource.') 34*9c5db199SXin Li return func(instance, *args, **kwargs) 35*9c5db199SXin Li return wrapper 36*9c5db199SXin Li 37*9c5db199SXin Li 38*9c5db199SXin Liclass VideoFacadeLocal(object): 39*9c5db199SXin Li """Facede to access the video-related functionality. 40*9c5db199SXin Li 41*9c5db199SXin Li The methods inside this class only accept Python native types. 42*9c5db199SXin Li 43*9c5db199SXin Li """ 44*9c5db199SXin Li 45*9c5db199SXin Li def __init__(self, resource, arc_resource=None): 46*9c5db199SXin Li """Initializes an video facade. 47*9c5db199SXin Li 48*9c5db199SXin Li @param resource: A FacadeResource object. 49*9c5db199SXin Li @param arc_resource: An ArcResource object. 50*9c5db199SXin Li 51*9c5db199SXin Li """ 52*9c5db199SXin Li self._resource = resource 53*9c5db199SXin Li self._player = None 54*9c5db199SXin Li self._arc_resource = arc_resource 55*9c5db199SXin Li self._display_facade = display_facade.DisplayFacadeLocal( 56*9c5db199SXin Li resource) 57*9c5db199SXin Li self.bindir = os.path.dirname(os.path.realpath(__file__)) 58*9c5db199SXin Li 59*9c5db199SXin Li 60*9c5db199SXin Li def cleanup(self): 61*9c5db199SXin Li """Clean up the temporary files.""" 62*9c5db199SXin Li for path in glob.glob('/tmp/playback_*'): 63*9c5db199SXin Li os.unlink(path) 64*9c5db199SXin Li 65*9c5db199SXin Li if self._arc_resource: 66*9c5db199SXin Li self._arc_resource.cleanup() 67*9c5db199SXin Li 68*9c5db199SXin Li 69*9c5db199SXin Li def prepare_playback(self, file_path, fullscreen=True): 70*9c5db199SXin Li """Copies the html file to /tmp and loads the webpage. 71*9c5db199SXin Li 72*9c5db199SXin Li @param file_path: The path to the file. 73*9c5db199SXin Li @param fullscreen: Plays the video in fullscreen. 74*9c5db199SXin Li 75*9c5db199SXin Li """ 76*9c5db199SXin Li # Copies the html file to /tmp to make it accessible. 77*9c5db199SXin Li utils.get_file( 78*9c5db199SXin Li os.path.join(self.bindir, 'video.html'), 79*9c5db199SXin Li '/tmp/playback_video.html') 80*9c5db199SXin Li 81*9c5db199SXin Li html_path = 'file:///tmp/playback_video.html' 82*9c5db199SXin Li 83*9c5db199SXin Li tab = self._resource._browser.tabs.New() 84*9c5db199SXin Li tab.Navigate(html_path) 85*9c5db199SXin Li self._player = builtin_html5_player.BuiltinHtml5Player( 86*9c5db199SXin Li tab=tab, 87*9c5db199SXin Li full_url=html_path, 88*9c5db199SXin Li video_id='video', 89*9c5db199SXin Li video_src_path=file_path) 90*9c5db199SXin Li self._player.load_video() 91*9c5db199SXin Li 92*9c5db199SXin Li if fullscreen: 93*9c5db199SXin Li self._display_facade.set_fullscreen(True) 94*9c5db199SXin Li 95*9c5db199SXin Li 96*9c5db199SXin Li def start_playback(self, blocking=False): 97*9c5db199SXin Li """Starts video playback on the webpage. 98*9c5db199SXin Li 99*9c5db199SXin Li Before calling this method, user should call prepare_playback to 100*9c5db199SXin Li put the files to /tmp and load the webpage. 101*9c5db199SXin Li 102*9c5db199SXin Li @param blocking: Blocks this call until playback finishes. 103*9c5db199SXin Li 104*9c5db199SXin Li """ 105*9c5db199SXin Li self._player.play() 106*9c5db199SXin Li if blocking: 107*9c5db199SXin Li self._player.wait_video_ended() 108*9c5db199SXin Li 109*9c5db199SXin Li 110*9c5db199SXin Li def pause_playback(self): 111*9c5db199SXin Li """Pauses playback on the webpage.""" 112*9c5db199SXin Li self._player.pause() 113*9c5db199SXin Li 114*9c5db199SXin Li 115*9c5db199SXin Li def dropped_frame_count(self): 116*9c5db199SXin Li """ 117*9c5db199SXin Li Gets the number of dropped frames. 118*9c5db199SXin Li 119*9c5db199SXin Li @returns: An integer indicates the number of dropped frame. 120*9c5db199SXin Li 121*9c5db199SXin Li """ 122*9c5db199SXin Li return self._player.dropped_frame_count() 123*9c5db199SXin Li 124*9c5db199SXin Li 125*9c5db199SXin Li @check_arc_resource 126*9c5db199SXin Li def prepare_arc_playback(self, file_path, fullscreen=True): 127*9c5db199SXin Li """Copies the video file to be played into container and starts the app. 128*9c5db199SXin Li 129*9c5db199SXin Li User should call this method to put the file into container before 130*9c5db199SXin Li calling start_arc_playback. 131*9c5db199SXin Li 132*9c5db199SXin Li @param file_path: Path to the file to be played on Cros host. 133*9c5db199SXin Li @param fullscreen: Plays the video in fullscreen. 134*9c5db199SXin Li 135*9c5db199SXin Li """ 136*9c5db199SXin Li self._arc_resource.play_video.prepare_playback(file_path, fullscreen) 137*9c5db199SXin Li 138*9c5db199SXin Li 139*9c5db199SXin Li @check_arc_resource 140*9c5db199SXin Li def start_arc_playback(self, blocking_secs=None): 141*9c5db199SXin Li """Starts playback through Play Video app. 142*9c5db199SXin Li 143*9c5db199SXin Li Before calling this method, user should call set_arc_playback_file to 144*9c5db199SXin Li put the file into container and start the app. 145*9c5db199SXin Li 146*9c5db199SXin Li @param blocking_secs: A positive number indicates the timeout to wait 147*9c5db199SXin Li for the playback is finished. Set None to make 148*9c5db199SXin Li it non-blocking. 149*9c5db199SXin Li 150*9c5db199SXin Li 151*9c5db199SXin Li """ 152*9c5db199SXin Li self._arc_resource.play_video.start_playback(blocking_secs) 153*9c5db199SXin Li 154*9c5db199SXin Li 155*9c5db199SXin Li @check_arc_resource 156*9c5db199SXin Li def pause_arc_playback(self): 157*9c5db199SXin Li """Pauses playback through Play Video app.""" 158*9c5db199SXin Li self._arc_resource.play_video.pause_playback() 159*9c5db199SXin Li 160*9c5db199SXin Li 161*9c5db199SXin Li @check_arc_resource 162*9c5db199SXin Li def stop_arc_playback(self): 163*9c5db199SXin Li """Stops playback through Play Video app.""" 164*9c5db199SXin Li self._arc_resource.play_video.stop_playback() 165