1#!/usr/bin/env python
2
3# Copyright (c) 2012 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Takes a screenshot or a screen video capture from an Android device."""
8
9import logging
10import optparse
11import os
12import sys
13
14from pylib import android_commands
15from pylib import screenshot
16from pylib.device import device_utils
17
18def _PrintMessage(heading, eol='\n'):
19  sys.stdout.write('%s%s' % (heading, eol))
20  sys.stdout.flush()
21
22
23def _CaptureScreenshot(device, host_file):
24  host_file = device.TakeScreenshot(host_file)
25  _PrintMessage('Screenshot written to %s' % os.path.abspath(host_file))
26
27
28def _CaptureVideo(device, host_file, options):
29  size = tuple(map(int, options.size.split('x'))) if options.size else None
30  recorder = screenshot.VideoRecorder(device,
31                                      megabits_per_second=options.bitrate,
32                                      size=size,
33                                      rotate=options.rotate)
34  try:
35    recorder.Start()
36    _PrintMessage('Recording. Press Enter to stop...', eol='')
37    raw_input()
38  finally:
39    recorder.Stop()
40  host_file = recorder.Pull(host_file)
41  _PrintMessage('Video written to %s' % os.path.abspath(host_file))
42
43
44def main():
45  # Parse options.
46  parser = optparse.OptionParser(description=__doc__,
47                                 usage='screenshot.py [options] [filename]')
48  parser.add_option('-d', '--device', metavar='ANDROID_DEVICE', help='Serial '
49                    'number of Android device to use.', default=None)
50  parser.add_option('-f', '--file', help='Save result to file instead of '
51                    'generating a timestamped file name.', metavar='FILE')
52  parser.add_option('-v', '--verbose', help='Verbose logging.',
53                    action='store_true')
54  video_options = optparse.OptionGroup(parser, 'Video capture')
55  video_options.add_option('--video', help='Enable video capturing. Requires '
56                           'Android KitKat or later', action='store_true')
57  video_options.add_option('-b', '--bitrate', help='Bitrate in megabits/s, '
58                           'from 0.1 to 100 mbps, %default mbps by default.',
59                           default=4, type='float')
60  video_options.add_option('-r', '--rotate', help='Rotate video by 90 degrees.',
61                           default=False, action='store_true')
62  video_options.add_option('-s', '--size', metavar='WIDTHxHEIGHT',
63                           help='Frame size to use instead of the device '
64                           'screen size.', default=None)
65  parser.add_option_group(video_options)
66
67  (options, args) = parser.parse_args()
68
69  if options.verbose:
70    logging.getLogger().setLevel(logging.DEBUG)
71
72  if not options.device and len(android_commands.GetAttachedDevices()) > 1:
73    parser.error('Multiple devices are attached. '
74                 'Please specify device serial number with --device.')
75
76  if len(args) > 1:
77    parser.error('Too many positional arguments.')
78  host_file = args[0] if args else options.file
79  device = device_utils.DeviceUtils(options.device)
80
81  if options.video:
82    _CaptureVideo(device, host_file, options)
83  else:
84    _CaptureScreenshot(device, host_file)
85  return 0
86
87
88if __name__ == '__main__':
89  sys.exit(main())
90