Skip to content

Commit 1a3b0e1

Browse files
authored
Initial set of files to support video recording (#1111) [deploy][prerelease]
* Initial set of files to support video recording * Adding Selenium Grid logo as wallpaper for Fluxbox * Adding video image build to Makefile * Fixing copy&paste error * Adding docker-compose-v3-video.yml as example * Simple docs showing how to use video container * Adjusting tags in docker-compose-v3-video.yml * Updating script that updates tags and dates in docs * Removing ambiguous commentary * Adding ffmpeg version to release notes
1 parent 7e48f59 commit 1a3b0e1

11 files changed

+259
-2
lines changed

Makefile

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,20 @@ BUILD_ARGS := $(BUILD_ARGS)
1010
MAJOR := $(word 1,$(subst ., ,$(TAG_VERSION)))
1111
MINOR := $(word 2,$(subst ., ,$(TAG_VERSION)))
1212
MAJOR_MINOR_PATCH := $(word 1,$(subst -, ,$(TAG_VERSION)))
13+
FFMPEG_TAG_VERSION := $(or $(FFMPEG_TAG_VERSION),$(FFMPEG_TAG_VERSION),ffmpeg-4.3.1)
1314

14-
all: hub distributor router sessions event_bus chrome firefox opera standalone_chrome standalone_firefox standalone_opera
15+
all: hub \
16+
distributor \
17+
router \
18+
sessions \
19+
event_bus \
20+
chrome \
21+
firefox \
22+
opera \
23+
standalone_chrome \
24+
standalone_firefox \
25+
standalone_opera \
26+
video
1527

1628
generate_all: \
1729
generate_hub \
@@ -106,6 +118,9 @@ generate_standalone_opera:
106118
standalone_opera: opera generate_standalone_opera
107119
cd ./StandaloneOpera && docker build $(BUILD_ARGS) -t $(NAME)/standalone-opera:$(TAG_VERSION) .
108120

121+
video:
122+
cd ./Video && docker build $(BUILD_ARGS) -t $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) .
123+
109124

110125
# https://github.com/SeleniumHQ/docker-selenium/issues/992
111126
# Additional tags for browser images
@@ -257,6 +272,7 @@ release: tag_major_minor
257272
docker push $(NAME)/standalone-chrome:$(MAJOR_MINOR_PATCH)
258273
docker push $(NAME)/standalone-firefox:$(MAJOR_MINOR_PATCH)
259274
docker push $(NAME)/standalone-opera:$(MAJOR_MINOR_PATCH)
275+
docker push $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE)
260276

261277
test: test_chrome \
262278
test_firefox \
@@ -316,4 +332,5 @@ test_opera_standalone:
316332
standalone_firefox \
317333
tag_latest \
318334
tag_and_push_browser_images \
319-
test
335+
test \
336+
video

NodeBase/Dockerfile.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ RUN sudo chmod -R 777 ${HOME} \
120120
COPY start-vnc.sh \
121121
/opt/bin/
122122

123+
#==============================
124+
# Selenium Grid logo as wallpaper for Fluxbox
125+
#==============================
126+
COPY selenium_grid_logo.png /usr/share/images/fluxbox/ubuntu-light.png
127+
123128
#============================
124129
# Some configuration options
125130
#============================

NodeBase/selenium_grid_logo.png

23.2 KB
Loading

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,48 @@ instructions on top of it.
128128

129129
___
130130

131+
## Video recording ![BETA](https://img.shields.io/badge/beta!-blue?style=for-the-badge)
132+
133+
It is possible to record your tests running in containers by using the `selenium/video:ffmpeg-4.3.1-20200920`
134+
Docker image. One container is needed per each container where a browser is running. This means if you are
135+
running 5 Nodes/Standalone containers, you will need 5 video containers, the mapping is 1-1.
136+
137+
Currently, the only way to do this mapping is manually (either starting the containers manually, or through
138+
`docker-compose`). We are iterating on this process and probably this setup will be more simple in the future.
139+
140+
The video Docker image we provide is based on the ffmpeg Ubuntu image provided by the
141+
[jrottenberg/ffmpeg](https://github.com/jrottenberg/ffmpeg) project, thank you for providing this image and
142+
simplifying our work :tada:
143+
144+
**Notes**:
145+
- If you have questions or feedback, please use the community contact points shown [here](https://www.selenium.dev/support/).
146+
- Please report any bugs through GitHub [issues](https://github.com/SeleniumHQ/docker-selenium/issues/new/choose), and provide
147+
all the information requested on the template.
148+
- Video recording for headless browsers is not supported.
149+
- Video recording tends to use considerable amounts of CPU. Normally you should estimate 1CPU per video container,
150+
and 1 CPU per browser container.
151+
- Videos are stored in the `/videos` directory inside the video container. Map a local directory to get the videos.
152+
- If you are running more than one video container, be sure to overwrite the video file name through the `FILE_NAME`
153+
environment variable to avoid unexpected results.
154+
155+
This example shows how to start the containers manually:
156+
157+
``` bash
158+
$ docker network create grid
159+
$ docker run -d -p 4444:4444 -p 6900:5900 --net grid --name selenium -v /dev/shm:/dev/shm selenium/standalone-chrome:4.0.0-alpha-7-20200907
160+
$ docker run -d --net grid --name video -v /tmp/videos:/videos selenium/video:ffmpeg-4.3.1-20200907
161+
# Run your tests
162+
$ docker stop video && docker rm video
163+
$ docker stop selenium && docker rm selenium
164+
```
165+
After the containers are stopped and removed, you should see a video file on your machine's `/tmp/videos` directory.
166+
167+
Here is an example using a Hub and 3 Nodes (Chrome, Firefox, and Opera):
168+
169+
[`docker-compose-v3-video.yml`](docker-compose-v3-video.yml)
170+
171+
___
172+
131173
## Deploying to Kubernetes (:warning: not tested yet with Selenium 4 images)
132174

133175
Check out [the Kubernetes examples](https://github.com/kubernetes/examples/tree/master/staging/selenium)

Video/Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM jrottenberg/ffmpeg:4.3.1-ubuntu1804
2+
LABEL authors="Selenium <[email protected]>"
3+
4+
#================================================
5+
# Customize sources for apt-get
6+
#================================================
7+
RUN echo "deb http://archive.ubuntu.com/ubuntu bionic main universe\n" > /etc/apt/sources.list \
8+
&& echo "deb http://archive.ubuntu.com/ubuntu bionic-updates main universe\n" >> /etc/apt/sources.list \
9+
&& echo "deb http://security.ubuntu.com/ubuntu bionic-security main universe\n" >> /etc/apt/sources.list
10+
11+
# No interactive frontend during docker build
12+
ENV DEBIAN_FRONTEND=noninteractive \
13+
DEBCONF_NONINTERACTIVE_SEEN=true
14+
15+
#========================
16+
# Supervisor
17+
#========================
18+
RUN apt-get -qqy update \
19+
&& apt-get -qqy --no-install-recommends install \
20+
supervisor x11-xserver-utils \
21+
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*
22+
23+
#======================================
24+
# Add Supervisor configuration file
25+
#======================================
26+
COPY supervisord.conf /etc
27+
COPY entry_point.sh video.sh /opt/bin/
28+
29+
RUN mkdir -p /var/run/supervisor /var/log/supervisor /videos
30+
31+
ENTRYPOINT ["/opt/bin/entry_point.sh"]
32+
CMD ["/opt/bin/entry_point.sh"]

Video/entry_point.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
3+
/usr/bin/supervisord --configuration /etc/supervisord.conf &
4+
5+
SUPERVISOR_PID=$!
6+
7+
function shutdown {
8+
echo "Trapped SIGTERM/SIGINT/x so shutting down supervisord..."
9+
kill -s SIGTERM ${SUPERVISOR_PID}
10+
wait ${SUPERVISOR_PID}
11+
echo "Shutdown complete"
12+
}
13+
14+
trap shutdown SIGTERM SIGINT
15+
wait ${SUPERVISOR_PID}

Video/supervisord.conf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; Documentation of this file format -> http://supervisord.org/configuration.html
2+
3+
[supervisord]
4+
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
5+
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
6+
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
7+
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
8+
loglevel=info ; (log level;default info; others: debug,warn,trace)
9+
pidfile=/var/run/supervisor/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
10+
nodaemon=true ; (start in foreground if true;default false)
11+
minfds=1024 ; (min. avail startup file descriptors;default 1024)
12+
minprocs=200 ; (min. avail process descriptors;default 200)
13+
14+
[program:video-recording]
15+
priority=0
16+
command=/opt/bin/video.sh
17+
autostart=true
18+
autorestart=false
19+
startsecs=0
20+
startretries=0
21+
stopsignal=INT
22+
23+
;Logs (all activity redirected to stdout so it can be seen through "docker logs"
24+
redirect_stderr=true
25+
stdout_logfile=/dev/stdout
26+
stdout_logfile_maxbytes=0
27+

Video/video.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
3+
VIDEO_SIZE=${VIDEO_SIZE:-"1360x1020"}
4+
DISPLAY_CONTAINER_NAME=${DISPLAY_CONTAINER_NAME:-"selenium"}
5+
DISPLAY=${DISPLAY:-"99"}
6+
FILE_NAME=${FILE_NAME:-"video.mp4"}
7+
FRAME_RATE=${FRAME_RATE:-"15"}
8+
CODEC=${CODEC:-"libx264"}
9+
PRESET=${PRESET:-"-preset ultrafast"}
10+
11+
return_code=1
12+
max_attempts=50
13+
attempts=0
14+
echo 'Checking if the display is open...'
15+
until [ $return_code -eq 0 -o $attempts -eq $max_attempts ]; do
16+
xset -display ${DISPLAY_CONTAINER_NAME}:${DISPLAY} b off > /dev/null 2>&1
17+
return_code=$?
18+
if [ $return_code -ne 0 ]; then
19+
echo 'Waiting before next display check...'
20+
sleep 0.5
21+
fi
22+
attempts=$((attempts+1))
23+
done
24+
25+
# exec replaces the video.sh process with ffmpeg, this makes easier to pass the process termination signal
26+
exec ffmpeg -y -f x11grab -video_size ${VIDEO_SIZE} -r ${FRAME_RATE} -i ${DISPLAY_CONTAINER_NAME}:${DISPLAY}.0 -codec:v ${CODEC} ${PRESET} -pix_fmt yuv420p "/videos/$FILE_NAME"
27+

docker-compose-v3-video.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# To execute this docker-compose yml file use `docker-compose -f docker-compose-v3-video.yml up`
2+
# Add the `-d` flag at the end for detached execution
3+
# To stop the execution, hit Ctrl+C, and then `docker-compose -f docker-compose-v3-video.yml down`
4+
version: "3"
5+
services:
6+
chrome:
7+
image: selenium/node-chrome:4.0.0-alpha-7-prerelease-20200907
8+
volumes:
9+
- /dev/shm:/dev/shm
10+
depends_on:
11+
- selenium-hub
12+
environment:
13+
- SE_EVENT_BUS_HOST=selenium-hub
14+
- SE_EVENT_BUS_PUBLISH_PORT=4442
15+
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
16+
ports:
17+
- "6900:5900"
18+
19+
firefox:
20+
image: selenium/node-firefox:4.0.0-alpha-7-prerelease-20200907
21+
volumes:
22+
- /dev/shm:/dev/shm
23+
depends_on:
24+
- selenium-hub
25+
environment:
26+
- SE_EVENT_BUS_HOST=selenium-hub
27+
- SE_EVENT_BUS_PUBLISH_PORT=4442
28+
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
29+
ports:
30+
- "6901:5900"
31+
32+
opera:
33+
image: selenium/node-opera:4.0.0-alpha-7-prerelease-20200907
34+
volumes:
35+
- /dev/shm:/dev/shm
36+
depends_on:
37+
- selenium-hub
38+
environment:
39+
- SE_EVENT_BUS_HOST=selenium-hub
40+
- SE_EVENT_BUS_PUBLISH_PORT=4442
41+
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
42+
ports:
43+
- "6902:5900"
44+
45+
chrome_video:
46+
image: selenium/video:ffmpeg-4.3.1-20200920
47+
volumes:
48+
- /tmp/videos:/videos
49+
depends_on:
50+
- chrome
51+
environment:
52+
- DISPLAY_CONTAINER_NAME=chrome
53+
- FILE_NAME=chrome_video.mp4
54+
55+
firefox_video:
56+
image: selenium/video:ffmpeg-4.3.1-20200920
57+
volumes:
58+
- /tmp/videos:/videos
59+
depends_on:
60+
- firefox
61+
environment:
62+
- DISPLAY_CONTAINER_NAME=firefox
63+
- FILE_NAME=firefox_video.mp4
64+
65+
opera_video:
66+
image: selenium/video:ffmpeg-4.3.1-20200907
67+
volumes:
68+
- /tmp/videos:/videos
69+
depends_on:
70+
- opera
71+
environment:
72+
- DISPLAY_CONTAINER_NAME=firefox
73+
- FILE_NAME=opera_video.mp4
74+
75+
selenium-hub:
76+
image: selenium/hub:4.0.0-alpha-7-prerelease-20200907
77+
container_name: selenium-hub
78+
ports:
79+
- "4442:4442"
80+
- "4443:4443"
81+
- "4444:4444"

generate_release_notes.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ FIREFOX_VERSION=$(docker run --rm selenium/node-firefox:${TAG_VERSION} firefox -
1717
GECKODRIVER_VERSION=$(docker run --rm selenium/node-firefox:${TAG_VERSION} geckodriver --version | awk 'NR==1{print $2}')
1818
OPERA_VERSION=$(docker run --rm selenium/node-opera:${TAG_VERSION} opera --version)
1919
OPERADRIVER_VERSION=$(docker run --rm selenium/node-opera:${TAG_VERSION} operadriver --version | awk 'NR==1{print $2}')
20+
FFMPEG_VERSION=$(docker run --entrypoint="" --rm selenium/video:ffmpeg-4.3.1-${BUILD_DATE} ffmpeg -version | awk '{print $3}' | head -n 1)
2021

2122

2223
echo "" >> release_notes.md
@@ -28,6 +29,7 @@ echo "* Firefox: ${FIREFOX_VERSION}" >> release_notes.md
2829
echo "* GeckoDriver: ${GECKODRIVER_VERSION}" >> release_notes.md
2930
echo "* Opera: ${OPERA_VERSION}" >> release_notes.md
3031
echo "* OperaDriver: ${OPERADRIVER_VERSION}" >> release_notes.md
32+
echo "* ffmpeg: ${FFMPEG_VERSION}" >> release_notes.md
3133

3234
echo "" >> release_notes.md
3335
echo "### Published Docker images" >> release_notes.md

update_tag_in_docs_and_files.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
LATEST_TAG=$1
44
NEXT_TAG=$2
5+
LATEST_DATE=$(echo ${LATEST_TAG} | sed 's/.*-//')
6+
NEXT_DATE=$4$(echo ${NEXT_TAG} | sed 's/.*-//')
57

68
echo -e "\033[0;32m Updating tag displayed in docs and files...\033[0m"
79
echo -e "\033[0;32m LATEST_TAG -> ${LATEST_TAG}\033[0m"
@@ -10,6 +12,13 @@ echo -e "\033[0;32m NEXT_TAG -> ${NEXT_TAG}\033[0m"
1012
# If you want to test this locally and you are using macOS, do `brew install gnu-sed` and change `sed` for `gsed`.
1113
find . \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/${LATEST_TAG}/${NEXT_TAG}/g"
1214

15+
echo -e "\033[0;32m Updating date used in some docs and files...\033[0m"
16+
echo -e "\033[0;32m LATEST_DATE -> ${LATEST_DATE}\033[0m"
17+
echo -e "\033[0;32m NEXT_DATE -> ${NEXT_DATE}\033[0m"
18+
19+
# If you want to test this locally and you are using macOS, do `brew install gnu-sed` and change `sed` for `gsed`.
20+
find . \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/${LATEST_DATE}/${NEXT_DATE}/g"
21+
1322
git diff | cat
1423

1524
echo -e "\033[0;32m Text updated...\033[0m"

0 commit comments

Comments
 (0)