我正在尝试在我的 CI 服务器上获取失败测试的视频。
目标是在每次测试时开始截屏,然后当它失败时将视频保存在某个地方,当它通过时,删除视频。CI 服务器将使用 adb 获取文件。
我正在考虑screenrecord
为此目的使用。我认为这很容易,因为这个二进制文件已经存在于设备上,并且在通过 ADB 使用时效果非常好。
这是我以编程方式使用它的方式:打开一个线程,它将启动并跟踪该过程,并在测试开始之前启动它:
@Before
fun baseBefore() {
startScreenRecording()
}
private fun startScreenRecording() {
Timber.d("screenrecord: start record thread")
screenRecordThread = Thread(screenRecordRunnable)
screenRecordThread.start()
Timber.d("screenrecord: wait a bit")
Thread.sleep(5000)
Timber.d("screenrecord: go")
}
我正在等待 5 秒钟,因为screenrecord
可能需要一些时间才能启动。
这是实际的screenrecord
调用:
private class ScreenRecordRunnable : Runnable {
private lateinit var process: Process
override fun run() {
try {
Timber.d("screenrecord-record: start")
// tried also with the following: no luck
// process = ProcessBuilder(
// "/system/bin/screenrecord",
// "--time-limit", "60",
// "--verbose",
// "--bit-rate", "4M",
// "--bugreport",
// "/sdcard/test.mp4",
// "&"
// )
// .redirectErrorStream(true)
// .start()
process = Runtime.getRuntime().exec("/system/bin/screenrecord --time-limit 60 --verbose --bit-rate 4M --bugreport /sdcard/test.mp4")
val reader = BufferedReader(InputStreamReader(process.inputStream))
while (true) {
val line = reader.readLine() ?: break
Timber.d("screenrecord-record: log: $line")
}
Timber.d("screenrecord-record: wait for (isAlive: ${process.isAlive})")
process.waitFor()
Timber.d("screenrecord-record: wait stopped; exit value: ${process.exitValue()}")
reader.close()
} catch (e: IOException) {
throw Exception(e)
} catch (e: InterruptedException) {
throw Exception(e)
}
}
}
在该@After
方法中,我检索screenrecord
进程的 PID(通过pgrep
,它可以工作)并发送它kill -2 $pid
,以模拟该进程上的 Ctrl-C,以停止屏幕录制。
不包括此代码,因为它似乎不相关。
这是正在发生的事情:
12-16 21:11:31.527 5487 5543 D InstrumentedTestBase: screenrecord: start record thread
12-16 21:11:31.528 5487 5543 D InstrumentedTestBase: screenrecord: wait a bit
12-16 21:11:31.528 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: start
12-16 21:11:31.633 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Main display is 1440x2960 @60.00fps (orientation=0)
12-16 21:11:31.633 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Configuring recorder for 1440x2960 video/avc at 4.00Mbps
12-16 21:11:32.362 5574 5574 W screenrecord: type=1400 audit(0.0:22906): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=19753 scontext=u:r:untrusted_app:s0:c242,c256,c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0
12-16 21:11:32.492 5574 5574 W screenrecord: type=1400 audit(0.0:22907): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=19753 scontext=u:r:untrusted_app:s0:c242,c256,c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0
12-16 21:11:32.543 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Bugreport overlay created
12-16 21:11:32.544 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Content area is 1440x2960 at offset x=0 y=0
12-16 21:11:39.780 5487 5543 D InstrumentedTestBase: screenrecord: go
12-16 21:11:43.546 5487 5543 D InstrumentedTestBase: screenrecord: wait for record thread to stop
12-16 21:11:43.546 5487 5543 D InstrumentedTestBase$ScreenRecordStopperRunnable: screenrecord-stopper: get pid
12-16 21:11:43.578 5487 5543 D InstrumentedTestBase$ScreenRecordStopperRunnable: screenrecord-stopper: getpid log: 5574
12-16 21:11:43.579 5487 5543 D InstrumentedTestBase$ScreenRecordStopperRunnable: screenrecord-stopper: kill -2 5574
12-16 21:11:43.679 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Encoder stopping; recorded 1 frames in 7 seconds
12-16 21:11:43.680 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Stopping encoder and muxer
12-16 21:11:43.784 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Executing: /system/bin/am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/test.mp4
12-16 21:11:43.860 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: log: Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/test.mp4 flg=0x400000 }
12-16 21:11:43.919 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: wait for (isAlive: true)
12-16 21:11:43.919 5487 5573 D InstrumentedTestBase$ScreenRecordRunnable: screenrecord-record: wait stopped; exit value: 0
12-16 21:11:44.013 5487 5543 D InstrumentedTestBase: screenrecord: rename video file to /sdcard/failed_test_emptyDeclarationState.mp4
如您所见,一切看起来都很好,除了只保存了一帧:
编码器停止;在 7 秒内记录 1 帧
该框架是--bugreport
结果,带有设备信息(品牌、型号等)。
我能做些什么来捕捉该测试的视频吗?