В продолжение данной темы,
посмотрим, как заставить Selenium Grid записывать видео не только на Linux, но и Windows OS. Оригинал.
После небольшого исследования я пришел к выводу, что для организации кросс-платформенного решения лучше все же взять ffmpeg
, вместо avconv
. Ввиду отсутствия отличий в плане ключевых функций, изменения конснутся по сути только нескольких IO опций.
final String display = SystemUtils.IS_OS_LINUX ? System.getenv("DISPLAY") : "desktop";
final String recorder = SystemUtils.IS_OS_LINUX ? "x11grab" : "gdigrab";
final String[] commandsSequence = new String[]{
RECORDING_TOOL, "-y",
"-video_size", info.getResolution(),
"-f", recorder,
"-i", display,
"-an",
"-vcodec", "libx264",
"-crf", String.valueOf(info.getQuality()),
"-r", String.valueOf(info.getFrameRate()),
outputPath
};
Вместо x11grab
будет использоваться gdigrab, который поставляется вместе с Windows. Ну а в качестве input мы должны сообщить тулу, что намеряны записывать desktop
.
Стоит также отметить, что в случае наличия видео записи с указанным именем, ffmpeg
будет ожидать подтверждения пользователя о перезаписи. Т.к. мы запускаем процесс в non-interactive mode, для избежания потенциальных проблем следует указать флаг -y
.
Следующий challenge касатется остановки видео записи. Ввиду того, что ffmpeg
требует корретного закрытия для осуществления финализации видео потока, мы не можем просто так прибить процесс командой taskkill
. Такой же трюк с INT
сигналом, как и в Linux, не поддерживается из коробки в Windows. Посему, для решения данной задачи был использован сторонний тул, написанный на плюсах, который умеет делать ровно то же самое, что и линуксовый аналог. От нас лишь требуется получить ffmpeg PID
, и передать его данному тулу.
public static void stopVideoRecording() {
final String output = SystemUtils.IS_OS_LINUX ?
runCommand("pkill", "-INT", RECORDING_TOOL) :
runCommand(Optional.ofNullable(SEND_CTRL_C_TOOL_PATH).orElse(SEND_CTRL_C_TOOL_NAME), getPidOf(RECORDING_TOOL));
LOGGER.info("Stop recording output log: " + output);
}
Следует отметить, что сам тул - весьма экзотический. И найти его на просторах всемирной паутины оказалось не так уж и просто. Посему, во избежание дополнительных сложностей с поиском, он был помещен в ресурсы проекта. Но использовать его напрямую из jar файла мы не сможем. Для этого нам предвариательно понадобится его извлечь, скажем, в OS-specific tmp folder. И сделать это желательно уже при старте самого грида.
public static void main(String[] args) throws Exception {
if (SystemUtils.IS_OS_WINDOWS)
exportResourceToTmpDir(SEND_CTRL_C_TOOL_NAME).ifPresent(path -> SEND_CTRL_C_TOOL_PATH = path);
GridLauncher.main(args);
}
Там самым, мы определили новую точку входа в приложение, что следует обязательно указать maven-assembly-plugin
’у.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.blogspot.notes.automation.qa.grid.core.CustomGridLauncher</mainClass>
</manifest>
</archive>
</configuration>
Вот собственно и все. Стоит разве что только отметить, что раз уж мы поменяли avconv
на ffmpeg
, следует позаботиться и об обновлении docker-selenium исходников.
#=====
# VNC, ffmpeg
#=====
RUN apt-get update -qqy \
&& DEBIAN_FRONTEND=noninteractive apt-get -qqy install software-properties-common python-software-properties \
&& DEBIAN_FRONTEND=noninteractive add-apt-repository ppa:djcj/hybrid \
&& apt-get -qqy install \
x11vnc \
ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p ~/.vnc \
&& x11vnc -storepasswd secret ~/.vnc/passwd
Ввиду того, что ffmpeg
отсутствует в официальных Ubuntu-репозиториях, необходимо вначале указать его точное месторасположение, подключив ppa:djcj/hybrid
, перед непосредственной установкой.
На этом все. Исходники, как обычно, на GitHub. Не забываем об установке ffmpeg и помещении оного в system path
, а также - ставить лайки, если пост вам оказался полезным.