TODO: Activate IPFS Video/Audio Streaming

This commit is contained in:
fred 2022-11-06 00:46:59 +01:00
parent 1aa295e77b
commit 13b295419f
6 changed files with 265 additions and 0 deletions

BIN
tools/streaming/audio.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

96
tools/streaming/install.sh Executable file
View File

@ -0,0 +1,96 @@
#!/usr/bin/env bash
########################################################################
exit 0
########################################################################
### REWRITE NEEDED
########################################################################
set -e
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Enable camera on the Raspberry Pi
# sudo "$BASE_DIR/enable-camera.sh"
# Install ffmpeg and supporting tools
sudo apt-get install -y ffmpeg lsof inotify-tools nginx
# Copy placeholder for audio-only streams
cp "$BASE_DIR/audio.jpg" "$HOME/audio.jpg"
# Add user to be able to modify nginx directories
sudo usermod -a -G "$USER" www-data
sudo chmod g+rw /var/www/html
# TODO: why is this needed?
sudo chmod a+rw /var/www/html
sudo cp -f "$BASE_DIR/process-stream.sh" /usr/bin/process-stream.sh
sudo cp -f "$BASE_DIR/process-stream.service" /etc/systemd/system/process-stream.service
sudo systemctl daemon-reload
sudo systemctl enable process-stream
# Add hourly job to clear out old data
# echo "41 * * * * $USER /usr/local/bin/ipfs repo gc" | sudo tee --append /etc/crontab
# Install the ipfs video player
mkdir "$BASE_DIR/tmp"
current_dir="$(pwd)"
git clone https://github.com/tomeshnet/ipfs-live-streaming.git "$BASE_DIR/tmp/ipfs-live-streaming"
cd "$BASE_DIR/tmp/ipfs-live-streaming"
git checkout b9be352582317e5336ddd7183ecf49042dafb33e
cd "$current_dir"
VIDEO_PLAYER_PATH="$BASE_DIR/tmp/ipfs-live-streaming/terraform/shared/video-player"
sed -i s#__IPFS_GATEWAY_SELF__#/ipfs/# "$VIDEO_PLAYER_PATH/js/common.js"
sed -i s#__IPFS_GATEWAY_ORIGIN__#https://ipfs.io/ipfs/# "$VIDEO_PLAYER_PATH/js/common.js"
IPFS_ID=$(ipfs id | grep ID | head -n 1 | awk -F\" '{print $4}')
sed -i "s#live.m3u8#/ipns/$IPFS_ID#" "$VIDEO_PLAYER_PATH/js/common.js"
sed -i s#__M3U8_HTTP_URLS__#\ # "$VIDEO_PLAYER_PATH/js/common.js"
cp -r "$VIDEO_PLAYER_PATH" /var/www/html/video-player
rm -rf "$BASE_DIR/tmp"
# Add entry into nginx home screen
APP="<div class='app'><h2>IPFS Pi Stream Player</h2>IPFS Video player for Pi Stream. <br />M3U8 Stream located <a href='/ipns/$IPFS_ID'>over ipns</a> <br/><a href='/video-player/'>Go </a> and play with built in video player</div>"
sudo sed -i "s#<\!--APPLIST-->#$APP\n<\!--APPLIST-->#" "/var/www/html/index.html"
## ACTIVATE nginx rtmp
# GUIDES
# https://bartsimons.me/nginx-rtmp-streaming-server-installation-guide/
# https://blog.100tb.com/how-to-set-up-an-rtmp-server-on-ubuntu-linux-using-nginx
# https://obsproject.com/forum/resources/how-to-set-up-your-own-private-rtmp-server-using-nginx.50/
# https://www.hostwinds.com/guide/live-streaming-from-a-vps-with-nginx-rtmp/
# CONFIG
# https://github.com/arut/nginx-rtmp-module/wiki/Directives
# https://github.com/arut/nginx-rtmp-module/wiki/Directives#hls_variant
printf "
rtmp {
server {
listen 1935;
chunk_size 8192;
application vod {
play $HOME/live;
}
application stream {
live on;
record off;
allow publish 127.0.0.1;
deny publish all;
allow play all;
}
application src {
live on;
exec_push ffmpeg -i rtmp://localhost/src/$name -vcodec libx264 -vprofile baseline -g 10 -s 300x200 -acodec aac -ar 44100 -ac 1 -f flv rtmp://localhost/hls/$name 2>>/var/log/ffmpeg-$name.log;
}
}
}
" | sudo tee -a /etc/nginx/nginx.conf

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@ -0,0 +1,16 @@
[Unit]
Description=Service to process RTMP stream
Wants=network.target
After=ipfs.service
[Service]
Type=simple
User=pi
Group=pi
ExecStart=/usr/bin/process-stream.sh
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target

134
tools/streaming/process-stream.sh Executable file
View File

@ -0,0 +1,134 @@
#!/usr/bin/env bash
HLS_TIME=40
M3U8_SIZE=3
IPFS_GATEWAY="http://127.0.0.1:8080"
echo "Astroport stream is playing on star_1 : https://tube.copylaradio.com/ipns/$(ipfs key list -l | grep star_1 | cut -d ' ' -f 1)"
# Load settings
# Prepare Pi Camera
# sudo modprobe bcm2835-v4l2
# sudo v4l2-ctl --set-ctrl video_bitrate=100000
function startFFmpeg() {
while true; do
mv /tmp/ffmpeg.log /tmp/ffmpeg.1
echo 1 > /tmp/stream-reset
# Stream WebCamera
#ffmpeg -f pulse -i 1 -f video4linux2 -video_size 1280x720 -framerate 25 -i /dev/video0 -hls_time "${HLS_TIME}" "${what}.m3u8" > /tmp/ffmpeg.log 2>&1
ffmpeg -f pulse -i 1 -f video4linux2 -video_size 720x480 -framerate 25 -i /dev/video0 -hls_time "${HLS_TIME}" "${what}.m3u8" > /tmp/ffmpeg.log 2>&1
## MORE SOURCES
# http://4youngpadawans.com/stream-camera-video-and-audio-with-ffmpeg/
## STILL BAD :: ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 -profile:v high -pix_fmt yuvj420p -level:v 4.1 -preset ultrafast -tune zerolatency -vcodec libx264 -r 10 -b:v 512k -s 640x360 -acodec aac -strict -2 -ac 2 -ab 32k -ar 44100 -f mpegts -flush_packets 0 -hls_time "${HLS_TIME}" "${what}.m3u8" > /tmp/ffmpeg.log 2>&1
################ GOOD ?
# Stream FM Station from a SDR module (see contrib/pi-stream to install drivers)
# Frequency ends in M IE 99.9M
# rtl_fm -f 99.9M -M fm -s 170k -A std -l0 -E deemp -r 44.1k | ffmpeg -r 15 -loop 1 -i ../audio.jpg -f s16le -ac 1 -i pipe:0 -c:v libx264 -tune stillimage -preset ultrafast -hls_time "${HLS_TIME}" "${what}.m3u8" > /tmp/ffmpeg 2>&1
sleep 0.5
done
}
# Create directory for HLS content
currentpath="$HOME/live"
sudo umount "${currentpath}"
rm -rf "${currentpath}"
mkdir "${currentpath}"
sudo mount -t tmpfs tmpfs "${currentpath}"
# shellcheck disable=SC2164
cd "${currentpath}"
what="$(date +%Y%m%d%H%M)-LIVE"
echo "STARTING $what"
# Start ffmpeg in background
startFFmpeg &
while true; do
#TODO# Fix this one
# shellcheck disable=SC2086,SC2012
nextfile=$(ls -tr ${what}*.ts 2>/dev/null | head -n 1)
if [ -n "${nextfile}" ]; then
# Check if the next file on the list is still being written to by ffmpeg
if lsof "${nextfile}" | grep -1 ffmpeg; then
# Wait for file to finish writing
# If not finished in 45 seconds something is wrong, timeout
inotifywait -e close_write "${nextfile}" -t ${HLS_TIME}
fi
# 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 /tmp/stream-reset)
reset_stream_marker=''
if [[ ${reset_stream} -eq '1' ]]; then
reset_stream_marker=" #EXT-X-DISCONTINUITY"
fi
echo 0 > /tmp/stream-reset
# Current UTC date for the log
time=$(date "+%F-%H-%M-%S")
echo "Add ts file to IPFS"
ret=$(ipfs add --pin=false "${nextfile}" 2>/dev/null > /tmp/tmp.txt; echo $?)
attempts=5
until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do
# Wait and retry
sleep 0.5
ret=$(ipfs add --pin=false "${nextfile}" 2>/dev/null > /tmp/tmp.txt; echo $?)
echo "$attempts RETRY"
attempts=$((attempts-1))
done
if [[ ${ret} -eq 0 ]]; then
# Update the log with the future name (hash already there)
echo "$(cat /tmp/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker}" >> /tmp/process-stream.log
# Remove nextfile and tmp.txt
rm -f "${nextfile}" /tmp/tmp.txt
# Write the m3u8 file with the new IPFS hashes from the log
totalLines="$(wc -l /tmp/process-stream.log | awk '{print $1}')"
sequence=0
if ((totalLines>M3U8_SIZE)); then
sequence=$((totalLines-M3U8_SIZE))
fi
{
echo "#EXTM3U"
echo "#EXT-X-VERSION:3"
echo "#EXT-X-TARGETDURATION:${HLS_TIME}"
echo "#EXT-X-MEDIA-SEQUENCE:${sequence}"
} > current.m3u8
tail -n ${M3U8_SIZE} /tmp/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
echo 'Add m3u8 file to IPFS and IPNS publish'
m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}')
ipfs name publish --key='star_1' --timeout=5s "${m3u8hash}" &
# Copy files to web server
cat current.m3u8
# cp current.m3u8 /var/www/html/live.m3u8
# cp /tmp/process-stream.log /var/www/html/live.log
fi
else
sleep 5
fi
done

19
tools/streaming/uninstall.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
## TO CONTROL & REWRITE
exit 0
set -e
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
sudo systemctl stop process-stream
sudo systemctl disable process-stream
sudo rm -f /usr/bin/process-stream.sh
sudo rm -f /etc/systemd/system/process-stream.service
sudo systemctl daemon-reload
# Remove ffmpeg and supporting tools
sudo apt-get -y remove ffmpeg lsof inotify-tools
# Revert permissions
sudo chmod 755 /var/www/html
sed -i "/ipfs repo gc/d" | sudo tee --append /etc/crontab