diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index c006ba94..cf7078bc 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -63,8 +63,8 @@ body:
label: MediaMTX configuration
description: |
MediaMTX configuration is often required to replicate the issue.
- placeholder: Paste or drag the configuration file here
- # render: shell
+ placeholder: Paste the configuration file here
+ render: yaml
- type: textarea
id: logs
@@ -73,7 +73,6 @@ body:
description: |
MediaMTX logs are often useful to identify the issue. If you think this is the case, set the parameter 'logLevel' to 'debug' and attach logs.
placeholder: Paste or drag the log file here
- # render: shell
- type: textarea
id: network
diff --git a/.github/workflows/code_lint.yml b/.github/workflows/code_lint.yml
index 9d50b91d..63144a0c 100644
--- a/.github/workflows/code_lint.yml
+++ b/.github/workflows/code_lint.yml
@@ -23,7 +23,7 @@ jobs:
- uses: golangci/golangci-lint-action@v9
with:
- version: v2.6.1
+ version: v2.8.0
go_mod:
runs-on: ubuntu-22.04
diff --git a/.github/workflows/nightly_binaries.yml b/.github/workflows/nightly_binaries.yml
index 049e3b17..e70c8f88 100644
--- a/.github/workflows/nightly_binaries.yml
+++ b/.github/workflows/nightly_binaries.yml
@@ -14,7 +14,7 @@ jobs:
- run: make binaries
- - uses: actions/upload-artifact@v5
+ - uses: actions/upload-artifact@v6
with:
name: binaries
path: binaries
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f11377c9..b3912e45 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -28,7 +28,7 @@ jobs:
with:
subject-path: '${{ github.workspace }}/binaries/*'
- - uses: actions/upload-artifact@v5
+ - uses: actions/upload-artifact@v6
with:
name: binaries
path: binaries
@@ -38,7 +38,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- - uses: actions/download-artifact@v6
+ - uses: actions/download-artifact@v7
with:
name: binaries
path: binaries
@@ -62,7 +62,7 @@ jobs:
+ `\n`
+ `## Security\n`
+ `\n`
- + `Binaries are compiled from source through the [Release workflow](https://github.com/${owner}/${repo}/actions/workflows/release.yml) without human intervention,`
+ + `Binaries are compiled from source through the [Release workflow](https://github.com/${owner}/${repo}/actions/workflows/release.yml?query=branch%3Amain) without human intervention,`
+ ` preventing any external interference.\n`
+ `\n`
+ 'You can verify that binaries have been produced by the workflow by using [GitHub Attestations](https://docs.github.com/en/actions/concepts/security/artifact-attestations):\n'
@@ -151,7 +151,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- - uses: actions/download-artifact@v6
+ - uses: actions/download-artifact@v7
with:
name: binaries
path: binaries
diff --git a/Makefile b/Makefile
index 5553d83a..dcc97cd0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
BASE_IMAGE = golang:1.25-alpine3.22
-GOLANGCI_LINT_IMAGE = golangci/golangci-lint:v2.7.1
+GOLANGCI_LINT_IMAGE = golangci/golangci-lint:v2.8.0
NODE_IMAGE = node:20-alpine3.22
.PHONY: $(shell ls)
diff --git a/README.md b/README.md
index e7ae3141..85010774 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@
[](https://mediamtx.org)
- [](https://github.com/bluenviron/mediamtx/actions/workflows/code_test.yml)
- [](https://github.com/bluenviron/mediamtx/actions/workflows/code_lint.yml)
+ [](https://github.com/bluenviron/mediamtx/actions/workflows/code_test.yml?query=branch%3Amain)
+ [](https://github.com/bluenviron/mediamtx/actions/workflows/code_lint.yml?query=branch%3Amain)
[](https://app.codecov.io/gh/bluenviron/mediamtx/tree/main)
[](https://github.com/bluenviron/mediamtx/releases)
[](https://hub.docker.com/r/bluenviron/mediamtx)
diff --git a/api/openapi.yaml b/api/openapi.yaml
index 19835de9..18c46f1b 100644
--- a/api/openapi.yaml
+++ b/api/openapi.yaml
@@ -73,6 +73,8 @@ components:
type: array
items:
type: string
+ logStructured:
+ type: boolean
logFile:
type: string
sysLogPrefix:
diff --git a/docker/ffmpeg-rpi.Dockerfile b/docker/ffmpeg-rpi.Dockerfile
index b5619507..14d19966 100644
--- a/docker/ffmpeg-rpi.Dockerfile
+++ b/docker/ffmpeg-rpi.Dockerfile
@@ -6,15 +6,37 @@ ADD binaries/mediamtx_*_linux_armv7.tar.gz /linux/arm/v7
ADD binaries/mediamtx_*_linux_arm64.tar.gz /linux/arm64
#################################################################
+FROM --platform=linux/arm/v7 debian:bullseye-slim AS base-arm-v7
-FROM --platform=linux/arm/v6 balenalib/raspberry-pi:bullseye-run-20240508 AS base-arm-v6
-FROM --platform=linux/arm/v7 balenalib/raspberry-pi:bullseye-run-20240508 AS base-arm-v7
-FROM --platform=linux/arm64 balenalib/raspberrypi3-64:bullseye-run-20240429 AS base-arm64
+# even though the base image is arm v7,
+# Raspbian libraries and compilers provide arm v6 compatibility.
+
+RUN apt update \
+ && apt install -y wget gpg \
+ && echo "deb http://archive.raspbian.org/raspbian bullseye main rpi firmware" > /etc/apt/sources.list \
+ && echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
+ && wget -O- https://archive.raspbian.org/raspbian.public.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspbian.gpg \
+ && wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN apt update && apt install --reinstall -y \
+ libc6 \
+ libstdc++6 \
+ && rm -rf /var/lib/apt/lists/*
+
+#################################################################
+FROM --platform=linux/arm64 debian:bullseye-slim AS base-arm64
+
+RUN apt update \
+ && apt install -y wget gpg \
+ && echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
+ && wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
+ && rm -rf /var/lib/apt/lists/*
#################################################################
FROM --platform=linux/amd64 scratch AS base
-COPY --from=base-arm-v6 / /linux/arm/v6
+COPY --from=base-arm-v7 / /linux/arm/v6
COPY --from=base-arm-v7 / /linux/arm/v7
COPY --from=base-arm64 / /linux/arm64
diff --git a/docker/rpi.Dockerfile b/docker/rpi.Dockerfile
index 16c3736f..6f860fe0 100644
--- a/docker/rpi.Dockerfile
+++ b/docker/rpi.Dockerfile
@@ -6,15 +6,37 @@ ADD binaries/mediamtx_*_linux_armv7.tar.gz /linux/arm/v7
ADD binaries/mediamtx_*_linux_arm64.tar.gz /linux/arm64
#################################################################
+FROM --platform=linux/arm/v7 debian:bullseye-slim AS base-arm-v7
-FROM --platform=linux/arm/v6 balenalib/raspberry-pi:bullseye-run-20240508 AS base-arm-v6
-FROM --platform=linux/arm/v7 balenalib/raspberry-pi:bullseye-run-20240508 AS base-arm-v7
-FROM --platform=linux/arm64 balenalib/raspberrypi3-64:bullseye-run-20240429 AS base-arm64
+# even though the base image is arm v7,
+# Raspbian libraries and compilers provide arm v6 compatibility.
+
+RUN apt update \
+ && apt install -y wget gpg \
+ && echo "deb http://archive.raspbian.org/raspbian bullseye main rpi firmware" > /etc/apt/sources.list \
+ && echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
+ && wget -O- https://archive.raspbian.org/raspbian.public.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspbian.gpg \
+ && wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN apt update && apt install --reinstall -y \
+ libc6 \
+ libstdc++6 \
+ && rm -rf /var/lib/apt/lists/*
+
+#################################################################
+FROM --platform=linux/arm64 debian:bullseye-slim AS base-arm64
+
+RUN apt update \
+ && apt install -y wget gpg \
+ && echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
+ && wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
+ && rm -rf /var/lib/apt/lists/*
#################################################################
FROM --platform=linux/amd64 scratch AS base
-COPY --from=base-arm-v6 / /linux/arm/v6
+COPY --from=base-arm-v7 / /linux/arm/v6
COPY --from=base-arm-v7 / /linux/arm/v7
COPY --from=base-arm64 / /linux/arm64
diff --git a/docs/1-kickoff/1-introduction.md b/docs/1-kickoff/1-introduction.md
index 5b610f8d..623ff2c7 100644
--- a/docs/1-kickoff/1-introduction.md
+++ b/docs/1-kickoff/1-introduction.md
@@ -2,7 +2,7 @@
Welcome to the MediaMTX documentation!
-MediaMTX is a ready-to-use and zero-dependency live media server and media proxy. It has been conceived as a "media router" that routes media streams from one end to the other.
+_MediaMTX_ is a ready-to-use and zero-dependency live media server and media proxy. It has been conceived as a "media router" that routes media streams from one end to the other.
Main features:
diff --git a/docs/1-kickoff/2-install.md b/docs/1-kickoff/2-install.md
index 0e0bc48c..b13618ba 100644
--- a/docs/1-kickoff/2-install.md
+++ b/docs/1-kickoff/2-install.md
@@ -6,7 +6,7 @@ There are several installation methods available: standalone binary, Docker imag
1. Visit the [Releases page](https://github.com/bluenviron/mediamtx/releases) on GitHub, download and extract a standalone binary that corresponds to your operating system and architecture (example: `mediamtx_{version_tag}_linux_amd64.tar.gz`).
-2. Start the server:
+2. Start the server by double clicking on `mediamtx` (`mediamtx.exe` on Windows) or writing in the terminal:
```sh
./mediamtx
diff --git a/docs/1-kickoff/3-upgrade.md b/docs/1-kickoff/3-upgrade.md
index 092e421e..73eeaa66 100644
--- a/docs/1-kickoff/3-upgrade.md
+++ b/docs/1-kickoff/3-upgrade.md
@@ -1,6 +1,6 @@
# Upgrade
-If you have an existing MediaMTX installation, you can upgrade it to the latest version. The procedure depends on how MediaMTX was installed.
+If you have an existing _MediaMTX_ installation, you can upgrade it to the latest version. The procedure depends on how _MediaMTX_ was installed.
## Standalone binary
@@ -10,7 +10,7 @@ The standalone binary comes with a upgrade utility that can be launched with:
./mediamtx --upgrade
```
-This will replace the MediaMTX executable with its latest version. Privileges to write to the executable location are required.
+This will replace the _MediaMTX_ executable with its latest version. Privileges to write to the executable location are required.
## Docker image
diff --git a/docs/2-usage/01-basic-usage.md b/docs/2-usage/01-basic-usage.md
index c3bb156a..dd064520 100644
--- a/docs/2-usage/01-basic-usage.md
+++ b/docs/2-usage/01-basic-usage.md
@@ -13,7 +13,7 @@
! qtdemux name=d d.video_0 ! queue ! s.sink_0 d.audio_0 ! queue ! s.sink_1
```
-2. Open the stream. For instance, you can open the stream with _VLC_:
+2. Read the stream. For instance, you can read the stream with _VLC_:
```sh
vlc --network-caching=50 rtsp://localhost:8554/mystream
diff --git a/docs/2-usage/02-publish.md b/docs/2-usage/02-publish.md
index af9ea177..131af1f4 100644
--- a/docs/2-usage/02-publish.md
+++ b/docs/2-usage/02-publish.md
@@ -94,7 +94,7 @@ paths:
source: wheps://host:port/path
```
-If the remote server is a MediaMTX instance, remember to add a `/whep` suffix after the stream name, since in MediaMTX [it's part of the WHEP URL](read#webrtc):
+If the remote server is a _MediaMTX_ instance, remember to add a `/whep` suffix after the stream name, since in _MediaMTX_ [it's part of the WHEP URL](read#webrtc):
```yml
paths:
@@ -287,6 +287,7 @@ paths:
_MediaMTX_ natively supports most of the Raspberry Pi Camera models, enabling high-quality and low-latency video streaming from the camera to any user, for any purpose. There are some additional requirements:
1. The server must run on a Raspberry Pi, with one of the following operating systems:
+ - Raspberry Pi OS Trixie
- Raspberry Pi OS Bookworm
- Raspberry Pi OS Bullseye
@@ -452,7 +453,7 @@ ffmpeg -re -stream_loop -1 -i file.ts -c copy -f flv rtmp://localhost:1935/mystr
#### FFmpeg and MPEG-TS over UDP
-In MediaMTX configuration, add a path with `source: udp+mpegts://238.0.0.1:1234`. Then:
+In _MediaMTX_ configuration, add a path with `source: udp+mpegts://238.0.0.1:1234`. Then:
```sh
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f mpegts 'udp://127.0.0.1:3356?pkt_size=1316'
@@ -468,7 +469,7 @@ ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
#### FFmpeg and RTP over UDP
-In MediaMTX configuration, add a path with `source: udp+rtp://238.0.0.1:1234` and a valid `rtpSDP` (see [RTP](#rtp)). Then:
+In _MediaMTX_ configuration, add a path with `source: udp+rtp://238.0.0.1:1234` and a valid `rtpSDP` (see [RTP](#rtp)). Then:
```sh
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
diff --git a/docs/2-usage/04-configuration.md b/docs/2-usage/04-configuration.md
index 083ac566..f9c104e0 100644
--- a/docs/2-usage/04-configuration.md
+++ b/docs/2-usage/04-configuration.md
@@ -2,6 +2,8 @@
All the configuration parameters are listed and commented in the [configuration file](/docs/references/configuration-file) (`mediamtx.yml`).
+## Change the configuration
+
There are several ways to change the configuration:
1. By editing the configuration file, that is
@@ -46,3 +48,13 @@ There are several ways to change the configuration:
```
3. By using the [Control API](control-api).
+
+## Encrypt the configuration
+
+The configuration file can be entirely encrypted for security purposes by using the `crypto_secretbox` function of the NaCL function. An online tool for performing this operation is [available here](https://play.golang.org/p/rX29jwObNe4).
+
+After performing the encryption, put the base64-encoded result into the configuration file, and launch the server with the `MTX_CONFKEY` variable:
+
+```
+MTX_CONFKEY=mykey ./mediamtx
+```
diff --git a/docs/2-usage/05-authentication.md b/docs/2-usage/05-authentication.md
index 2beac485..d9d860b8 100644
--- a/docs/2-usage/05-authentication.md
+++ b/docs/2-usage/05-authentication.md
@@ -2,7 +2,7 @@
## Overview
-MediaMTX can be configured to ask clients for credentials, either in the form of username/password or a string-based token. These credentials are then validated through a chosen method.
+_MediaMTX_ can be configured to ask clients for credentials, either in the form of username/password or a string-based token. These credentials are then validated through a chosen method.
## Credential validation
@@ -306,6 +306,6 @@ Authorization: Bearer MY_JWT
In OBS Studio, this is the "Bearer Token" field.
-If the `Authorization: Bearer` token cannot be directly provided (for instance, with web browsers that directly access MediaMTX and show a credential dialog), you can pass the token as password, using an arbitrary user.
+If the `Authorization: Bearer` token cannot be directly provided (for instance, with web browsers that directly access _MediaMTX_ and show a credential dialog), you can pass the token as password, using an arbitrary user.
In web browsers, if you need to automatically fill credentials from a parent web page, see [Embed streams in a website](embed-streams-in-a-website).
diff --git a/docs/2-usage/06-encrypt-the-configuration.md b/docs/2-usage/06-encrypt-the-configuration.md
deleted file mode 100644
index 6be4e630..00000000
--- a/docs/2-usage/06-encrypt-the-configuration.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Encrypt the configuration
-
-The configuration file can be entirely encrypted for security purposes by using the `crypto_secretbox` function of the NaCL function. An online tool for performing this operation is [available here](https://play.golang.org/p/rX29jwObNe4).
-
-After performing the encryption, put the base64-encoded result into the configuration file, and launch the server with the `MTX_CONFKEY` variable:
-
-```
-MTX_CONFKEY=mykey ./mediamtx
-```
diff --git a/docs/2-usage/07-remuxing-reencoding-compression.md b/docs/2-usage/06-remuxing-reencoding-compression.md
similarity index 100%
rename from docs/2-usage/07-remuxing-reencoding-compression.md
rename to docs/2-usage/06-remuxing-reencoding-compression.md
diff --git a/docs/2-usage/08-record.md b/docs/2-usage/07-record.md
similarity index 100%
rename from docs/2-usage/08-record.md
rename to docs/2-usage/07-record.md
diff --git a/docs/2-usage/09-playback.md b/docs/2-usage/08-playback.md
similarity index 100%
rename from docs/2-usage/09-playback.md
rename to docs/2-usage/08-playback.md
diff --git a/docs/2-usage/10-forward.md b/docs/2-usage/09-forward.md
similarity index 100%
rename from docs/2-usage/10-forward.md
rename to docs/2-usage/09-forward.md
diff --git a/docs/2-usage/11-proxy.md b/docs/2-usage/10-proxy.md
similarity index 100%
rename from docs/2-usage/11-proxy.md
rename to docs/2-usage/10-proxy.md
diff --git a/docs/2-usage/12-extract-snapshots.md b/docs/2-usage/11-extract-snapshots.md
similarity index 100%
rename from docs/2-usage/12-extract-snapshots.md
rename to docs/2-usage/11-extract-snapshots.md
diff --git a/docs/2-usage/13-on-demand-publishing.md b/docs/2-usage/12-on-demand-publishing.md
similarity index 100%
rename from docs/2-usage/13-on-demand-publishing.md
rename to docs/2-usage/12-on-demand-publishing.md
diff --git a/docs/2-usage/14-route-absolute-timestamps.md b/docs/2-usage/13-route-absolute-timestamps.md
similarity index 100%
rename from docs/2-usage/14-route-absolute-timestamps.md
rename to docs/2-usage/13-route-absolute-timestamps.md
diff --git a/docs/2-usage/15-expose-the-server-in-a-subfolder.md b/docs/2-usage/14-expose-the-server-in-a-subfolder.md
similarity index 93%
rename from docs/2-usage/15-expose-the-server-in-a-subfolder.md
rename to docs/2-usage/14-expose-the-server-in-a-subfolder.md
index f8d5ad4e..06ceb8d1 100644
--- a/docs/2-usage/15-expose-the-server-in-a-subfolder.md
+++ b/docs/2-usage/14-expose-the-server-in-a-subfolder.md
@@ -1,6 +1,6 @@
# Expose the server in a subfolder
-HTTP-based services (WebRTC, HLS, Control API, Playback Server, Metrics, pprof) can be exposed in a subfolder of an existing HTTP server or reverse proxy. The reverse proxy must be able to intercept HTTP requests addressed to MediaMTX and corresponding responses, and perform the following changes:
+HTTP-based services (WebRTC, HLS, Control API, Playback Server, Metrics, pprof) can be exposed in a subfolder of an existing HTTP server or reverse proxy. The reverse proxy must be able to intercept HTTP requests addressed to _MediaMTX_ and corresponding responses, and perform the following changes:
- The subfolder path must be stripped from request paths. For instance, if the server is exposed behind `/subpath` and the reverse proxy receives a request with path `/subpath/mystream/index.m3u8`, this has to be changed into `/mystream/index.m3u8`.
diff --git a/docs/2-usage/16-embed-streams-in-a-website.md b/docs/2-usage/15-embed-streams-in-a-website.md
similarity index 97%
rename from docs/2-usage/16-embed-streams-in-a-website.md
rename to docs/2-usage/15-embed-streams-in-a-website.md
index 58517eb5..c8ee2656 100644
--- a/docs/2-usage/16-embed-streams-in-a-website.md
+++ b/docs/2-usage/15-embed-streams-in-a-website.md
@@ -20,7 +20,7 @@ The iframe can be controlled by adding query parameters to the URL (example: `ht
The iframe method is fit for most use cases, but it has some limitations:
-- it doesn't allow to pass credentials (username, password or token) from the website to MediaMTX; credentials are asked directly to users.
+- it doesn't allow to pass credentials (username, password or token) from the website to _MediaMTX_; credentials are asked directly to users.
- it doesn't allow to directly access the video tag, to extract data from it, or to perform dynamic actions.
In order to overcome these limitations, it is possible to load the stream directly inside a `