From 103d8f012e391efbc3ee615c14197a3cb86f8048 Mon Sep 17 00:00:00 2001 From: Christophe Monniez Date: Wed, 16 Sep 2020 13:27:48 +0000 Subject: [PATCH] [IMP] tests: use concat demuxer to encode frames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the sceencast argument is used to produce a video file of failing tests, the framerate is computed with a KISS average. This results in a misleading video flow. For example, if a tour step is stuck, the average could show a smooth transition instead of the reality. With this commit, the real duration of frames are used to produce the video. The result is a more realistic video flow. The configuration text file used by the ffmpeg concat demuxer is kept alongside with the video file so that it can be used for other purposes (e.g.: parse the durations to be used by a video player on runbot). closes odoo/odoo#58280 X-original-commit: 58eb6a4565c024077557fa2de83fdf831e5ef026 Signed-off-by: Xavier Dollé (xdo) Signed-off-by: Christophe Monniez (moc) --- odoo/tests/common.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 522de3a2434..1074b116554 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -1047,9 +1047,17 @@ class ChromeBrowser(): ffmpeg_path = None if ffmpeg_path: - framerate = int(len(self.screencast_frames) / (self.screencast_frames[-1].get('timestamp') - self.screencast_frames[0].get('timestamp'))) - r = subprocess.run([ffmpeg_path, '-framerate', str(framerate), '-i', '%s/frame_%%05d.png' % self.screencasts_frames_dir, outfile]) - self._logger.runbot('Screencast in: %s', outfile) + nb_frames = len(self.screencast_frames) + concat_script_path = os.path.join(self.screencasts_dir, fname.replace('.mp4', '.txt')) + with open(concat_script_path, 'w') as concat_file: + for i in range(nb_frames): + frame_file_path = os.path.join(self.screencasts_frames_dir, self.screencast_frames[i]['file_path']) + end_time = time.time() if i == nb_frames - 1 else self.screencast_frames[i+1]['timestamp'] + duration = end_time - self.screencast_frames[i]['timestamp'] + concat_file.write("file '%s'\nduration %s\n" % (frame_file_path, duration)) + concat_file.write("file '%s'" % frame_file_path) # needed by the concat plugin + r = subprocess.run([ffmpeg_path, '-intra', '-f', 'concat','-safe', '0', '-i', concat_script_path, '-pix_fmt', 'yuv420p', outfile]) + self._logger.log(25, 'Screencast in: %s', outfile) else: outfile = outfile.strip('.mp4') shutil.move(self.screencasts_frames_dir, outfile) @@ -1060,7 +1068,7 @@ class ChromeBrowser(): os.makedirs(self.screencasts_dir, exist_ok=True) self.screencasts_frames_dir = os.path.join(self.screencasts_dir, 'frames') os.makedirs(self.screencasts_frames_dir, exist_ok=True) - self._websocket_send('Page.startScreencast', params={'maxWidth': 1024, 'maxHeight': 576}) + self._websocket_send('Page.startScreencast') def set_cookie(self, name, value, path, domain): params = {'name': name, 'value': value, 'path': path, 'domain': domain} @@ -1130,6 +1138,7 @@ class ChromeBrowser(): elif res: self._logger.debug('chrome devtools protocol event: %s', res) self.take_screenshot() + self._save_screencast() raise ChromeBrowserException('Script timeout exceeded : %s' % (time.time() - start_time))