Skip to content

Commit 1ca9b53

Browse files
committed
Docker: FFmpeg with audio devices support (Pulse, Alsa)
Signed-off-by: Viet Nguyen Duc <[email protected]>
1 parent f692a3c commit 1ca9b53

File tree

9 files changed

+216
-180
lines changed

9 files changed

+216
-180
lines changed

.ffmpeg/Dockerfile

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ USER root
99
# Install build tools
1010
#======================================
1111
ARG TOOLS_DEPS="autoconf automake cmake libfreetype6 gcc build-essential libtool make nasm pkg-config zlib1g-dev numactl \
12-
libnuma-dev libx11-dev libxcb-shm0 libxcb1-dev yasm git curl jq wget ca-certificates"
12+
libnuma-dev libx11-dev libxcb-shm0 libxcb1-dev libpulse-dev libasound2-dev yasm git curl jq wget ca-certificates"
1313

1414
RUN apt-get update -qqy \
1515
&& apt-get upgrade -yq \
@@ -66,6 +66,8 @@ RUN cd /usr/local/src \
6666
--enable-nonfree \
6767
--enable-libx264 \
6868
--enable-libxcb \
69+
--enable-libpulse \
70+
--enable-alsa \
6971
--enable-static \
7072
&& make \
7173
&& make install
@@ -80,7 +82,9 @@ COPY --from=builder /usr/local/bin/rclone /usr/local/bin/rclone
8082

8183
RUN apt-get -qqy update \
8284
&& apt-get -qqy --no-install-recommends install \
83-
libx11-dev libxcb-shm0 libxcb1-dev \
85+
libx11-dev libxcb-shm0 libxcb1-dev libpulse-dev libasound2-dev \
86+
&& apt-get -qqy update \
87+
&& apt-get -yq upgrade \
8488
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*
8589

8690
RUN ldd /usr/local/bin/ffmpeg \

ENV_VARIABLES.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
| SE_HTTPS_PRIVATE_KEY | /opt/selenium/secrets/tls.key | | |
5454
| SE_ENABLE_TRACING | true | | |
5555
| SE_OTEL_EXPORTER_ENDPOINT | | | |
56-
| SE_OTEL_SERVICE_NAME | selenium-router | | |
56+
| SE_OTEL_SERVICE_NAME | selenium-standalone-docker | | |
5757
| SE_OTEL_JVM_ARGS | | | |
5858
| SE_OTEL_TRACES_EXPORTER | otlp | | |
5959
| SE_OTEL_JAVA_GLOBAL_AUTOCONFIGURE_ENABLED | true | | |
@@ -88,7 +88,7 @@
8888
| SE_REJECT_UNSUPPORTED_CAPS | false | | |
8989
| SE_NEW_SESSION_THREAD_POOL_SIZE | | | |
9090
| SE_SESSION_REQUEST_TIMEOUT | 300 | | |
91-
| SE_SESSION_RETRY_INTERVAL | 5 | | |
91+
| SE_SESSION_RETRY_INTERVAL | 15 | | |
9292
| SE_HEALTHCHECK_INTERVAL | 120 | | |
9393
| SE_RELAX_CHECKS | true | | |
9494
| SE_SESSION_QUEUE_HOST | | | |
@@ -119,3 +119,5 @@
119119
| SE_SUPERVISORD_LOG_FILE | /tmp/supervisord.log | | |
120120
| SE_SUPERVISORD_AUTO_RESTART | true | | |
121121
| SE_SUPERVISORD_START_RETRIES | 5 | | |
122+
| SE_RECORD_AUDIO | false | Flag to enable recording the audio source (default is Pulse Audio input) | |
123+
| SE_AUDIO_SOURCE | -f pulse -ac 2 -i default | FFmpeg arguments to record the audio source | |

Router/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ USER ${SEL_UID}
1313
# In seconds, maps to "--session-request-timeout"
1414
ENV SE_SESSION_REQUEST_TIMEOUT="300" \
1515
# In seconds, maps to "--session-retry-interval"
16-
SE_SESSION_RETRY_INTERVAL="5" \
16+
SE_SESSION_RETRY_INTERVAL="15" \
1717
SE_OTEL_SERVICE_NAME="selenium-router"
1818

1919
EXPOSE 4444

Video/Dockerfile

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ COPY --from=source /usr/local/bin/rclone /usr/local/bin/rclone
1717

1818
RUN apt-get -qqy update \
1919
&& apt-get -qqy --no-install-recommends install \
20-
libx11-dev libxcb-shm0 libxcb1-dev \
20+
libx11-dev libxcb-shm0 libxcb1-dev libpulse-dev libasound2-dev \
2121
x11-xserver-utils x11-utils \
2222
python3-pip \
23+
&& apt-get -qqy update \
24+
&& apt-get -yq upgrade \
2325
&& pip install --upgrade --break-system-packages --no-cache-dir setuptools psutil \
2426
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*
2527

@@ -35,6 +37,8 @@ RUN ffmpeg -version \
3537
ENV DISPLAY_NUM="99" \
3638
DISPLAY_CONTAINER_NAME="selenium" \
3739
SE_RECORD_VIDEO="true" \
40+
SE_RECORD_AUDIO="false" \
41+
SE_AUDIO_SOURCE="-f pulse -ac 2 -i default" \
3842
SE_SERVER_PROTOCOL="http" \
3943
SE_VIDEO_POLL_INTERVAL="1" \
4044
SE_SCREEN_WIDTH="1920" \

Video/video.sh

+16-4
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,23 @@ function graceful_exit_force() {
204204
exit 0
205205
}
206206

207+
if [ "${SE_RECORD_AUDIO,,}" = "true" ]; then
208+
echo "$(date -u +"${ts_format}") [${process_name}] - Audio source arguments: ${SE_AUDIO_SOURCE}"
209+
else
210+
SE_AUDIO_SOURCE=""
211+
fi
212+
207213
if [[ "${VIDEO_UPLOAD_ENABLED}" != "true" ]] && [[ "${VIDEO_FILE_NAME}" != "auto" ]] && [[ -n "${VIDEO_FILE_NAME}" ]]; then
208214
trap graceful_exit SIGTERM SIGINT EXIT
209215
wait_for_display
210216
video_file="$VIDEO_FOLDER/$VIDEO_FILE_NAME"
211217
# exec replaces the video.sh process with ffmpeg, this makes easier to pass the process termination signal
212218
ffmpeg -hide_banner -loglevel warning -flags low_delay -threads 2 -fflags nobuffer+genpts -strict experimental -y -f x11grab \
213-
-video_size ${VIDEO_SIZE} -r ${FRAME_RATE} -i ${DISPLAY} -codec:v ${CODEC} ${PRESET} -pix_fmt yuv420p "$video_file" &
214-
wait $!
219+
-video_size ${VIDEO_SIZE} -r ${FRAME_RATE} -i ${DISPLAY} ${SE_AUDIO_SOURCE} -codec:v ${CODEC} ${PRESET} -pix_fmt yuv420p "$video_file" &
220+
FFMPEG_PID=$!
221+
if ps -p $FFMPEG_PID >/dev/null; then
222+
wait $FFMPEG_PID
223+
fi
215224
wait_for_file_integrity
216225

217226
else
@@ -243,8 +252,11 @@ else
243252
video_file="${VIDEO_FOLDER}/$video_file_name"
244253
echo "$(date -u +"${ts_format}") [${process_name}] - Starting to record video"
245254
ffmpeg -hide_banner -loglevel warning -flags low_delay -threads 2 -fflags nobuffer+genpts -strict experimental -y -f x11grab \
246-
-video_size ${VIDEO_SIZE} -r ${FRAME_RATE} -i ${DISPLAY} -codec:v ${CODEC} ${PRESET} -pix_fmt yuv420p "$video_file" &
247-
recording_started="true"
255+
-video_size ${VIDEO_SIZE} -r ${FRAME_RATE} -i ${DISPLAY} ${SE_AUDIO_SOURCE} -codec:v ${CODEC} ${PRESET} -pix_fmt yuv420p "$video_file" &
256+
FFMPEG_PID=$!
257+
if ps -p $FFMPEG_PID >/dev/null; then
258+
recording_started="true"
259+
fi
248260
echo "$(date -u +"${ts_format}") [${process_name}] - Video recording started"
249261
sleep ${poll_interval}
250262
elif [[ "$session_id" != "$prev_session_id" && "$recording_started" = "true" ]]; then

scripts/generate_list_env_vars/description.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,9 @@
360360
- name: SE_SUPERVISORD_START_RETRIES
361361
description: ''
362362
cli: ''
363+
- name: SE_RECORD_AUDIO
364+
description: Flag to enable recording the audio source (default is Pulse Audio input)
365+
cli: ''
366+
- name: SE_AUDIO_SOURCE
367+
description: FFmpeg arguments to record the audio source
368+
cli: ''

scripts/generate_list_env_vars/extract_env.py

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
def extract_variables_from_shell_scripts(directory_path):
77
variables = OrderedDict()
88
for root, _, files in os.walk(directory_path):
9+
files.sort()
910
for file in files:
1011
if file.endswith(".sh"):
1112
file_path = os.path.join(root, file)
@@ -23,6 +24,7 @@ def extract_variables_from_shell_scripts(directory_path):
2324
def extract_variables_from_dockerfiles(directory_path):
2425
variables = OrderedDict()
2526
for root, _, files in os.walk(directory_path):
27+
files.sort()
2628
for file in files:
2729
if file.startswith("Dockerfile"):
2830
file_path = os.path.join(root, file)
@@ -40,6 +42,7 @@ def extract_variables_from_dockerfiles(directory_path):
4042
def combine_dictionaries(dict1, dict2):
4143
combined_dict = OrderedDict(dict1)
4244
combined_dict.update(dict2)
45+
combined_dict = dict(sorted(combined_dict.items()))
4346
return combined_dict
4447

4548
def read_description_yaml(file_path):

0 commit comments

Comments
 (0)