Index: build/android/devil/android/tools/video_recorder.py |
diff --git a/build/android/devil/android/tools/video_recorder.py b/build/android/devil/android/tools/video_recorder.py |
deleted file mode 100755 |
index 685b682ea866c952f3d563ff389d9a0059324438..0000000000000000000000000000000000000000 |
--- a/build/android/devil/android/tools/video_recorder.py |
+++ /dev/null |
@@ -1,173 +0,0 @@ |
-#!/usr/bin/env python |
-# Copyright 2015 The Chromium Authors. All rights reserved. |
-# Use of this source code is governed by a BSD-style license that can be |
-# found in the LICENSE file. |
- |
-"""Captures a video from an Android device.""" |
- |
-import argparse |
-import logging |
-import os |
-import threading |
-import time |
-import sys |
- |
-if __name__ == '__main__': |
- sys.path.append(os.path.abspath(os.path.join( |
- os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))) |
-from devil.android import device_signal |
-from devil.android import device_utils |
-from devil.android.tools import script_common |
-from devil.utils import cmd_helper |
-from devil.utils import reraiser_thread |
-from devil.utils import timeout_retry |
- |
- |
-class VideoRecorder(object): |
- """Records a screen capture video from an Android Device (KitKat or newer).""" |
- |
- def __init__(self, device, megabits_per_second=4, size=None, |
- rotate=False): |
- """Creates a VideoRecorder instance. |
- |
- Args: |
- device: DeviceUtils instance. |
- host_file: Path to the video file to store on the host. |
- megabits_per_second: Video bitrate in megabits per second. Allowed range |
- from 0.1 to 100 mbps. |
- size: Video frame size tuple (width, height) or None to use the device |
- default. |
- rotate: If True, the video will be rotated 90 degrees. |
- """ |
- self._bit_rate = megabits_per_second * 1000 * 1000 |
- self._device = device |
- self._device_file = ( |
- '%s/screen-recording.mp4' % device.GetExternalStoragePath()) |
- self._recorder_thread = None |
- self._rotate = rotate |
- self._size = size |
- self._started = threading.Event() |
- |
- def __enter__(self): |
- self.Start() |
- |
- def Start(self, timeout=None): |
- """Start recording video.""" |
- def screenrecord_started(): |
- return bool(self._device.GetPids('screenrecord')) |
- |
- if screenrecord_started(): |
- raise Exception("Can't run multiple concurrent video captures.") |
- |
- self._started.clear() |
- self._recorder_thread = reraiser_thread.ReraiserThread(self._Record) |
- self._recorder_thread.start() |
- timeout_retry.WaitFor( |
- screenrecord_started, wait_period=1, max_tries=timeout) |
- self._started.wait(timeout) |
- |
- def _Record(self): |
- cmd = ['screenrecord', '--verbose', '--bit-rate', str(self._bit_rate)] |
- if self._rotate: |
- cmd += ['--rotate'] |
- if self._size: |
- cmd += ['--size', '%dx%d' % self._size] |
- cmd += [self._device_file] |
- for line in self._device.adb.IterShell( |
- ' '.join(cmd_helper.SingleQuote(i) for i in cmd), None): |
- if line.startswith('Content area is '): |
- self._started.set() |
- |
- def __exit__(self, _exc_type, _exc_value, _traceback): |
- self.Stop() |
- |
- def Stop(self): |
- """Stop recording video.""" |
- if not self._device.KillAll('screenrecord', signum=device_signal.SIGINT, |
- quiet=True): |
- logging.warning('Nothing to kill: screenrecord was not running') |
- self._recorder_thread.join() |
- |
- def Pull(self, host_file=None): |
- """Pull resulting video file from the device. |
- |
- Args: |
- host_file: Path to the video file to store on the host. |
- Returns: |
- Output video file name on the host. |
- """ |
- # TODO(jbudorick): Merge filename generation with the logic for doing so in |
- # DeviceUtils. |
- host_file_name = ( |
- host_file |
- or 'screen-recording-%s-%s.mp4' % ( |
- str(self._device), |
- time.strftime('%Y%m%dT%H%M%S', time.localtime()))) |
- host_file_name = os.path.abspath(host_file_name) |
- self._device.PullFile(self._device_file, host_file_name) |
- self._device.RunShellCommand('rm -f "%s"' % self._device_file) |
- return host_file_name |
- |
- |
-def main(): |
- # Parse options. |
- parser = argparse.ArgumentParser(description=__doc__) |
- parser.add_argument('-d', '--device', dest='devices', action='append', |
- help='Serial number of Android device to use.') |
- parser.add_argument('--blacklist-file', help='Device blacklist JSON file.') |
- parser.add_argument('-f', '--file', metavar='FILE', |
- help='Save result to file instead of generating a ' |
- 'timestamped file name.') |
- parser.add_argument('-v', '--verbose', action='store_true', |
- help='Verbose logging.') |
- parser.add_argument('-b', '--bitrate', default=4, type=float, |
- help='Bitrate in megabits/s, from 0.1 to 100 mbps, ' |
- '%default mbps by default.') |
- parser.add_argument('-r', '--rotate', action='store_true', |
- help='Rotate video by 90 degrees.') |
- parser.add_argument('-s', '--size', metavar='WIDTHxHEIGHT', |
- help='Frame size to use instead of the device ' |
- 'screen size.') |
- parser.add_argument('host_file', nargs='?', |
- help='File to which the video capture will be written.') |
- |
- args = parser.parse_args() |
- |
- host_file = args.host_file or args.file |
- |
- if args.verbose: |
- logging.getLogger().setLevel(logging.DEBUG) |
- |
- size = (tuple(int(i) for i in args.size.split('x')) |
- if args.size |
- else None) |
- |
- def record_video(device, stop_recording): |
- recorder = VideoRecorder( |
- device, megabits_per_second=args.bitrate, size=size, rotate=args.rotate) |
- with recorder: |
- stop_recording.wait() |
- |
- f = None |
- if host_file: |
- root, ext = os.path.splitext(host_file) |
- f = '%s_%s%s' % (root, str(device), ext) |
- f = recorder.Pull(f) |
- print 'Video written to %s' % os.path.abspath(f) |
- |
- parallel_devices = device_utils.DeviceUtils.parallel( |
- script_common.GetDevices(args.devices, args.blacklist_file), |
- async=True) |
- stop_recording = threading.Event() |
- running_recording = parallel_devices.pMap(record_video, stop_recording) |
- print 'Recording. Press Enter to stop.', |
- sys.stdout.flush() |
- raw_input() |
- stop_recording.set() |
- |
- running_recording.pGet(None) |
- return 0 |
- |
- |
-if __name__ == '__main__': |
- sys.exit(main()) |