From 34b366308e65e9c86b3a148798799f3845385f1a Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Wed, 27 Mar 2019 20:51:58 -0400 Subject: [PATCH 01/27] initial merge of nginx and ipfs server into one instance --- terraform/ipfs-server/bootstrap.sh | 105 ------------------ .../bootstrap-post-dns.sh | 0 terraform/rtmp-server/bootstrap.sh | 88 ++++++++++++++- .../{ipfs-server => rtmp-server}/ipfs.service | 0 .../nginx-default | 0 .../nginx-gateway | 0 terraform/rtmp-server/nginx.conf | 5 + .../process-stream.service | 0 .../process-stream.sh | 19 +--- 9 files changed, 94 insertions(+), 123 deletions(-) delete mode 100644 terraform/ipfs-server/bootstrap.sh rename terraform/{ipfs-server => rtmp-server}/bootstrap-post-dns.sh (100%) rename terraform/{ipfs-server => rtmp-server}/ipfs.service (100%) rename terraform/{ipfs-server => rtmp-server}/nginx-default (100%) rename terraform/{ipfs-server => rtmp-server}/nginx-gateway (100%) rename terraform/{ipfs-server => rtmp-server}/process-stream.service (100%) rename terraform/{ipfs-server => rtmp-server}/process-stream.sh (88%) diff --git a/terraform/ipfs-server/bootstrap.sh b/terraform/ipfs-server/bootstrap.sh deleted file mode 100644 index b0111e7..0000000 --- a/terraform/ipfs-server/bootstrap.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env bash - -set -e - -DOMAIN_NAME=$1 -EMAIL_ADDRESS=$2 -RTMP_SERVER_PRIVATE_IP=$3 -M3U8_HTTP_URLS=$4 - -IPFS_VERSION=0.4.15 - -# Wait for cloud-init to complete -until [[ -f /var/lib/cloud/instance/boot-finished ]]; do - sleep 1 -done - -# Prevent apt-daily from holding up /var/lib/dpkg/lock on boot -systemctl disable apt-daily.service -systemctl disable apt-daily.timer - -# Install Digital Ocean new metrics -curl -sSL https://agent.digitalocean.com/install.sh | sh - -# Install programs -apt update -apt install -y \ - bc \ - certbot \ - ffmpeg \ - inotify-tools \ - jq \ - lsof \ - nginx - -# Create directory for generating client keys -mkdir /root/client-keys - -######## -# IPFS # -######## - -# Install IPFS -cd /tmp -wget "https://dist.ipfs.io/go-ipfs/v${IPFS_VERSION}/go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" -tar xvfz "go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" -cp go-ipfs/ipfs /usr/local/bin -cd ~ - -# Configure IPFS -ipfs init -sed -i 's#"Gateway": "/ip4/127.0.0.1/tcp/8080#"Gateway": "/ip4/0.0.0.0/tcp/8080#' ~/.ipfs/config -cp -f /tmp/ipfs-server/ipfs.service /etc/systemd/system/ipfs.service -systemctl daemon-reload -systemctl enable ipfs -systemctl start ipfs - -# Wait for IPFS daemon to start -sleep 10 -until [[ `ipfs id >/dev/null 2>&1; echo $?` -eq 0 ]]; do - sleep 1 -done -sleep 10 - -# Write IPFS identity to client file -IPFS_ID=`ipfs id | jq .ID | sed 's/"//g'` -echo -n "$IPFS_ID" > ~/client-keys/ipfs_id - -# Publish message to IPNS -# Commented out because IPNS is not predictable and could stall the script -# echo "Serving m3u8 over IPNS is currently disabled" | ipfs add | awk '{print $2}' | ipfs name publish - -######################## -# Process video stream # -######################## - -# Install video stream processing script -cp -f /tmp/ipfs-server/process-stream.sh ~/process-stream.sh - -# Save settings to a file -echo "#!/bin/sh" > ~/settings -echo "export DOMAIN_NAME=\"${DOMAIN_NAME}\"" >> ~/settings -echo "export RTMP_SERVER_PRIVATE_IP=\"${RTMP_SERVER_PRIVATE_IP}\"" >> ~/settings -echo "export RTMP_STREAM=\"rtmp://${RTMP_SERVER_PRIVATE_IP}/live\"" >> ~/settings -echo "export IPFS_GATEWAY=\"https://ipfs-gateway.${DOMAIN_NAME}\"" >> ~/settings -chmod +x ~/settings - -# Install and start process-stream service -cp -f /tmp/ipfs-server/process-stream.service /etc/systemd/system/process-stream.service -systemctl daemon-reload -systemctl enable process-stream -systemctl start process-stream - -################ -# Video player # -################ - -# Install web video player -rm -rf /var/www/html/* -cp -r /tmp/video-player/* /var/www/html/ - -# Configure video player -sed -i "s#__IPFS_GATEWAY_SELF__#https://ipfs-gateway.${DOMAIN_NAME}#g" /var/www/html/js/common.js -sed -i "s#__IPFS_GATEWAY_ORIGIN__#https://ipfs-gateway.${DOMAIN_NAME}#g" /var/www/html/js/common.js -sed -i "s#__IPFS_ID_ORIGIN__#${IPFS_ID}#g" /var/www/html/js/common.js -sed -i "s#__M3U8_HTTP_URLS__#${M3U8_HTTP_URLS}#g" /var/www/html/js/common.js diff --git a/terraform/ipfs-server/bootstrap-post-dns.sh b/terraform/rtmp-server/bootstrap-post-dns.sh similarity index 100% rename from terraform/ipfs-server/bootstrap-post-dns.sh rename to terraform/rtmp-server/bootstrap-post-dns.sh diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 9234927..2c36290 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -2,9 +2,16 @@ set -e +DOMAIN_NAME=$1 +EMAIL_ADDRESS=$2 +RTMP_SERVER_PRIVATE_IP=$3 +M3U8_HTTP_URLS=$4 + YGGDRASIL_GO_VERSION=0.3.2 NGINX_VERSION=1.15.0 +IPFS_VERSION=0.4.15 + # Wait for cloud-init to complete until [[ -f /var/lib/cloud/instance/boot-finished ]]; do sleep 1 @@ -27,7 +34,16 @@ apt install -y \ libssl-dev \ zlibc \ zlib1g \ - zlib1g-dev + zlib1g-dev \ + bc \ + certbot \ + ffmpeg \ + inotify-tools \ + jq \ + lsof + +# Create directory for generating client keys +mkdir /root/client-keys # Install golang mkdir /tmp/golang @@ -195,3 +211,73 @@ sed -i "s/__PUBLISHER_IP_ADDRESS__/`cat ~/publisher.key | grep Address | awk '{p # Start nginx /usr/local/nginx/sbin/nginx + +######## +# IPFS # +######## + +# Install IPFS +cd /tmp +wget "https://dist.ipfs.io/go-ipfs/v${IPFS_VERSION}/go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" +tar xvfz "go-ipfs_v${IPFS_VERSION}_linux-amd64.tar.gz" +cp go-ipfs/ipfs /usr/local/bin +cd ~ + +# Configure IPFS +ipfs init +sed -i 's#"Gateway": "/ip4/127.0.0.1/tcp/8080#"Gateway": "/ip4/0.0.0.0/tcp/8080#' ~/.ipfs/config +cp -f /tmp/ipfs-server/ipfs.service /etc/systemd/system/ipfs.service +systemctl daemon-reload +systemctl enable ipfs +systemctl start ipfs + +# Wait for IPFS daemon to start +sleep 10 +until [[ `ipfs id >/dev/null 2>&1; echo $?` -eq 0 ]]; do + sleep 1 +done +sleep 10 + +# Write IPFS identity to client file +IPFS_ID=`ipfs id | jq .ID | sed 's/"//g'` +echo -n "$IPFS_ID" > ~/client-keys/ipfs_id + + +# Publish message to IPNS +# Commented out because IPNS is not predictable and could stall the script +# echo "Serving m3u8 over IPNS is currently disabled" | ipfs add | awk '{print $2}' | ipfs name publish + +######################## +# Process video stream # +######################## + +# Install video stream processing script +cp -f /tmp/ipfs-server/process-stream.sh ~/process-stream.sh + +# Save settings to a file +echo "#!/bin/sh" > ~/settings +echo "export DOMAIN_NAME=\"${DOMAIN_NAME}\"" >> ~/settings +echo "export RTMP_SERVER_PRIVATE_IP=\"${RTMP_SERVER_PRIVATE_IP}\"" >> ~/settings +echo "export RTMP_STREAM=\"/root/hls\"" >> ~/settings +echo "export IPFS_GATEWAY=\"https://ipfs-gateway.${DOMAIN_NAME}\"" >> ~/settings +chmod +x ~/settings + +# Install and start process-stream service +cp -f /tmp/ipfs-server/process-stream.service /etc/systemd/system/process-stream.service +systemctl daemon-reload +systemctl enable process-stream +systemctl start process-stream + +################ +# Video player # +################ + +# Install web video player +rm -rf /var/www/html/* +cp -r /tmp/video-player/* /var/www/html/ + +# Configure video player +sed -i "s#__IPFS_GATEWAY_SELF__#https://ipfs-gateway.${DOMAIN_NAME}#g" /var/www/html/js/common.js +sed -i "s#__IPFS_GATEWAY_ORIGIN__#https://ipfs-gateway.${DOMAIN_NAME}#g" /var/www/html/js/common.js +sed -i "s#__IPFS_ID_ORIGIN__#${IPFS_ID}#g" /var/www/html/js/common.js +sed -i "s#__M3U8_HTTP_URLS__#${M3U8_HTTP_URLS}#g" /var/www/html/js/common.js diff --git a/terraform/ipfs-server/ipfs.service b/terraform/rtmp-server/ipfs.service similarity index 100% rename from terraform/ipfs-server/ipfs.service rename to terraform/rtmp-server/ipfs.service diff --git a/terraform/ipfs-server/nginx-default b/terraform/rtmp-server/nginx-default similarity index 100% rename from terraform/ipfs-server/nginx-default rename to terraform/rtmp-server/nginx-default diff --git a/terraform/ipfs-server/nginx-gateway b/terraform/rtmp-server/nginx-gateway similarity index 100% rename from terraform/ipfs-server/nginx-gateway rename to terraform/rtmp-server/nginx-gateway diff --git a/terraform/rtmp-server/nginx.conf b/terraform/rtmp-server/nginx.conf index c0bb7fb..86b00c2 100644 --- a/terraform/rtmp-server/nginx.conf +++ b/terraform/rtmp-server/nginx.conf @@ -18,6 +18,11 @@ rtmp { deny publish all; drop_idle_publisher 10s; allow play all; + hls on; + hls_path /root/hls; + hls_sync 100ms; + hls_fragment 10s; + hls_playlist_length 60m; } } } \ No newline at end of file diff --git a/terraform/ipfs-server/process-stream.service b/terraform/rtmp-server/process-stream.service similarity index 100% rename from terraform/ipfs-server/process-stream.service rename to terraform/rtmp-server/process-stream.service diff --git a/terraform/ipfs-server/process-stream.sh b/terraform/rtmp-server/process-stream.sh similarity index 88% rename from terraform/ipfs-server/process-stream.sh rename to terraform/rtmp-server/process-stream.sh index 7b49ee3..edc115d 100644 --- a/terraform/ipfs-server/process-stream.sh +++ b/terraform/rtmp-server/process-stream.sh @@ -1,26 +1,11 @@ #!/bin/bash -HLS_TIME=15 -M3U8_SIZE=6 - # Load settings . ~/settings -function startFFmpeg() { - while true; do - mv /var/log/ffmpeg /var/log/ffmpeg.1 - echo 1 > ~/stream-reset - ffmpeg -nostats -re -i "${RTMP_STREAM}" -f mpegts -vcodec copy -hls_time ${HLS_TIME} -hls_list_size 10 -f hls ${what}.m3u8 > /var/log/ffmpeg 2>&1 - sleep 0.5 - done -} - # Create directory for HLS content -rm -rf ~/live -mkdir ~/live -cd ~/live - -what="$(date +%Y%m%d%H%M)-LIVE" +rm -rf ~/hls/* +cd ~/hls # Start ffmpeg in background startFFmpeg & From 2b444bf4b60d43169e4da137d2b58b7ac9dd0495 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 14:49:31 -0400 Subject: [PATCH 02/27] Corrected errors in tf --- terraform/Security | 1 + terraform/main.tf | 111 ++++------------------------- terraform/rtmp-server/bootstrap.sh | 7 +- 3 files changed, 17 insertions(+), 102 deletions(-) create mode 100644 terraform/Security diff --git a/terraform/Security b/terraform/Security new file mode 100644 index 0000000..545f9b8 --- /dev/null +++ b/terraform/Security @@ -0,0 +1 @@ +Add the SSH key to your Digital Ocean account under Settings diff --git a/terraform/main.tf b/terraform/main.tf index 8671a04..7a6a990 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -6,7 +6,7 @@ resource "digitalocean_tag" "ipfs-live-streaming" { # Domain name managed by Digital Ocean resource "digitalocean_domain" "ipfs-live-streaming" { name = "${file(var.domain_name)}" - ip_address = "${digitalocean_droplet.ipfs-server.ipv4_address}" + ip_address = "${digitalocean_droplet.rtmp-server.ipv4_address}" } # RTMP server Droplet @@ -30,6 +30,10 @@ resource "digitalocean_droplet" "rtmp-server" { source = "rtmp-server" destination = "/tmp" } + provisioner "file" { + source = "shared/video-player" + destination = "/tmp" + } provisioner "remote-exec" { inline = [ "chmod +x /tmp/rtmp-server/bootstrap.sh", @@ -80,94 +84,11 @@ resource "digitalocean_record" "publish-yggdrasil" { ttl = "600" } -# IPFS server Droplet -resource "digitalocean_droplet" "ipfs-server" { - depends_on = ["digitalocean_droplet.rtmp-server"] - image = "debian-9-x64" - name = "ipfs-server" - region = "tor1" - size = "s-2vcpu-2gb" - tags = ["${digitalocean_tag.ipfs-live-streaming.id}"] - private_networking = true - ipv6 = true - monitoring = true - ssh_keys = ["${file(var.ssh_fingerprint)}"] - connection { - user = "root" - type = "ssh" - private_key = "${file(var.pvt_key)}" - timeout = "2m" - } - provisioner "file" { - source = "shared/video-player" - destination = "/tmp" - } - provisioner "file" { - source = "ipfs-server" - destination = "/tmp" - } - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/ipfs-server/bootstrap.sh", - "chmod +x /tmp/ipfs-server/bootstrap-post-dns.sh", - "chmod +x /tmp/ipfs-server/process-stream.sh", - "/tmp/ipfs-server/bootstrap.sh ${file(var.domain_name)} ${file(var.email_address)} ${digitalocean_droplet.rtmp-server.ipv4_address_private} ${var.m3u8_http_urls}", - ] - } - provisioner "local-exec" { - command = "scp -B -o 'StrictHostKeyChecking no' -i ${var.pvt_key} root@${digitalocean_droplet.ipfs-server.ipv4_address}:/root/client-keys/* .keys/" - } -} - -# DNS records for IPFS server -resource "digitalocean_record" "ipfs-server" { - domain = "${digitalocean_domain.ipfs-live-streaming.name}" - type = "A" - name = "ipfs-server" - value = "${digitalocean_droplet.ipfs-server.ipv4_address}" - ttl = "600" -} -resource "digitalocean_record" "ipfs-server-private" { - domain = "${digitalocean_domain.ipfs-live-streaming.name}" - type = "A" - name = "private.ipfs-server" - value = "${digitalocean_droplet.ipfs-server.ipv4_address_private}" - ttl = "600" -} -resource "digitalocean_record" "ipfs-server-v6" { - domain = "${digitalocean_domain.ipfs-live-streaming.name}" - type = "AAAA" - name = "v6.ipfs-server" - value = "${digitalocean_droplet.ipfs-server.ipv6_address}" - ttl = "600" -} -resource "digitalocean_record" "ipfs-server-gateway" { - domain = "${digitalocean_domain.ipfs-live-streaming.name}" - type = "A" - name = "ipfs-gateway" - value = "${digitalocean_droplet.ipfs-server.ipv4_address}" - ttl = "600" -} -resource "digitalocean_record" "ipfs-server-gateway-private" { - domain = "${digitalocean_domain.ipfs-live-streaming.name}" - type = "A" - name = "private.ipfs-gateway" - value = "${digitalocean_droplet.ipfs-server.ipv4_address_private}" - ttl = "600" -} -resource "digitalocean_record" "ipfs-server-gateway-v6" { - domain = "${digitalocean_domain.ipfs-live-streaming.name}" - type = "AAAA" - name = "v6.ipfs-gateway" - value = "${digitalocean_droplet.ipfs-server.ipv6_address}" - ttl = "600" -} - # Get HTTPS certificates after DNS records are configured for IPFS server -resource "null_resource" "ipfs-server" { - depends_on = ["digitalocean_record.ipfs-server"] +resource "null_resource" "rtmp-server" { + depends_on = ["digitalocean_record.rtmp-server"] connection { - host = "${digitalocean_droplet.ipfs-server.ipv4_address}" + host = "${digitalocean_droplet.rtmp-server.ipv4_address}" user = "root" type = "ssh" private_key = "${file(var.pvt_key)}" @@ -175,14 +96,14 @@ resource "null_resource" "ipfs-server" { } provisioner "remote-exec" { inline = [ - "/tmp/ipfs-server/bootstrap-post-dns.sh ${file(var.domain_name)} ${file(var.email_address)}", + "/tmp/rtmp-server/bootstrap-post-dns.sh ${file(var.domain_name)} ${file(var.email_address)}", ] } } # IPFS mirror Droplets resource "digitalocean_droplet" "ipfs-mirror" { - depends_on = ["digitalocean_droplet.ipfs-server"] + depends_on = ["digitalocean_droplet.rtmp-server"] count = "${var.mirror}" image = "debian-9-x64" name = "ipfs-mirror" @@ -291,7 +212,6 @@ output "digital_ocean_droplets" { depends_on = ["digitalocean_record.*"] value = [ "${digitalocean_droplet.rtmp-server.name}: ${digitalocean_droplet.rtmp-server.status}", - "${digitalocean_droplet.ipfs-server.name}: ${digitalocean_droplet.ipfs-server.status}", "ipfs-mirror instance(s): ${length(digitalocean_droplet.ipfs-mirror.*.status)}", "${digitalocean_droplet.ipfs-mirror.*.status}", ] @@ -301,18 +221,14 @@ output "dns_records" { value = [ " ${digitalocean_domain.ipfs-live-streaming.name} = ${digitalocean_domain.ipfs-live-streaming.ip_address}", " ${digitalocean_record.rtmp-server.fqdn} = ${digitalocean_record.rtmp-server.value}", - " ${digitalocean_record.ipfs-server.fqdn} = ${digitalocean_record.ipfs-server.value}", - " ${digitalocean_record.ipfs-server-gateway.fqdn} = ${digitalocean_record.ipfs-server-gateway.value}", + " ${digitalocean_record.rtmp-server.fqdn} = ${digitalocean_record.rtmp-server.value}", "${zipmap(digitalocean_record.ipfs-mirror.*.fqdn, digitalocean_record.ipfs-mirror.*.value)}", "${zipmap(digitalocean_record.ipfs-mirror-gateway.*.fqdn, digitalocean_record.ipfs-mirror-gateway.*.value)}", " ${digitalocean_record.rtmp-server-private.fqdn} = ${digitalocean_record.rtmp-server-private.value}", - " ${digitalocean_record.ipfs-server-private.fqdn} = ${digitalocean_record.ipfs-server-private.value}", - " ${digitalocean_record.ipfs-server-gateway-private.fqdn} = ${digitalocean_record.ipfs-server-gateway-private.value}", + " ${digitalocean_record.rtmp-server-private.fqdn} = ${digitalocean_record.rtmp-server-private.value}", "${zipmap(digitalocean_record.ipfs-mirror-private.*.fqdn, digitalocean_record.ipfs-mirror-private.*.value)}", "${zipmap(digitalocean_record.ipfs-mirror-gateway-private.*.fqdn, digitalocean_record.ipfs-mirror-gateway-private.*.value)}", " ${digitalocean_record.rtmp-server-v6.fqdn} = ${digitalocean_record.rtmp-server-v6.value}", - " ${digitalocean_record.ipfs-server-v6.fqdn} = ${digitalocean_record.ipfs-server-v6.value}", - " ${digitalocean_record.ipfs-server-gateway-v6.fqdn} = ${digitalocean_record.ipfs-server-gateway-v6.value}", "${zipmap(digitalocean_record.ipfs-mirror-v6.*.fqdn, digitalocean_record.ipfs-mirror-v6.*.value)}", "${zipmap(digitalocean_record.ipfs-mirror-gateway-v6.*.fqdn, digitalocean_record.ipfs-mirror-gateway-v6.*.value)}", " ${digitalocean_record.publish-openvpn.fqdn} = ${digitalocean_record.publish-openvpn.value}", @@ -323,7 +239,6 @@ output "ssh_access" { depends_on = ["digitalocean_record.*"] value = [ "rtmp-server: ssh -i .keys/id_rsa root@${digitalocean_record.rtmp-server.fqdn}", - "ipfs-server: ssh -i .keys/id_rsa root@${digitalocean_record.ipfs-server.fqdn}", "ipfs-mirror-N: ssh -i .keys/id_rsa root@ipfs-mirror-N.${digitalocean_domain.ipfs-live-streaming.name}", ] } @@ -346,4 +261,4 @@ output "public_urls" { "Video player (mirror-N): https://ipfs-mirror-N.${digitalocean_domain.ipfs-live-streaming.name}", "Video player (debug): https://${digitalocean_domain.ipfs-live-streaming.name}?live=live.m3u8", ] -} \ No newline at end of file +} diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 2c36290..42934bf 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -57,7 +57,6 @@ tar -C /usr/local -xzf /tmp/golang/go1.11.2.linux-amd64.tar.gz . /etc/profile # Create directory for generating client keys -mkdir /root/client-keys ########### # OpenVPN # @@ -226,7 +225,7 @@ cd ~ # Configure IPFS ipfs init sed -i 's#"Gateway": "/ip4/127.0.0.1/tcp/8080#"Gateway": "/ip4/0.0.0.0/tcp/8080#' ~/.ipfs/config -cp -f /tmp/ipfs-server/ipfs.service /etc/systemd/system/ipfs.service +cp -f /tmp/rtmp-server/ipfs.service /etc/systemd/system/ipfs.service systemctl daemon-reload systemctl enable ipfs systemctl start ipfs @@ -252,7 +251,7 @@ echo -n "$IPFS_ID" > ~/client-keys/ipfs_id ######################## # Install video stream processing script -cp -f /tmp/ipfs-server/process-stream.sh ~/process-stream.sh +cp -f /tmp/rtmp-server/process-stream.sh ~/process-stream.sh # Save settings to a file echo "#!/bin/sh" > ~/settings @@ -263,7 +262,7 @@ echo "export IPFS_GATEWAY=\"https://ipfs-gateway.${DOMAIN_NAME}\"" >> ~/settings chmod +x ~/settings # Install and start process-stream service -cp -f /tmp/ipfs-server/process-stream.service /etc/systemd/system/process-stream.service +cp -f /tmp/rtmp-server/process-stream.service /etc/systemd/system/process-stream.service systemctl daemon-reload systemctl enable process-stream systemctl start process-stream From a2086c78e61836f00cdf97aa648c33f3dd581d81 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 14:59:00 -0400 Subject: [PATCH 03/27] Update bootstrap.sh --- terraform/rtmp-server/bootstrap.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 2c36290..8db933a 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -209,9 +209,6 @@ mkdir /root/hls cp -f /tmp/rtmp-server/nginx.conf /usr/local/nginx/conf/nginx.conf sed -i "s/__PUBLISHER_IP_ADDRESS__/`cat ~/publisher.key | grep Address | awk '{print $2}'`/" /usr/local/nginx/conf/nginx.conf -# Start nginx -/usr/local/nginx/sbin/nginx - ######## # IPFS # ######## @@ -273,7 +270,8 @@ systemctl start process-stream ################ # Install web video player -rm -rf /var/www/html/* +rm -rf /var/www/html/* || true +mkdir -p /var/www/html/ || true cp -r /tmp/video-player/* /var/www/html/ # Configure video player @@ -281,3 +279,8 @@ sed -i "s#__IPFS_GATEWAY_SELF__#https://ipfs-gateway.${DOMAIN_NAME}#g" /var/www/ sed -i "s#__IPFS_GATEWAY_ORIGIN__#https://ipfs-gateway.${DOMAIN_NAME}#g" /var/www/html/js/common.js sed -i "s#__IPFS_ID_ORIGIN__#${IPFS_ID}#g" /var/www/html/js/common.js sed -i "s#__M3U8_HTTP_URLS__#${M3U8_HTTP_URLS}#g" /var/www/html/js/common.js + +mkdir /usr/local/nginx/conf/conf.d + +# Start nginx +/usr/local/nginx/sbin/nginx From 26967cdc6eceda29eeb2bba31e60dda5fe5c99e2 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 14:59:46 -0400 Subject: [PATCH 04/27] Update bootstrap-post-dns.sh --- terraform/rtmp-server/bootstrap-post-dns.sh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/terraform/rtmp-server/bootstrap-post-dns.sh b/terraform/rtmp-server/bootstrap-post-dns.sh index a4895b4..f2921cf 100644 --- a/terraform/rtmp-server/bootstrap-post-dns.sh +++ b/terraform/rtmp-server/bootstrap-post-dns.sh @@ -17,15 +17,12 @@ systemctl stop nginx.service certbot certonly -n --agree-tos --standalone --email "${EMAIL_ADDRESS}" -d "${DOMAIN_NAME}" -d "ipfs-server.${DOMAIN_NAME}" -d "ipfs-gateway.${DOMAIN_NAME}" # Configure nginx with HTTPS -cp -f /tmp/ipfs-server/nginx-default /etc/nginx/sites-available/default -sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" /etc/nginx/sites-available/default +cp -f /tmp/rtmp-server/nginx-default /usr/local/nginx/conf/conf.d/default +sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" /usr/local/nginx/conf/conf.d/default -cp -f /tmp/ipfs-server/nginx-gateway "/etc/nginx/sites-available/ipfs-gateway.${DOMAIN_NAME}" -sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" "/etc/nginx/sites-available/ipfs-gateway.${DOMAIN_NAME}" -ln -s "/etc/nginx/sites-available/ipfs-gateway.${DOMAIN_NAME}" "/etc/nginx/sites-enabled/ipfs-gateway.${DOMAIN_NAME}" - -systemctl start nginx.service +cp -f /tmp/rtmp-server/nginx-gateway "/usr/local/nginx/conf/conf.d/ipfs-gateway.${DOMAIN_NAME}" +sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" "/usr/local/nginx/conf/conf.d/ipfs-gateway.${DOMAIN_NAME}" # Configure auto-renewals echo "30 2 * * 1 certbot renew >> /var/log/letsencrypt/letsencrypt.log" >> /etc/crontab -echo "35 2 * * 1 systemctl reload nginx" >> /etc/crontab \ No newline at end of file +echo "35 2 * * 1 systemctl reload nginx" >> /etc/crontab From b845d43fbec1458bdcfec9a73eb581708da8ac5c Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 15:00:20 -0400 Subject: [PATCH 05/27] Update nginx.conf --- terraform/rtmp-server/nginx.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/terraform/rtmp-server/nginx.conf b/terraform/rtmp-server/nginx.conf index 86b00c2..d0afe9d 100644 --- a/terraform/rtmp-server/nginx.conf +++ b/terraform/rtmp-server/nginx.conf @@ -25,4 +25,6 @@ rtmp { hls_playlist_length 60m; } } -} \ No newline at end of file +} + +include include/*; From 8b67eebbc5ed4e1f0bf34a0040aebf1d5d413d36 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 15:05:18 -0400 Subject: [PATCH 06/27] Update nginx.conf --- terraform/rtmp-server/nginx.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/terraform/rtmp-server/nginx.conf b/terraform/rtmp-server/nginx.conf index d0afe9d..8ec2f79 100644 --- a/terraform/rtmp-server/nginx.conf +++ b/terraform/rtmp-server/nginx.conf @@ -27,4 +27,6 @@ rtmp { } } -include include/*; +http { + include conf.d/*; +} From b5fbb7d7beda710d8b5c0da1261756ddbe4676b0 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 15:06:48 -0400 Subject: [PATCH 07/27] Updated nginx compile paramaters --- terraform/rtmp-server/bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 8db933a..6ea2882 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -200,7 +200,7 @@ git clone https://github.com/arut/nginx-rtmp-module.git # Build nginx with nginx-rtmp cd "nginx-${NGINX_VERSION}" -./configure --with-http_ssl_module --add-module=../nginx-rtmp-module +./configure --with-http_ssl_module --with-http_v2_module --with-fastcgi=/usr/local --add-module=../nginx-rtmp-module make make install From 95b278aa6df6cedfc8ba1eb231647dd026e1b28b Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 16:09:43 -0400 Subject: [PATCH 08/27] Update nginx.conf --- terraform/rtmp-server/nginx.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/terraform/rtmp-server/nginx.conf b/terraform/rtmp-server/nginx.conf index 8ec2f79..90ce2a4 100644 --- a/terraform/rtmp-server/nginx.conf +++ b/terraform/rtmp-server/nginx.conf @@ -28,5 +28,6 @@ rtmp { } http { + include mime.types; include conf.d/*; } From 06e8ef5f22ffaf4a2cc290760a80516b67f44565 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 17:19:41 -0400 Subject: [PATCH 09/27] Process stream updated for hls --- terraform/rtmp-server/process-stream.sh | 121 +++++++++++------------- 1 file changed, 57 insertions(+), 64 deletions(-) diff --git a/terraform/rtmp-server/process-stream.sh b/terraform/rtmp-server/process-stream.sh index edc115d..6a7afd8 100644 --- a/terraform/rtmp-server/process-stream.sh +++ b/terraform/rtmp-server/process-stream.sh @@ -1,3 +1,4 @@ + #!/bin/bash # Load settings @@ -9,79 +10,71 @@ cd ~/hls # Start ffmpeg in background startFFmpeg & +what="TEST1" +M3U8_SIZE=5 while true; do - nextfile=$(ls -tr ${what}*.ts 2>/dev/null | tail -n 1) + nextfile=$(cat ${what}.m3u8 |tail -n1); + + if [ -f "${nextfile}" ]; then + timecode=`grep -B1 ${nextfile} ${what}.m3u8 | head -n1 | awk -F : '{print $2}' | tr -d ,` + if ! [ -z "${nextfile}" ]; then + if ! [ -z "{$timecode}" ]; then + echo FOUND $nextfile + + # Check if the next file on the list is still being written to by ffmpeg + echo ${nextfile} ${timecode} + reset_stream=$(cat ~/stream-reset) + reset_stream_marker='' + if [[ ${reset_stream} -eq '1' ]]; then + reset_stream_marker=" #EXT-X-DISCONTINUITY" + fi + + echo 0 > ~/stream-reset + # Current UTC date for the log + time=`date "+%F-%H-%M-%S"` - if ! [ -z "${nextfile}" ]; then - # Check if the next file on the list is still being written to by ffmpeg - if ! [ -z "$(lsof ${nextfile} | grep ffmpeg)" ]; then - # Wait for file to finish writing - # If not finished in 45 seconds something is wrong, timeout - inotifywait -e close_write $nextfile -t 45 - fi + # Add ts file to IPFS - # Grab the timecode from the m3u8 file so we can add it to the log - timecode=`grep -B1 ${nextfile} ${what}.m3u8 | head -n1 | awk -F : '{print $2}' | tr -d ,` - attempts=5 - until [[ "${timecode}" || ${attempts} -eq 0 ]]; do - # Wait and retry - sleep 0.5 - timecode=`grep -B1 ${nextfile} ${what}.m3u8 | head -n1 | awk -F : '{print $2}' | tr -d ,` - attempts=$((attempts-1)) - done - if ! [[ "${timecode}" ]]; then - # Set approximate timecode - timecode="${HLS_TIME}.000000" - fi - - reset_stream=$(cat ~/stream-reset) - reset_stream_marker='' - if [[ ${reset_stream} -eq '1' ]]; then - reset_stream_marker=" #EXT-X-DISCONTINUITY" - fi - - echo 0 > ~/stream-reset - # Current UTC date for the log - time=`date "+%F-%H-%M-%S"` + ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` + attempts=5 + until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do + # Wait and retry + sleep 1 + echo ipfs add ${nextfile} + ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` + attempts=$((attempts-1)) + done + if [[ ${ret} -eq 0 ]]; then + # Update the log with the future name (hash already there) + echo $(cat ~/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker} >> ~/process-stream.log - # Add ts file to IPFS - ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` - attempts=5 - until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do - # Wait and retry - sleep 1 - ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` - attempts=$((attempts-1)) - done - if [[ ${ret} -eq 0 ]]; then - # Update the log with the future name (hash already there) - echo $(cat ~/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker} >> ~/process-stream.log + # Remove nextfile and tmp.txt + rm -f ${nextfile} ~/tmp.txt - # Remove nextfile and tmp.txt - rm -f ${nextfile} ~/tmp.txt + # Write the m3u8 file with the new IPFS hashes from the log + totalLines="$(wc -l ~/process-stream.log | awk '{print $1}')" - # Write the m3u8 file with the new IPFS hashes from the log - totalLines="$(wc -l ~/process-stream.log | awk '{print $1}')" - - sequence=0 - if (( "${totalLines}" > ${M3U8_SIZE} )); then - sequence=`expr ${totalLines} - ${M3U8_SIZE}` - fi - echo "#EXTM3U" > current.m3u8 - echo "#EXT-X-VERSION:3" >> current.m3u8 - echo "#EXT-X-TARGETDURATION:${HLS_TIME}" >> current.m3u8 - echo "#EXT-X-MEDIA-SEQUENCE:${sequence}" >> current.m3u8 - tail -n ${M3U8_SIZE} ~/process-stream.log | awk '{print $6"#EXTINF:"$5",\n'${IPFS_GATEWAY}'/ipfs/"$2}' | sed 's/#EXT-X-DISCONTINUITY#/#EXT-X-DISCONTINUITY\n#/g' >> current.m3u8 + sequence=0 + if (( "${totalLines}" > ${M3U8_SIZE} )); then + sequence=`expr ${totalLines} - ${M3U8_SIZE}` + fi + echo "#EXTM3U" > current.m3u8 + echo "#EXT-X-VERSION:3" >> current.m3u8 + echo "#EXT-X-TARGETDURATION:${HLS_TIME}" >> current.m3u8 + echo "#EXT-X-MEDIA-SEQUENCE:${sequence}" >> current.m3u8 + tail -n ${M3U8_SIZE} ~/process-stream.log | awk '{print $6"#EXTINF:"$5",\n'${IPFS_GATEWAY}'/ipfs/"$2}' | sed 's/#EXT-X-DISCONTINUITY#/#EXT-X-DISCONTINUITY\n#/g' >> current.m3u8 - # Add m3u8 file to IPFS and IPNS publish (uncomment to enable) - #m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}') - #ipfs name publish --timeout=5s $m3u8hash & + # Add m3u8 file to IPFS and IPNS publish (uncomment to enable) + #m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}') + #ipfs name publish --timeout=5s $m3u8hash & - # Copy files to web server - cp current.m3u8 /var/www/html/live.m3u8 - cp ~/process-stream.log /var/www/html/live.log - fi + # Copy files to web server + cp current.m3u8 /var/www/html/live.m3u8 + cp ~/process-stream.log /var/www/html/live.log + fi + fi + fi else sleep 5 fi From d2a18e106909ddea1c2d7fa18de4f636dcf3accb Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 20:06:05 -0400 Subject: [PATCH 10/27] Fixed nginx and bootstrap things --- terraform/main.tf | 36 +++++++++++++++++++-- terraform/rtmp-server/bootstrap-post-dns.sh | 0 terraform/rtmp-server/bootstrap.sh | 6 ++-- terraform/rtmp-server/nginx.service | 28 ++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) mode change 100644 => 100755 terraform/rtmp-server/bootstrap-post-dns.sh create mode 100644 terraform/rtmp-server/nginx.service diff --git a/terraform/main.tf b/terraform/main.tf index 7a6a990..a567012 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -37,7 +37,9 @@ resource "digitalocean_droplet" "rtmp-server" { provisioner "remote-exec" { inline = [ "chmod +x /tmp/rtmp-server/bootstrap.sh", - "/tmp/rtmp-server/bootstrap.sh", + "chmod +x /tmp/rtmp-server/bootstrap-post-dns.sh", + "chmod +x /tmp/rtmp-server/process-stream.sh", + "/tmp/rtmp-server/bootstrap.sh ${file(var.domain_name)} ${file(var.email_address)} ${digitalocean_droplet.rtmp-server.ipv4_address_private} ${var.m3u8_http_urls}", ] } provisioner "local-exec" { @@ -94,13 +96,41 @@ resource "null_resource" "rtmp-server" { private_key = "${file(var.pvt_key)}" timeout = "2m" } + provisioner "remote-exec" { inline = [ "/tmp/rtmp-server/bootstrap-post-dns.sh ${file(var.domain_name)} ${file(var.email_address)}", ] } } - +resource "digitalocean_record" "ipfs-server-v6" { + domain = "${digitalocean_domain.ipfs-live-streaming.name}" + type = "AAAA" + name = "v6.ipfs-server" + value = "${digitalocean_droplet.rtmp-server.ipv6_address}" + ttl = "600" +} +resource "digitalocean_record" "ipfs-server-gateway" { + domain = "${digitalocean_domain.ipfs-live-streaming.name}" + type = "A" + name = "ipfs-gateway" + value = "${digitalocean_droplet.rtmp-server.ipv4_address}" + ttl = "600" +} +resource "digitalocean_record" "ipfs-server-gateway-private" { + domain = "${digitalocean_domain.ipfs-live-streaming.name}" + type = "A" + name = "private.ipfs-gateway" + value = "${digitalocean_droplet.rtmp-server.ipv4_address_private}" + ttl = "600" +} +resource "digitalocean_record" "ipfs-server-gateway-v6" { + domain = "${digitalocean_domain.ipfs-live-streaming.name}" + type = "AAAA" + name = "v6.ipfs-gateway" + value = "${digitalocean_droplet.rtmp-server.ipv6_address}" + ttl = "600" +} # IPFS mirror Droplets resource "digitalocean_droplet" "ipfs-mirror" { depends_on = ["digitalocean_droplet.rtmp-server"] @@ -238,7 +268,7 @@ output "dns_records" { output "ssh_access" { depends_on = ["digitalocean_record.*"] value = [ - "rtmp-server: ssh -i .keys/id_rsa root@${digitalocean_record.rtmp-server.fqdn}", + "rtmp-server: ssh -i .keys/id_rsa root@${digitalocean_record.rtmp-server.fqdn}", "ipfs-mirror-N: ssh -i .keys/id_rsa root@ipfs-mirror-N.${digitalocean_domain.ipfs-live-streaming.name}", ] } diff --git a/terraform/rtmp-server/bootstrap-post-dns.sh b/terraform/rtmp-server/bootstrap-post-dns.sh old mode 100644 new mode 100755 diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 082b512..941217f 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -199,7 +199,7 @@ git clone https://github.com/arut/nginx-rtmp-module.git # Build nginx with nginx-rtmp cd "nginx-${NGINX_VERSION}" -./configure --with-http_ssl_module --with-http_v2_module --with-fastcgi=/usr/local --add-module=../nginx-rtmp-module +./configure --with-http_ssl_module --with-http_v2_module --add-module=../nginx-rtmp-module make make install @@ -282,4 +282,6 @@ sed -i "s#__M3U8_HTTP_URLS__#${M3U8_HTTP_URLS}#g" /var/www/html/js/common.js mkdir /usr/local/nginx/conf/conf.d # Start nginx -/usr/local/nginx/sbin/nginx +cp /tmp/rtmp-server/nginx.service /etc/systemd/system/nginx.service +chmod +x /tmp/rtmp-server/*.sh +systemctl start nginx diff --git a/terraform/rtmp-server/nginx.service b/terraform/rtmp-server/nginx.service new file mode 100644 index 0000000..845b28b --- /dev/null +++ b/terraform/rtmp-server/nginx.service @@ -0,0 +1,28 @@ +# Stop dance for nginx +# ======================= +# +# ExecStop sends SIGSTOP (graceful stop) to the nginx process. +# If, after 5s (--retry QUIT/5) nginx is still running, systemd takes control +# and sends SIGTERM (fast shutdown) to the main process. +# After another 5s (TimeoutStopSec=5), and if nginx is alive, systemd sends +# SIGKILL to all the remaining processes in the process group (KillMode=mixed). +# +# nginx signals reference doc: +# http://nginx.org/en/docs/control.html +# +[Unit] +Description=A high performance web server and a reverse proxy server +After=network.target + +[Service] +Type=forking +PIDFile=/usr/local/nginx/logs/nginx.pid +ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -g 'daemon on; master_process on;' +ExecStart=/usr/local/nginx/sbin/nginx -g 'daemon on; master_process on;' +ExecReload=/usr/local/nginx/sbin/nginx -g 'daemon on; master_process on;' -s reload +ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /usr/local/nginx/logs/nginx.pid +TimeoutStopSec=5 +KillMode=mixed + +[Install] +WantedBy=multi-user.target From d3c9acb2a9f50a29b747cf52f8c801943e902937 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 28 Mar 2019 21:40:43 -0400 Subject: [PATCH 11/27] Updated process stream --- terraform/rtmp-server/process-stream.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/terraform/rtmp-server/process-stream.sh b/terraform/rtmp-server/process-stream.sh index 6a7afd8..42fcfc6 100644 --- a/terraform/rtmp-server/process-stream.sh +++ b/terraform/rtmp-server/process-stream.sh @@ -1,4 +1,3 @@ - #!/bin/bash # Load settings @@ -8,8 +7,9 @@ rm -rf ~/hls/* cd ~/hls +DISCONNET=1 + # Start ffmpeg in background -startFFmpeg & what="TEST1" M3U8_SIZE=5 @@ -20,17 +20,17 @@ while true; do timecode=`grep -B1 ${nextfile} ${what}.m3u8 | head -n1 | awk -F : '{print $2}' | tr -d ,` if ! [ -z "${nextfile}" ]; then if ! [ -z "{$timecode}" ]; then - echo FOUND $nextfile - # Check if the next file on the list is still being written to by ffmpeg - echo ${nextfile} ${timecode} - reset_stream=$(cat ~/stream-reset) - reset_stream_marker='' - if [[ ${reset_stream} -eq '1' ]]; then - reset_stream_marker=" #EXT-X-DISCONTINUITY" - fi - echo 0 > ~/stream-reset + reset_stream_marker='' + if [[ "$(grep -B2 ${nextfile} ${what}.m3u8 | head -n1)" == "#EXT-X-DISCONTINUITY" ]]; then + reset_stream_marker=" #EXT-X-DISCONTINUITY" + if + if [[ "$(DISCONNET)" == "1" ]]; then + reset_stream_marker=" #EXT-X-DISCONTINUITY" + DISCONNECT=0 + fi + # Current UTC date for the log time=`date "+%F-%H-%M-%S"` From 5e6f8ad2de61b8c161e8137b188f6905efced854 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Fri, 29 Mar 2019 00:05:51 -0400 Subject: [PATCH 12/27] Corrected bootstrap and process stream --- terraform/rtmp-server/bootstrap.sh | 5 +- terraform/rtmp-server/process-stream.sh | 95 ++++++++++++------------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 941217f..5f2151d 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -283,5 +283,6 @@ mkdir /usr/local/nginx/conf/conf.d # Start nginx cp /tmp/rtmp-server/nginx.service /etc/systemd/system/nginx.service -chmod +x /tmp/rtmp-server/*.sh -systemctl start nginx +systemctl daemon-reload +systemctl enable nginx.service +systemctl start nginx.service \ No newline at end of file diff --git a/terraform/rtmp-server/process-stream.sh b/terraform/rtmp-server/process-stream.sh index 42fcfc6..1871101 100644 --- a/terraform/rtmp-server/process-stream.sh +++ b/terraform/rtmp-server/process-stream.sh @@ -10,26 +10,25 @@ cd ~/hls DISCONNET=1 # Start ffmpeg in background -what="TEST1" +what="stream1" M3U8_SIZE=5 while true; do nextfile=$(cat ${what}.m3u8 |tail -n1); - if [ -f "${nextfile}" ]; then + if [ -f "${nextfile}" ]; then timecode=`grep -B1 ${nextfile} ${what}.m3u8 | head -n1 | awk -F : '{print $2}' | tr -d ,` if ! [ -z "${nextfile}" ]; then if ! [ -z "{$timecode}" ]; then - - reset_stream_marker='' - if [[ "$(grep -B2 ${nextfile} ${what}.m3u8 | head -n1)" == "#EXT-X-DISCONTINUITY" ]]; then - reset_stream_marker=" #EXT-X-DISCONTINUITY" - if - if [[ "$(DISCONNET)" == "1" ]]; then - reset_stream_marker=" #EXT-X-DISCONTINUITY" - DISCONNECT=0 - fi + reset_stream_marker='' + if [[ "$(grep -B2 ${nextfile} ${what}.m3u8 | head -n1)" == "#EXT-X-DISCONTINUITY" ]]; then + reset_stream_marker=" #EXT-X-DISCONTINUITY" + if + if [[ "$(DISCONNET)" == "1" ]]; then + reset_stream_marker=" #EXT-X-DISCONTINUITY" + DISCONNECT=0 + fi # Current UTC date for the log time=`date "+%F-%H-%M-%S"` @@ -39,43 +38,43 @@ while true; do ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` attempts=5 until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do - # Wait and retry - sleep 1 - echo ipfs add ${nextfile} - ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` - attempts=$((attempts-1)) + # Wait and retry + sleep 1 + echo ipfs add ${nextfile} + ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` + attempts=$((attempts-1)) done if [[ ${ret} -eq 0 ]]; then - # Update the log with the future name (hash already there) - echo $(cat ~/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker} >> ~/process-stream.log - - # Remove nextfile and tmp.txt - rm -f ${nextfile} ~/tmp.txt - - # Write the m3u8 file with the new IPFS hashes from the log - totalLines="$(wc -l ~/process-stream.log | awk '{print $1}')" - - sequence=0 - if (( "${totalLines}" > ${M3U8_SIZE} )); then - sequence=`expr ${totalLines} - ${M3U8_SIZE}` - fi - echo "#EXTM3U" > current.m3u8 - echo "#EXT-X-VERSION:3" >> current.m3u8 - echo "#EXT-X-TARGETDURATION:${HLS_TIME}" >> current.m3u8 - echo "#EXT-X-MEDIA-SEQUENCE:${sequence}" >> current.m3u8 - tail -n ${M3U8_SIZE} ~/process-stream.log | awk '{print $6"#EXTINF:"$5",\n'${IPFS_GATEWAY}'/ipfs/"$2}' | sed 's/#EXT-X-DISCONTINUITY#/#EXT-X-DISCONTINUITY\n#/g' >> current.m3u8 - - # Add m3u8 file to IPFS and IPNS publish (uncomment to enable) - #m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}') - #ipfs name publish --timeout=5s $m3u8hash & - - # Copy files to web server - cp current.m3u8 /var/www/html/live.m3u8 - cp ~/process-stream.log /var/www/html/live.log - fi - fi - fi - else - sleep 5 - fi + # Update the log with the future name (hash already there) + echo $(cat ~/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker} >> ~/process-stream.log + + # Remove nextfile and tmp.txt + rm -f ${nextfile} ~/tmp.txt + + # Write the m3u8 file with the new IPFS hashes from the log + totalLines="$(wc -l ~/process-stream.log | awk '{print $1}')" + + sequence=0 + if (( "${totalLines}" > ${M3U8_SIZE} )); then + sequence=`expr ${totalLines} - ${M3U8_SIZE}` + fi + echo "#EXTM3U" > current.m3u8 + echo "#EXT-X-VERSION:3" >> current.m3u8 + echo "#EXT-X-TARGETDURATION:${HLS_TIME}" >> current.m3u8 + echo "#EXT-X-MEDIA-SEQUENCE:${sequence}" >> current.m3u8 + tail -n ${M3U8_SIZE} ~/process-stream.log | awk '{print $6"#EXTINF:"$5",\n'${IPFS_GATEWAY}'/ipfs/"$2}' | sed 's/#EXT-X-DISCONTINUITY#/#EXT-X-DISCONTINUITY\n#/g' >> current.m3u8 + + # Add m3u8 file to IPFS and IPNS publish (uncomment to enable) + #m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}') + #ipfs name publish --timeout=5s $m3u8hash & + + # Copy files to web server + cp current.m3u8 /var/www/html/live.m3u8 + cp ~/process-stream.log /var/www/html/live.log + fi + fi + fi + else + sleep 5 + fi done From 16d05bd71f1b00711f3c5fd85e3d5fa8e831c281 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Fri, 29 Mar 2019 00:34:40 -0400 Subject: [PATCH 13/27] Cleanup --- terraform/rtmp-server/bootstrap.sh | 10 ++++------ terraform/rtmp-server/process-stream.sh | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 5f2151d..e0f3a67 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -37,10 +37,7 @@ apt install -y \ zlib1g-dev \ bc \ certbot \ - ffmpeg \ - inotify-tools \ - jq \ - lsof + jq # Create directory for generating client keys mkdir /root/client-keys @@ -284,5 +281,6 @@ mkdir /usr/local/nginx/conf/conf.d # Start nginx cp /tmp/rtmp-server/nginx.service /etc/systemd/system/nginx.service systemctl daemon-reload -systemctl enable nginx.service -systemctl start nginx.service \ No newline at end of file +systemctl enable nginx.service || true +systemctl start nginx.service || true +exit 0 \ No newline at end of file diff --git a/terraform/rtmp-server/process-stream.sh b/terraform/rtmp-server/process-stream.sh index 1871101..d61d410 100644 --- a/terraform/rtmp-server/process-stream.sh +++ b/terraform/rtmp-server/process-stream.sh @@ -40,7 +40,6 @@ while true; do until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do # Wait and retry sleep 1 - echo ipfs add ${nextfile} ret=`ipfs add ${nextfile} 2>/dev/null > ~/tmp.txt; echo $?` attempts=$((attempts-1)) done From c05b63dbdbd82b45f5669d098b7cded7752bd084 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Fri, 29 Mar 2019 00:59:15 -0400 Subject: [PATCH 14/27] Corrected syntax --- terraform/rtmp-server/bootstrap-post-dns.sh | 2 ++ terraform/rtmp-server/process-stream.sh | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/terraform/rtmp-server/bootstrap-post-dns.sh b/terraform/rtmp-server/bootstrap-post-dns.sh index f2921cf..b9b6bd9 100755 --- a/terraform/rtmp-server/bootstrap-post-dns.sh +++ b/terraform/rtmp-server/bootstrap-post-dns.sh @@ -26,3 +26,5 @@ sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" "/usr/local/nginx/conf/conf.d/ipfs-g # Configure auto-renewals echo "30 2 * * 1 certbot renew >> /var/log/letsencrypt/letsencrypt.log" >> /etc/crontab echo "35 2 * * 1 systemctl reload nginx" >> /etc/crontab + +systemctl start nginx.service diff --git a/terraform/rtmp-server/process-stream.sh b/terraform/rtmp-server/process-stream.sh index d61d410..5a46056 100644 --- a/terraform/rtmp-server/process-stream.sh +++ b/terraform/rtmp-server/process-stream.sh @@ -8,8 +8,6 @@ rm -rf ~/hls/* cd ~/hls DISCONNET=1 - -# Start ffmpeg in background what="stream1" M3U8_SIZE=5 @@ -24,7 +22,7 @@ while true; do reset_stream_marker='' if [[ "$(grep -B2 ${nextfile} ${what}.m3u8 | head -n1)" == "#EXT-X-DISCONTINUITY" ]]; then reset_stream_marker=" #EXT-X-DISCONTINUITY" - if + fi if [[ "$(DISCONNET)" == "1" ]]; then reset_stream_marker=" #EXT-X-DISCONTINUITY" DISCONNECT=0 @@ -76,4 +74,4 @@ while true; do else sleep 5 fi -done +done \ No newline at end of file From c3d9f242c2f93747b67deea56ae0143c58112754 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Fri, 29 Mar 2019 01:17:53 -0400 Subject: [PATCH 15/27] Cleanup --- terraform/main.tf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/terraform/main.tf b/terraform/main.tf index a567012..4cc4617 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -103,6 +103,13 @@ resource "null_resource" "rtmp-server" { ] } } +resource "digitalocean_record" "ipfs-server" { + domain = "${digitalocean_domain.ipfs-live-streaming.name}" + type = "A" + name = "ipfs-server" + value = "${digitalocean_droplet.rtmp-server.ipv4_address}" + ttl = "600" +} resource "digitalocean_record" "ipfs-server-v6" { domain = "${digitalocean_domain.ipfs-live-streaming.name}" type = "AAAA" From 021162477b407fe2dcad1f81a8553723449fe91f Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Fri, 29 Mar 2019 01:23:20 -0400 Subject: [PATCH 16/27] Syntax cleanup --- terraform/rtmp-server/bootstrap.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index e0f3a67..c6cea93 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -281,6 +281,6 @@ mkdir /usr/local/nginx/conf/conf.d # Start nginx cp /tmp/rtmp-server/nginx.service /etc/systemd/system/nginx.service systemctl daemon-reload -systemctl enable nginx.service || true -systemctl start nginx.service || true +systemctl enable nginx.service +systemctl start nginx.service exit 0 \ No newline at end of file From 76ba2dcbf7fe74bed0bb5f261822b93a7ba29dfe Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Fri, 29 Mar 2019 01:27:26 -0400 Subject: [PATCH 17/27] Whitespace --- terraform/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/main.tf b/terraform/main.tf index 4cc4617..e12df55 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -269,7 +269,7 @@ output "dns_records" { "${zipmap(digitalocean_record.ipfs-mirror-v6.*.fqdn, digitalocean_record.ipfs-mirror-v6.*.value)}", "${zipmap(digitalocean_record.ipfs-mirror-gateway-v6.*.fqdn, digitalocean_record.ipfs-mirror-gateway-v6.*.value)}", " ${digitalocean_record.publish-openvpn.fqdn} = ${digitalocean_record.publish-openvpn.value}", - " ${digitalocean_record.publish-yggdrasil.fqdn} = ${digitalocean_record.publish-yggdrasil.value}", + " ${digitalocean_record.publish-yggdrasil.fqdn} = ${digitalocean_record.publish-yggdrasil.value}", ] } output "ssh_access" { From 2cccd4b09e6f716e27053f2d313cbd2856f939bf Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Tue, 13 Aug 2019 22:25:01 -0400 Subject: [PATCH 18/27] updated stream1 requirement --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d99032e..fa0bedb 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ installed on your local machine, which can be the same device running OBS Studio To authenticate using OpenVPN, connect with your OpenVPN client using `client.conf` or `client.ovpn`, then publish your OBS Studio stream to: - rtmp://10.10.10.1:1935/live + rtmp://10.10.10.1:1935/live/stream1 To authenticate using Yggdrasil, start it with `yggdrasil.conf` and note the last line of output like this: @@ -213,7 +213,7 @@ installed on your local machine, which can be the same device running OBS Studio Then publish your OBS Studio stream to the IPv6: - rtmp://[203:4bb0:9ff1:2312:e7f3:b8c4:852:a8b1]:1935/live + rtmp://[203:4bb0:9ff1:2312:e7f3:b8c4:852:a8b1]:1935/live/stream1 1. When your streaming session is done, you can stop OpenVPN or Yggdrasil and destroy the servers with: From 0dd2438c36eb74123fea71a8cdc4b912bd2d36b9 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Thu, 15 Aug 2019 09:51:00 -0400 Subject: [PATCH 19/27] Syntax Update --- terraform/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/main.tf b/terraform/main.tf index e12df55..2c4d3cc 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -275,7 +275,7 @@ output "dns_records" { output "ssh_access" { depends_on = ["digitalocean_record.*"] value = [ - "rtmp-server: ssh -i .keys/id_rsa root@${digitalocean_record.rtmp-server.fqdn}", + "rtmp-server: ssh -i .keys/id_rsa root@${digitalocean_record.rtmp-server.fqdn}", "ipfs-mirror-N: ssh -i .keys/id_rsa root@ipfs-mirror-N.${digitalocean_domain.ipfs-live-streaming.name}", ] } @@ -298,4 +298,4 @@ output "public_urls" { "Video player (mirror-N): https://ipfs-mirror-N.${digitalocean_domain.ipfs-live-streaming.name}", "Video player (debug): https://${digitalocean_domain.ipfs-live-streaming.name}?live=live.m3u8", ] -} +} \ No newline at end of file From 186eeae5c4318f414f916dd76d3232901c8b9460 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 21:47:36 -0400 Subject: [PATCH 20/27] Delete Security --- terraform/Security | 1 - 1 file changed, 1 deletion(-) delete mode 100644 terraform/Security diff --git a/terraform/Security b/terraform/Security deleted file mode 100644 index 545f9b8..0000000 --- a/terraform/Security +++ /dev/null @@ -1 +0,0 @@ -Add the SSH key to your Digital Ocean account under Settings From d7806a201aefd2768e82bff2aa6b2ebb668cad25 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 21:48:27 -0400 Subject: [PATCH 21/27] Update terraform/rtmp-server/bootstrap-post-dns.sh Co-Authored-By: Benedict Lau --- terraform/rtmp-server/bootstrap-post-dns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/rtmp-server/bootstrap-post-dns.sh b/terraform/rtmp-server/bootstrap-post-dns.sh index b9b6bd9..49868b3 100755 --- a/terraform/rtmp-server/bootstrap-post-dns.sh +++ b/terraform/rtmp-server/bootstrap-post-dns.sh @@ -18,7 +18,7 @@ certbot certonly -n --agree-tos --standalone --email "${EMAIL_ADDRESS}" -d "${DO # Configure nginx with HTTPS cp -f /tmp/rtmp-server/nginx-default /usr/local/nginx/conf/conf.d/default -sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" /usr/local/nginx/conf/conf.d/default +sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" /usr/local/nginx/conf/conf.d/default cp -f /tmp/rtmp-server/nginx-gateway "/usr/local/nginx/conf/conf.d/ipfs-gateway.${DOMAIN_NAME}" sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" "/usr/local/nginx/conf/conf.d/ipfs-gateway.${DOMAIN_NAME}" From 1426b899632fdad35997d455c4cd8bc6234f8e9b Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 21:49:00 -0400 Subject: [PATCH 22/27] Update terraform/rtmp-server/bootstrap.sh Co-Authored-By: Benedict Lau --- terraform/rtmp-server/bootstrap.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index c6cea93..0f079cf 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -235,7 +235,6 @@ sleep 10 IPFS_ID=`ipfs id | jq .ID | sed 's/"//g'` echo -n "$IPFS_ID" > ~/client-keys/ipfs_id - # Publish message to IPNS # Commented out because IPNS is not predictable and could stall the script # echo "Serving m3u8 over IPNS is currently disabled" | ipfs add | awk '{print $2}' | ipfs name publish @@ -283,4 +282,4 @@ cp /tmp/rtmp-server/nginx.service /etc/systemd/system/nginx.service systemctl daemon-reload systemctl enable nginx.service systemctl start nginx.service -exit 0 \ No newline at end of file +exit 0 From 066a0e3a9e5ed671859b25b8676f34a95db4872f Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 21:50:01 -0400 Subject: [PATCH 23/27] Update bootstrap.sh --- terraform/rtmp-server/bootstrap.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 0f079cf..3c9ba13 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -53,8 +53,6 @@ tar -C /usr/local -xzf /tmp/golang/go1.11.2.linux-amd64.tar.gz } >> /etc/profile . /etc/profile -# Create directory for generating client keys - ########### # OpenVPN # ########### From 61b44fcd2b0ad1c60a6c9b8e5e7d01f2808a1a79 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 21:51:11 -0400 Subject: [PATCH 24/27] Alphabetize apt-get --- terraform/rtmp-server/bootstrap.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/terraform/rtmp-server/bootstrap.sh b/terraform/rtmp-server/bootstrap.sh index 3c9ba13..26d8754 100644 --- a/terraform/rtmp-server/bootstrap.sh +++ b/terraform/rtmp-server/bootstrap.sh @@ -27,17 +27,17 @@ curl -sSL https://agent.digitalocean.com/install.sh | sh # Install standard tools apt update apt install -y \ + bc \ build-essential \ + certbot \ git \ + jq \ libpcre3 \ libpcre3-dev \ libssl-dev \ zlibc \ zlib1g \ - zlib1g-dev \ - bc \ - certbot \ - jq + zlib1g-dev # Create directory for generating client keys mkdir /root/client-keys From e340acc80cd8181ec45dfb4bf0dc290fd20674ca Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 22:03:16 -0400 Subject: [PATCH 25/27] Update terraform/rtmp-server/bootstrap-post-dns.sh Co-Authored-By: Benedict Lau --- terraform/rtmp-server/bootstrap-post-dns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/rtmp-server/bootstrap-post-dns.sh b/terraform/rtmp-server/bootstrap-post-dns.sh index 49868b3..84af23c 100755 --- a/terraform/rtmp-server/bootstrap-post-dns.sh +++ b/terraform/rtmp-server/bootstrap-post-dns.sh @@ -17,7 +17,7 @@ systemctl stop nginx.service certbot certonly -n --agree-tos --standalone --email "${EMAIL_ADDRESS}" -d "${DOMAIN_NAME}" -d "ipfs-server.${DOMAIN_NAME}" -d "ipfs-gateway.${DOMAIN_NAME}" # Configure nginx with HTTPS -cp -f /tmp/rtmp-server/nginx-default /usr/local/nginx/conf/conf.d/default +cp -f /tmp/rtmp-server/nginx-default /usr/local/nginx/conf/conf.d/default sed -i "s#__DOMAIN_NAME__#${DOMAIN_NAME}#g" /usr/local/nginx/conf/conf.d/default cp -f /tmp/rtmp-server/nginx-gateway "/usr/local/nginx/conf/conf.d/ipfs-gateway.${DOMAIN_NAME}" From 287aace1d182546d84e33d311918e99708c7e2f0 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 22:05:09 -0400 Subject: [PATCH 26/27] Reverted spacing --- terraform/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/main.tf b/terraform/main.tf index 2c4d3cc..b7b0f5f 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -269,7 +269,7 @@ output "dns_records" { "${zipmap(digitalocean_record.ipfs-mirror-v6.*.fqdn, digitalocean_record.ipfs-mirror-v6.*.value)}", "${zipmap(digitalocean_record.ipfs-mirror-gateway-v6.*.fqdn, digitalocean_record.ipfs-mirror-gateway-v6.*.value)}", " ${digitalocean_record.publish-openvpn.fqdn} = ${digitalocean_record.publish-openvpn.value}", - " ${digitalocean_record.publish-yggdrasil.fqdn} = ${digitalocean_record.publish-yggdrasil.value}", + " ${digitalocean_record.publish-yggdrasil.fqdn} = ${digitalocean_record.publish-yggdrasil.value}", ] } output "ssh_access" { @@ -298,4 +298,4 @@ output "public_urls" { "Video player (mirror-N): https://ipfs-mirror-N.${digitalocean_domain.ipfs-live-streaming.name}", "Video player (debug): https://${digitalocean_domain.ipfs-live-streaming.name}?live=live.m3u8", ] -} \ No newline at end of file +} From a61d6e1f031c0471a95120152bcdf9d22f384d38 Mon Sep 17 00:00:00 2001 From: darkdrgn2k Date: Sat, 17 Aug 2019 22:06:47 -0400 Subject: [PATCH 27/27] removed duplicate line --- terraform/main.tf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/terraform/main.tf b/terraform/main.tf index b7b0f5f..4fa9b84 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -156,7 +156,7 @@ resource "digitalocean_droplet" "ipfs-mirror" { type = "ssh" private_key = "${file(var.pvt_key)}" timeout = "2m" - } + } " ${digitalocean_record.ipfs-server-gateway.fqdn} = ${digitalocean_record.ipfs-server-gateway.value}", provisioner "file" { source = "shared/video-player" destination = "/tmp" @@ -258,7 +258,6 @@ output "dns_records" { value = [ " ${digitalocean_domain.ipfs-live-streaming.name} = ${digitalocean_domain.ipfs-live-streaming.ip_address}", " ${digitalocean_record.rtmp-server.fqdn} = ${digitalocean_record.rtmp-server.value}", - " ${digitalocean_record.rtmp-server.fqdn} = ${digitalocean_record.rtmp-server.value}", "${zipmap(digitalocean_record.ipfs-mirror.*.fqdn, digitalocean_record.ipfs-mirror.*.value)}", "${zipmap(digitalocean_record.ipfs-mirror-gateway.*.fqdn, digitalocean_record.ipfs-mirror-gateway.*.value)}", " ${digitalocean_record.rtmp-server-private.fqdn} = ${digitalocean_record.rtmp-server-private.value}",