This commit is contained in:
Dmitriy Tillyaev 2021-08-04 09:56:06 +05:00
commit 44d4a78efa

188
tstream Executable file
View file

@ -0,0 +1,188 @@
#!/bin/sh
# Kimapr's streaming setup
# how to use:
# install ncat, lua (tested with 5.4.3), and script
# mkdir ~/stream
# make a text file ~/stream/welcome, it will be displayed on stream startup.
# make a text file ~/stream/the_end, it will be displayed on stream end.
# start the stream by running this script (see usage in the echo command below)
# after it starts you can connect via the port provided from any interface
# end the stream by exitting from the shell in the stream window
# you can also replay past streams using `scriptreplay -O live -T live-timing` in ~/stream/hist/*/
echo "usage: tstream <port> <width> <height> [max bandwidth in KiB/s (per-client)]"
port=$1
width=$2
height=$3
bandwidth=$4
if [ "x$bandwidth" = "x" ]; then
bandwidth=32
fi
randid=`head -c 16 /dev/urandom | xxd -p`
name=`date -u +%Y-%m-%d_%H-%M-%S_UTC`
tmux new-session -d -s wstream_$randid "clear;cat ~/stream/welcome;$SHELL"
tmux resize-window -t wstream_$randid -x $width -y $(($height - 1))
tmux set-option -t wstream_$randid status-right "? viewers"
cat >/tmp/tstream-helper_$randid <<EOF
#!/bin/sh
clear
TMUX= tmux attach -t wstream_$randid
clear
cat ~/stream/the_end
for i in \$(seq 7); do
echo -n .
sleep 0.1
done
echo DISCONNECT
EOF
chmod +x /tmp/tstream-helper_$randid
mkdir -p ~/stream/hist/$name
tmux new-session -d -s stream_$randid "SHELL='/tmp/tstream-helper_$randid' script -f ~/stream/hist/$name/live -T ~/stream/hist/$name/live-timing;sleep 2"
tmux resize-window -t stream_$randid -x $width -y $height
cat >/tmp/tstream-refresh_$randid <<EOF
#!/usr/bin/env lua
local file=io.popen("tmux list-clients")
local lines={}
local line=file:read()
while line do
lines[#lines+1]=line
line=file:read()
end
local clients={}
for k,v in ipairs(lines) do
local cl,sess=string.match(v,"(.-)%: (.-) ")
if sess=="wstream_$randid" then
os.execute("tmux refresh-client -t "..cl)
end
end
EOF
echo 0 > /tmp/tstream-count_$randid
vcrefresh="tmux set-option -t wstream_$randid status-right \"\$(cat /tmp/tstream-count_$randid) viewers\""
sh -c "$vcrefresh"
cat >/tmp/tstream-smarttail_$randid <<EOF
#!/usr/bin/env lua
local unpack=unpack or table.unpack
local file=io.open("$HOME/stream/hist/$name/live")
file:seek("end")
local bandwidth=$bandwidth * 1024
local checkpoints={}
local coro=coroutine.create(function()
local file=io.open("/tmp/tstream-seektimes_$randid")
while true do
local curseek=file:seek()
local endseek=file:seek("end")
local avail=endseek-curseek
file:seek("set",curseek)
if avail>0 then
local str=file:read()
local seek,t=str:match("(.-) (.+)")
seek,t=tonumber(seek),tonumber(t)
if seek and t then
table.insert(checkpoints,{seek,t})
end
else
coroutine.yield()
end
end
end)
local ct=os.time()
local count=0
local counts={}
while true do
local curseek=file:seek()
local endseek=file:seek("end")
local avail=endseek-curseek
file:seek("set",curseek)
assert(coroutine.resume(coro))
if avail>0 then
local str=file:read(math.min(avail,512))
assert(str)
io.write(str)
io.flush()
count=count+#str
local cpc=#checkpoints
local avg=0
for k,v in pairs(counts) do
avg=avg+v
end
avg=avg/#counts
if avg>bandwidth then
os.execute("clear")
print("overload! "..(avg/1024).." KiB/s > "..(bandwidth/1024).." KiB/s")
while true do
os.execute("sleep 0.1")
assert(coroutine.resume(coro))
if #checkpoints>cpc then
cpc=#checkpoints
break
end
end
local seek=checkpoints[cpc][1]
print("seeking to "..seek.."/"..file:seek("end"))
os.execute("sleep 1")
counts={}
count=0
file:seek("set",checkpoints[cpc][1]) --congestion
end
else
os.execute("sleep 0.01")
end
local tf=io.open("/tmp/tstream-death_$randid")
if tf then
tf:close()
io.stdin:close()
io.stdout:close()
return
end
local ct2=os.time()
if ct2~=ct then
ct=ct2
table.insert(counts,count)
count=0
while #counts>5 do
table.remove(counts,1)
end
end
end
EOF
chmod +x /tmp/tstream-smarttail_$randid
cat >/tmp/tstream-cat_$randid <<EOF
#!/bin/sh
vcrefresh='$vcrefresh'
echo "\$vcrefresh"
{ sleep 5;/tmp/tstream-refresh_$randid; } &
echo "Welcome to Kimapr's stream. Please wait..."
echo \$((\$(cat /tmp/tstream-count_$randid) + 1)) > /tmp/tstream-count_$randid
sh -c "\$vcrefresh"
/tmp/tstream-smarttail_$randid
echo \$((\$(cat /tmp/tstream-count_$randid) - 1)) > /tmp/tstream-count_$randid
sh -c "\$vcrefresh"
EOF
chmod +x /tmp/tstream-cat_$randid
chmod +x /tmp/tstream-refresh_$randid
touch /tmp/tstream-seektimes_$randid
{
while true; do
sleep 5
echo "$(lua -e "local file=io.open(\"$HOME/stream/hist/$name/live\")print(file:seek(\"end\")..\" \"..os.time())file:close()")" >>/tmp/tstream-seektimes_$randid
/tmp/tstream-refresh_$randid
done
} &
ncat -l -k -c "/tmp/tstream-cat_$randid" $port &
sleep 1
tmux attach -t stream_$randid
tmux kill-session -t wstream_$randid
tmux kill-session -t stream_$randid
touch /tmp/tstream-death_$randid
echo PLEASE WAIT...
sleep 2;
rm /tmp/tstream-death_$randid
rm /tmp/tstream-helper_$randid
rm /tmp/tstream-refresh_$randid
rm /tmp/tstream-cat_$randid
rm /tmp/tstream-count_$randid
rm /tmp/tstream-smarttail_$randid
rm /tmp/tstream-seektimes_$randid
kill %1
kill %2
echo exit complete