1 # Copyright 2013 The Chromium 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.
10 from pylib
import cmd_helper
11 from pylib
import device_signal
12 from pylib
.device
import device_errors
14 # TODO(jbudorick) Remove once telemetry gets switched over.
15 import pylib
.android_commands
16 import pylib
.device
.device_utils
19 class VideoRecorder(object):
20 """Records a screen capture video from an Android Device (KitKat or newer).
23 device: DeviceUtils instance.
24 host_file: Path to the video file to store on the host.
25 megabits_per_second: Video bitrate in megabits per second. Allowed range
27 size: Video frame size tuple (width, height) or None to use the device
29 rotate: If True, the video will be rotated 90 degrees.
31 def __init__(self
, device
, megabits_per_second
=4, size
=None,
33 # TODO(jbudorick) Remove once telemetry gets switched over.
34 if isinstance(device
, pylib
.android_commands
.AndroidCommands
):
35 device
= pylib
.device
.device_utils
.DeviceUtils(device
)
38 '%s/screen-recording.mp4' % device
.GetExternalStoragePath())
40 self
._recorder
_stdout
= None
41 self
._is
_started
= False
45 self
._args
+= ['-s', str(self
._device
)]
46 self
._args
+= ['shell', 'screenrecord', '--verbose']
47 self
._args
+= ['--bit-rate', str(megabits_per_second
* 1000 * 1000)]
49 self
._args
+= ['--size', '%dx%d' % size
]
51 self
._args
+= ['--rotate']
52 self
._args
+= [self
._device
_file
]
55 """Start recording video."""
56 self
._recorder
_stdout
= tempfile
.mkstemp()[1]
57 self
._recorder
= cmd_helper
.Popen(
58 self
._args
, stdout
=open(self
._recorder
_stdout
, 'w'))
59 if not self
._device
.GetPids('screenrecord'):
60 raise RuntimeError('Recording failed. Is your device running Android '
64 if not self
._is
_started
:
65 for line
in open(self
._recorder
_stdout
):
66 self
._is
_started
= line
.startswith('Content area is ')
69 return self
._is
_started
72 """Stop recording video."""
73 os
.remove(self
._recorder
_stdout
)
74 self
._is
_started
= False
75 if not self
._recorder
:
77 if not self
._device
.KillAll('screenrecord', signum
=device_signal
.SIGINT
,
79 logging
.warning('Nothing to kill: screenrecord was not running')
82 def Pull(self
, host_file
=None):
83 """Pull resulting video file from the device.
86 host_file: Path to the video file to store on the host.
88 Output video file name on the host.
90 # TODO(jbudorick): Merge filename generation with the logic for doing so in
94 or 'screen-recording-%s.mp4' % time
.strftime('%Y%m%dT%H%M%S',
96 host_file_name
= os
.path
.abspath(host_file_name
)
97 self
._device
.PullFile(self
._device
_file
, host_file_name
)
98 self
._device
.RunShellCommand('rm -f "%s"' % self
._device
_file
)