/
stream.sh
executable file
·127 lines (108 loc) · 6.3 KB
/
stream.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/bin/bash
# Script for live DASH/HLS streaming lossy audio as AAC and/or archiving lossless audio as FLAC
# Exit immediately if any command exits with non zero status
set -e
function fail {
printf '%s\n' "$1" >&2 ## Send message to stderr. Exclude >&2 if you don't want it that way.
printf "mandatory env variable not set, exiting now" >&2
exit "${2-1}" ## Return a code specified by $2 or 1 by default.
}
#
# Check for all enviorment variables and fail if mandatory ones are not set
#
if [ -z ${NODE_NAME+x} ]; then fail "NODE_NAME is unset"; else echo "node name is set to '$NODE_NAME'"; fi
if [ -z ${SAMPLE_RATE+x} ]; then fail "SAMPLE_RATE is unset"; else echo "sample rate is set to '$SAMPLE_RATE'"; fi
if [ -z ${AUDIO_HW_ID+x} ]; then fail "AUDIO_HW_ID is unset"; else echo "sound card is set to '$AUDIO_HW_ID'"; fi
if [ -z ${CHANNELS+x} ]; then fail "CHANNELS is unset"; else echo "Number of audio channels is set to '$CHANNELS'"; fi
if [ -z ${NODE_TYPE+x} ]; then fail "NODE_TYPE is unset"; else echo "node type is set to '$NODE_TYPE'"; fi
if [ -z ${STREAM_RATE+x} ]; then fail "STREAM_RATE is unset"; else echo "stream rate is set to '$STREAM_RATE'"; fi
if [ -z ${SEGMENT_DURATION+x} ]; then fail "SEGMENT_DURATION is unset"; else echo "segment duration is set to '$SEGMENT_DURATION'"; fi
if [ -z ${NODE_ARCH+x} ]; then fail "NODE_ARCH is unset"; else echo "node architecture is set to '$NODE_ARCH'"; fi
if [ -z ${NODE_LOOPBACK+x} ]; then echo "NODE_LOOPBACK is unset"; else echo "node loopback is set to '$NODE_LOOPBACK'"; fi
# Get current timestamp
timestamp=$(date +%s)
#### Set up local output directories
mkdir -p /tmp/$NODE_NAME
mkdir -p /tmp/$NODE_NAME/flac
mkdir -p /tmp/$NODE_NAME/hls
mkdir -p /tmp/$NODE_NAME/hls/$timestamp
#mkdir -p /tmp/$NODE_NAME/dash
#mkdir -p /tmp/$NODE_NAME/dash/$timestamp
#ln /tmp/$NODE_NAME/dash/$timestamp /tmp/dash_output_dir
# Output timestamp for this (latest) stream
echo $timestamp > /tmp/$NODE_NAME/latest.txt
# Setup jack
if [ $NODE_ARCH = "arm32v7" ]; then
echo @audio - memlock 256000 >> /etc/security/limits.conf
echo @audio - rtprio 75 >> /etc/security/limits.co
JACK_NO_AUDIO_RESERVATION=1 jackd -t 2000 -P 75 -d alsa -d hw:$AUDIO_HW_ID -r $SAMPLE_RATE -p 1024 -n 10 -s &
fi
#### Generate stream segments and manifests, and/or lossless archive
echo "Node started at $timestamp"
echo "Node is named $NODE_NAME and is of type $NODE_TYPE"
## NODE_TYPE set in .env filt to one of: "research"; "debug" (DASH-only); "hls-only"; or default (FLAC+HLS+DASH)
if [ $NODE_TYPE = "research" ]; then
#SAMPLE_RATE=192000
## Setup Jack Audio outside for now
# sudo echo @audio - memlock 256000 >> /etc/security/limits.conf
# sudo echo @audio - rtprio 75 >> /etc/security/limits.co
# sudo JACK_NO_AUDIO_RESERVATION=1 jackd -t 2000 -P 75 -d alsa -d hw:pisound -r 192000 -p 1024 -n 10 -s
echo "Sampling $CHANNELS channels from $AUDIO_HW_ID at $SAMPLE_RATE Hz with bitrate of 32 bits/sample..."
echo "Asking ffmpeg to write $FLAC_DURATION second $SAMPLE_RATE Hz FLAC files..."
## Streaming HLS with FLAC archive
nice -n -10 ffmpeg -f jack -i ffjack \
-f segment -segment_time "00:00:$FLAC_DURATION.00" -strftime 1 "/tmp/$NODE_NAME/flac/%Y-%m-%d_%H-%M-%S_$NODE_NAME-$SAMPLE_RATE-$CHANNELS.flac" \
-f segment -segment_list "/tmp/$NODE_NAME/hls/$timestamp/live.m3u8" -segment_list_flags +live -segment_time $SEGMENT_DURATION -segment_format \
mpegts -ar $STREAM_RATE -ac 2 -acodec aac "/tmp/$NODE_NAME/hls/$timestamp/live%03d.ts" >/dev/null 2>/dev/null &
elif [ $NODE_TYPE = "debug" ]; then
echo "Sampling $CHANNELS channels from $AUDIO_HW_ID at $SAMPLE_RATE Hz with bitrate of 32 bits/sample..."
echo "Asking ffmpeg to stream DASH via mpegts at $STREAM_RATE Hz..."
## Streaming DASH only via mpegts
nice -n -10 ffmpeg -t 0 -f jack -i ffjack -f mpegts udp://127.0.0.1:1234 &
#### Stream with test engine live tools
## May need to adjust segment length in config_audio.json to match $SEGMENT_DURATION...
nice -n -7 ./test-engine-live-tools/bin/live-stream -c ./config_audio.json udp://127.0.0.1:1234 &
elif [ $NODE_TYPE = "hls-only" ]; then
echo "Sampling $CHANNELS channels from $AUDIO_HW_ID at $SAMPLE_RATE Hz..."
echo "Asking ffmpeg to stream only HLS segments at $STREAM_RATE Hz......"
## Streaming HLS only via mpegts
if [ $NODE_ARCH = "arm32v7" ]; then
## rpi, jack
nice -n -10 ffmpeg -f jack -i ffjack -f segment -segment_list "/tmp/$NODE_NAME/hls/$timestamp/live.m3u8" -segment_list_flags +live -segment_time $SEGMENT_DURATION -segment_format mpegts -ar $STREAM_RATE -ac $CHANNELS -threads 3 -acodec aac "/tmp/$NODE_NAME/hls/$timestamp/live%03d.ts" &
else
## amd64 alsa
nice -n -10 ffmpeg -f alsa -ac 2 -ar $SAMPLE_RATE -thread_queue_size 1024 -i hw:$AUDIO_HW_ID -f segment -segment_list "/tmp/$NODE_NAME/hls/$timestamp/live.m3u8" -segment_list_flags +live -segment_time $SEGMENT_DURATION -segment_format mpegts -ar $STREAM_RATE -ac $CHANNELS -threads 3 -acodec aac "/tmp/$NODE_NAME/hls/$timestamp/live%03d.ts" &
fi
elif [ $NODE_TYPE = "dev-virt-s3" ]; then
SAMPLE_RATE=48000
STREAM_RATE=48000
echo "Sampling from $AUDIO_HW_ID at $SAMPLE_RATE Hz..."
echo "Asking ffmpeg to stream only HLS segments at $STREAM_RATE Hz......"
## Streaming HLS only via mpegts
nice -n -10 ffmpeg -re -fflags +genpts -stream_loop -1 -i "samples/haro-strait_2005.wav" \
-f segment -segment_list "/tmp/$NODE_NAME/hls/$timestamp/live.m3u8" -segment_list_flags +live -segment_time $SEGMENT_DURATION -segment_format mpegts \
-ar $STREAM_RATE -ac $CHANNELS -threads 3 -acodec aac "/tmp/$NODE_NAME/hls/$timestamp/live%03d.ts" &
else
echo "unsupported please pick hls-only, research, or dev-virt-s3"
fi
# takes a second for ffmpeg to make ffjack connection before we can connect
if [ $NODE_ARCH = "arm32v7" ]; then
sleep 3
jack_connect system:capture_1 ffjack:input_1
jack_connect system:capture_2 ffjack:input_2
fi
if [ $NODE_LOOPBACK = "true" ]; then
jack_connect system:capture_1 system:playback_1
jack_connect system:capture_2 system:playback_2
fi
if [ $NODE_LOOPBACK = "hls" ]; then
sleep 20
ffplay -nodisp /tmp/$NODE_NAME/hls/$timestamp/live.m3u8
fi
if [ $NODE_TYPE = "research" ]; then
python3 upload_s3.py &
python3 upload_flac_s3.py
else
python3 upload_s3.py
fi
echo "all done"