summaryrefslogtreecommitdiff
path: root/roles/streaming/streamer/rtmp
diff options
context:
space:
mode:
Diffstat (limited to 'roles/streaming/streamer/rtmp')
-rw-r--r--roles/streaming/streamer/rtmp/defaults/main.yml30
-rw-r--r--roles/streaming/streamer/rtmp/tasks/main.yml45
-rw-r--r--roles/streaming/streamer/rtmp/templates/nginx.conf.j232
-rw-r--r--roles/streaming/streamer/rtmp/templates/pod-spec.yml.j2143
4 files changed, 250 insertions, 0 deletions
diff --git a/roles/streaming/streamer/rtmp/defaults/main.yml b/roles/streaming/streamer/rtmp/defaults/main.yml
new file mode 100644
index 00000000..82b16b67
--- /dev/null
+++ b/roles/streaming/streamer/rtmp/defaults/main.yml
@@ -0,0 +1,30 @@
+---
+# streamer_rtmp_storage:
+# type: (lvm|zfs)
+# ...
+streamer_rtmp_base_path: /srv/streamer/rtmp
+
+streamer_rtmp_port: 1935
+# streamer_rtmp_inst_name: feed
+# streamer_rtmp_nginx_image_version: 2022-05-15.24
+# streamer_rtmp_ffmpeg_image_version: bullseye-decklink11.7-2022-05-28.17
+# streamer_rtmp_input: ['-f', 'decklink', '-video_input', 'sdi', '-format_code', 'Hp25', '-ac', '2', '-i', 'DeckLink Mini Recorder']
+# streamer_rtmp_video_filter_common: "colorspace=iall=bt709:irange=tv:all=bt709:range=tv:format=yuv420p,setdar=dar=16/9"
+streamer_rtmp_app_name: "{{ streamer_rtmp_inst_name }}"
+streamer_rtmp_audio_track: orig
+streamer_rtmp_quality_levels:
+ - full
+
+streamer_rtmp_config: {}
+
+
+streamer_rtmp_forwards: {}
+# example:
+# url: rtmp://ingest.example.com/foo/secret
+# level: full
+
+
+# streamer_rtmp_recording:
+# level: full
+# segment_time: 7200
+# segment_clocktime_offset: 0
diff --git a/roles/streaming/streamer/rtmp/tasks/main.yml b/roles/streaming/streamer/rtmp/tasks/main.yml
new file mode 100644
index 00000000..9259fbd4
--- /dev/null
+++ b/roles/streaming/streamer/rtmp/tasks/main.yml
@@ -0,0 +1,45 @@
+---
+- name: prepare rtmp-streamer storage volume
+ when: streamer_rtmp_storage is defined
+ vars:
+ storage_volume: "{{ streamer_rtmp_storage | combine({'dest': streamer_rtmp_base_path}) }}"
+ include_role:
+ name: "storage/{{ streamer_rtmp_storage.type }}/volume"
+
+- name: create rtmp-streamer instance directory
+ file:
+ path: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}"
+ state: directory
+
+- name: generate nginx config
+ template:
+ src: nginx.conf.j2
+ dest: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}/nginx.conf"
+
+- name: generate streamer config
+ copy:
+ content: "{{ streamer_rtmp_config | combine({'rtmp': {'base_url': 'rtmp://127.0.0.1/'+streamer_rtmp_app_name}}) | to_nice_yaml }}\n"
+ dest: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}/config.yml"
+
+- name: create recording directory
+ when: streamer_rtmp_recording is defined
+ file:
+ path: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}/recordings"
+ state: directory
+ owner: app
+ group: app
+
+- name: install pod manifest
+ vars:
+ kubernetes_standalone_pod:
+ name: "rtmp-streamer-{{ streamer_rtmp_inst_name }}"
+ spec: "{{ lookup('template', 'pod-spec.yml.j2') }}"
+ config_hash_items:
+ - path: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}/nginx.conf"
+ properties:
+ - checksum
+ - path: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}/config.yml"
+ properties:
+ - checksum
+ include_role:
+ name: kubernetes/standalone/pod
diff --git a/roles/streaming/streamer/rtmp/templates/nginx.conf.j2 b/roles/streaming/streamer/rtmp/templates/nginx.conf.j2
new file mode 100644
index 00000000..37e7aa84
--- /dev/null
+++ b/roles/streaming/streamer/rtmp/templates/nginx.conf.j2
@@ -0,0 +1,32 @@
+worker_processes 1;
+pid /var/lib/nginx/nginx.pid;
+error_log /dev/stderr info;
+
+include /etc/nginx/modules-enabled/*.conf;
+
+events {
+ worker_connections 768;
+ # multi_accept on;
+}
+
+rtmp {
+ access_log /dev/null;
+
+ server {
+ listen 1935;
+
+ ping 10s;
+ ping_timeout 3s;
+ drop_idle_publisher 10s;
+ idle_streams off;
+ max_message 4M;
+
+ application {{ streamer_rtmp_app_name }} {
+ live on;
+ meta copy;
+
+ allow publish 127.0.0.1;
+ deny publish all;
+ }
+ }
+}
diff --git a/roles/streaming/streamer/rtmp/templates/pod-spec.yml.j2 b/roles/streaming/streamer/rtmp/templates/pod-spec.yml.j2
new file mode 100644
index 00000000..301b4f33
--- /dev/null
+++ b/roles/streaming/streamer/rtmp/templates/pod-spec.yml.j2
@@ -0,0 +1,143 @@
+containers:
+- name: nginx
+ image: registry.gitlab.com/spreadspace/docker/nginx:{{ streamer_rtmp_nginx_image_version }}
+ imagePullPolicy: Always
+ command:
+ - nginx
+ args:
+ - -c
+ - /srv/nginx.conf
+ - -g
+ - "daemon off;"
+ ports:
+ - containerPort: 1935
+ hostPort: {{ streamer_rtmp_port }}
+ volumeMounts:
+ - name: home
+ mountPath: /srv
+ readOnly: true
+ - name: nginx-lib
+ mountPath: /var/lib/nginx
+
+- name: source
+ image: registry.gitlab.com/spreadspace/docker/ffmpeg:{{ streamer_rtmp_ffmpeg_image_version }}
+ imagePullPolicy: Always
+ command:
+ - /usr/local/bin/generic-rtmp.py
+ args:
+{% for param in streamer_rtmp_input %}
+ - '{{ param }}'
+{% endfor %}
+ env:
+ - name: CONFIG_FILENAME
+ value: /srv/config.yml
+ - name: QUALITY_LEVELS
+ value: {{ streamer_rtmp_quality_levels | join(',') }}
+ - name: AUDIO_TRACKS
+ value: {{ streamer_rtmp_audio_track }}
+{% if streamer_rtmp_video_filter_common is defined %}
+ - name: VIDEO_FILTER_COMMON
+ value: "{{ streamer_rtmp_video_filter_common }}"
+{% endif %}
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - name: home
+ mountPath: /srv
+ readOnly: true
+ - name: decklink-device
+ mountPath: /dev/blackmagic
+ - name: decklink-libs
+ subPath: libDeckLinkAPI.so
+ mountPath: /usr/lib/libDeckLinkAPI.so
+ readOnly: true
+ - name: decklink-libs
+ subPath: libDeckLinkPreviewAPI.so
+ mountPath: /usr/lib/libDeckLinkPreviewAPI.so
+ readOnly: true
+ - name: decklink-libs
+ subPath: blackmagic
+ mountPath: /usr/lib/blackmagic
+ readOnly: true
+
+{% for name, forward in streamer_rtmp_forwards.items() %}
+- name: "forward-{{ name }}"
+ image: registry.gitlab.com/spreadspace/docker/ffmpeg:{{ streamer_rtmp_ffmpeg_image_version }}
+ imagePullPolicy: Always
+ command:
+ - /usr/bin/ffmpeg
+ args:
+ - -f
+ - live_flv
+ - -rtmp_live
+ - live
+ - -i
+ - "rtmp://127.0.0.1/{{ streamer_rtmp_app_name }}/{{ forward.level }}"
+ - -c:a
+ - copy
+ - -c:v
+ - copy
+ - -f
+ - flv
+ - "{{ forward.url }}"
+
+{% endfor %}
+{% if streamer_rtmp_recording is defined %}
+- name: record
+ image: registry.gitlab.com/spreadspace/docker/ffmpeg:{{ streamer_rtmp_ffmpeg_image_version }}
+ imagePullPolicy: Always
+ command:
+ - /usr/bin/ffmpeg
+ args:
+ - -f
+ - live_flv
+ - -rtmp_live
+ - live
+ - -i
+ - 'rtmp://127.0.0.1/{{ streamer_rtmp_app_name }}/{{ streamer_rtmp_recording.level }}'
+ - -c:a
+ - copy
+ - -c:v
+ - copy
+ - -f
+ - segment
+ - -segment_atclocktime
+ - '1'
+ - -segment_time
+ - '{{ streamer_rtmp_recording.segment_time | default(3600) }}'
+ - -segment_clocktime_offset
+ - '{{ streamer_rtmp_recording.segment_clocktime_offset | default(0) }}'
+ - -strftime
+ - '1'
+ - -reset_timestamps
+ - '1'
+ - '%Y-%m-%d_%H-%M-%S.mkv'
+ workingDir: /srv/recordings
+ volumeMounts:
+ - name: home
+ mountPath: /srv
+ readOnly: true
+ - name: recordings
+ mountPath: /srv/recordings
+
+{% endif %}
+volumes:
+- name: home
+ hostPath:
+ path: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}"
+- name: nginx-lib
+ emptyDir:
+ medium: Memory
+- name: decklink-device
+ hostPath:
+ path: /dev/blackmagic
+- name: decklink-libs
+ hostPath:
+ type: Directory
+ path: /usr/lib/
+{% if streamer_rtmp_recording is defined %}
+- name: recordings
+ hostPath:
+ type: Directory
+ path: "{{ streamer_rtmp_base_path }}/{{ streamer_rtmp_inst_name }}/recordings"
+{% endif %}