1{ pkgs, lib, ... }:
2
3let
4 rtmpUrl = "rtmp://localhost:1935/test";
5in
6{
7 name = "mediamtx";
8 meta.maintainers = with lib.maintainers; [ fpletz ];
9
10 nodes = {
11 machine = {
12 services.mediamtx = {
13 enable = true;
14 settings = {
15 metrics = true;
16 paths.all.source = "publisher";
17 };
18 };
19
20 systemd.services.rtmp-publish = {
21 description = "Publish an RTMP stream to mediamtx";
22 after = [ "mediamtx.service" ];
23 bindsTo = [ "mediamtx.service" ];
24 wantedBy = [ "multi-user.target" ];
25 serviceConfig = {
26 DynamicUser = true;
27 Restart = "on-failure";
28 RestartSec = "1s";
29 TimeoutStartSec = "30s";
30 ExecStart = "${lib.getBin pkgs.ffmpeg-headless}/bin/ffmpeg -re -f lavfi -i smptebars=size=800x600:rate=10 -c libx264 -f flv ${rtmpUrl}";
31 };
32 };
33
34 systemd.services.rtmp-receive = {
35 description = "Receive an RTMP stream from mediamtx";
36 after = [ "rtmp-publish.service" ];
37 bindsTo = [ "rtmp-publish.service" ];
38 wantedBy = [ "multi-user.target" ];
39 unitConfig.StartLimitIntervalSec = 0;
40 serviceConfig = {
41 DynamicUser = true;
42 Restart = "on-failure";
43 RestartSec = "1s";
44 TimeoutStartSec = "30s";
45 ExecStart = "${lib.getBin pkgs.ffmpeg-headless}/bin/ffmpeg -y -re -i ${rtmpUrl} -f flv /dev/null";
46 };
47 };
48 };
49 };
50
51 testScript = ''
52 start_all()
53
54 machine.wait_for_unit("mediamtx.service")
55
56 machine.wait_for_unit("rtmp-publish.service")
57 machine.wait_until_succeeds("curl http://localhost:9998/metrics | grep '^rtmp_conns.*state=\"publish\".*1$'")
58
59 machine.wait_for_unit("rtmp-receive.service")
60 machine.wait_until_succeeds("curl http://localhost:9998/metrics | grep '^rtmp_conns.*state=\"read\".*1$'")
61 '';
62}