mirror of
https://github.com/datarhei/restreamer.git
synced 2025-12-11 22:14:02 +01:00
237 lines
7.9 KiB
Bash
Executable File
237 lines
7.9 KiB
Bash
Executable File
#!/bin/sh
|
||
MODE=${MODE:="default"}
|
||
RS_MODE=${RS_MODE:=$MODE}
|
||
|
||
# debug reporting
|
||
RS_DEBUG=${RS_DEBUG:="false"}
|
||
if [ "$RS_DEBUG" = "true" ]; then
|
||
export FFREPORT="file=/restreamer/src/webserver/public/debug/%p-%t.log:level=48"
|
||
fi
|
||
|
||
DEVICE=${DEVICE:="default"}
|
||
|
||
if [ "$DEVICE" = "raspi" ]; then
|
||
cp ./conf/live-rpi.json ./conf/live.json
|
||
fi
|
||
|
||
echo "/opt/vc/lib" > /etc/ld.so.conf.d/00-vmcs.conf
|
||
ldconfig
|
||
|
||
CPU_TYPE=$(uname -m | cut -c 1-3)
|
||
if [ "${RS_MODE}" = "RASPICAM" ] && [ "$CPU_TYPE" = "arm" ]; then
|
||
npm start &
|
||
NGINX_RUNNING=0
|
||
until [ "$NGINX_RUNNING" = "1" ]; do
|
||
if pgrep "nginx" > /dev/null
|
||
then
|
||
NGINX_RUNNING=1
|
||
else
|
||
NGINX_RUNNING=0
|
||
sleep 5
|
||
fi
|
||
done
|
||
|
||
## options
|
||
|
||
RS_RASPICAM_INLINE=${RS_RASPICAM_INLINE:="true"}
|
||
|
||
RASPIVID_OPTIONS="--timeout 0 --nopreview"
|
||
|
||
# flip the image horizontally
|
||
if [ "$RS_RASPICAM_HFLIP" = "true" ]; then
|
||
RASPIVID_OPTIONS="$RASPIVID_OPTIONS --hflip"
|
||
fi
|
||
|
||
# flip the image vertically
|
||
if [ "$RS_RASPICAM_VFLIP" = "true" ]; then
|
||
RASPIVID_OPTIONS="$RASPIVID_OPTIONS --vflip"
|
||
fi
|
||
|
||
# inline headers (SPS, PPS) -- https://en.wikipedia.org/wiki/X264
|
||
if [ "$RS_RASPICAM_INLINE" = "true" ]; then
|
||
RASPIVID_OPTIONS="$RASPIVID_OPTIONS --inline"
|
||
fi
|
||
|
||
# video stabilization
|
||
if [ "$RS_RASPICAM_STABILIZATION" = "true" ]; then
|
||
RASPIVID_OPTIONS="$RASPIVID_OPTIONS --vstab"
|
||
fi
|
||
|
||
## FPS and GOP
|
||
|
||
RASPICAM_FPS=25
|
||
RASPICAM_GOP=50
|
||
|
||
if [ -n "$RS_RASPICAM_FPS" ]; then
|
||
RASPICAM_FPS=$RS_RASPICAM_FPS
|
||
RASPICAM_GOP=$((RASPICAM_FPS * 2))
|
||
fi
|
||
|
||
if [ -n "$RS_RASPICAM_GOP" ]; then
|
||
RASPICAM_GOP=$RASPICAM_GOP
|
||
fi
|
||
|
||
## bitrate and codec
|
||
|
||
RASPICAM_BITRATE=${RS_RASPICAM_BITRATE:=5000000}
|
||
# h264 profile: baseline (no B-frames), main, high
|
||
RASPICAM_H264PROFILE=${RS_RASPICAM_H264PROFILE:="high"}
|
||
# h264 level: 4, 4.1, 4.2 (1080p30, 720p60 and 640 × 480p60/90)
|
||
RASPICAM_H264LEVEL=${RS_RASPICAM_H264LEVEL:=4}
|
||
RASPICAM_CODEC=${RS_RASPICAM_CODEC:="H264"}
|
||
|
||
## image parameter
|
||
|
||
RASPICAM_WIDTH=${RS_RASPICAM_WIDTH:=1920}
|
||
RASPICAM_HEIGHT=${RS_RASPICAM_HEIGHT:=1080}
|
||
# -100 to 100
|
||
RASPICAM_SHARPNESS=${RS_RASPICAM_SHARPNESS:=0}
|
||
# -100 to 100
|
||
RASPICAM_CONTRAST=${RS_RASPICAM_CONTRAST:=0}
|
||
# 0 to 100
|
||
RASPICAM_BRIGHTNESS=${RS_RASPICAM_BRIGHTNESS:=50}
|
||
# -100 to 100
|
||
RASPICAM_SATURATION=${RS_RASPICAM_SATURATION:=0}
|
||
|
||
## image quality and effects
|
||
|
||
# capture ISO
|
||
RASPICAM_ISO=${RS_RASPICAM_ISO:=0}
|
||
# quantization parameter
|
||
RASPICAM_QP=${RS_RASPICAM_QP:=0}
|
||
# EV compensation, steps of 1/6 stop
|
||
RASPICAM_EV=${RS_RASPICAM_EV:=0}
|
||
# exposure: off,auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks
|
||
RASPICAM_EXPOSURE=${RS_RASPICAM_EXPOSURE:="auto"}
|
||
# flicker filter: off,auto,50hz,60hz
|
||
RASPICAM_FLICKER=${RS_RASPICAM_FLICKER:="off"}
|
||
# white balance: off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon
|
||
RASPICAM_AWB=${RS_RASPICAM_AWB:="auto"}
|
||
# image effects: none,negative,solarise,sketch,denoise,emboss,oilpaint,hatch,gpen,pastel,watercolour,film,blur,saturation,colourswap,washedout,posterise,colourpoint,colourbalance,cartoon
|
||
RASPICAM_IMXFX=${RS_RASPICAM_IMXFX:="none"}
|
||
# metering: average,spot,backlit,matrix
|
||
RASPICAM_METERING=${RS_RASPICAM_METERING:="average"}
|
||
# dynamic range compression: off,low,med,high
|
||
RASPICAM_DRC=${RS_RASPICAM_DRC:="off"}
|
||
|
||
## audio
|
||
|
||
RASPICAM_AUDIODEVICE=${RS_RASPICAM_AUDIODEVICE:="0"}
|
||
RASPICAM_AUDIOBITRATE=${RS_RASPICAM_AUDIOBITRATE:="0"}
|
||
RASPICAM_AUDIOCHANNELS=${RS_RASPICAM_AUDIOCHANNELS:="1"}
|
||
RASPICAM_AUDIOLAYOUT=${RS_RASPICAM_AUDIOLAYOUT:="mono"}
|
||
RASPICAM_AUDIOSAMPLING=${RS_RASPICAM_AUDIOSAMPLING:="44100"}
|
||
|
||
RASPICAM_AUDIO="-f lavfi -i anullsrc=r=${RASPICAM_AUDIOSAMPLING}:cl=${RASPICAM_AUDIOLAYOUT}"
|
||
|
||
if [ "$RS_RASPICAM_AUDIO" = "true" ]; then
|
||
RASPICAM_AUDIO="-thread_queue_size 512 -f alsa -ac ${RASPICAM_AUDIOCHANNELS} -ar ${RASPICAM_AUDIOSAMPLING} -i hw:${RASPICAM_AUDIODEVICE}"
|
||
RASPICAM_AUDIOBITRATE=${RS_RASPICAM_AUDIOBITRATE:="64000"}
|
||
fi
|
||
|
||
RASPICAM_AUDIOBITRATE=$(($RASPICAM_AUDIOBITRATE / 1024))
|
||
|
||
## RTMP URL
|
||
|
||
RTMP_URL="rtmp://127.0.0.1:1935/live/raspicam.stream"
|
||
|
||
if [ -n "$RS_TOKEN" ]; then
|
||
RTMP_URL="${RTMP_URL}?token=${RS_TOKEN}"
|
||
fi
|
||
|
||
/opt/vc/bin/raspivid \
|
||
$RASPIVID_OPTIONS \
|
||
--width "$RASPICAM_WIDTH" \
|
||
--height "$RASPICAM_HEIGHT" \
|
||
--framerate "$RASPICAM_FPS" \
|
||
--bitrate "$RASPICAM_BITRATE" \
|
||
--intra "$RASPICAM_GOP" \
|
||
--codec "$RASPICAM_CODEC" \
|
||
--profile "$RASPICAM_H264PROFILE" \
|
||
--level "$RASPICAM_H264LEVEL" \
|
||
--sharpness "$RASPICAM_SHARPNESS" \
|
||
--contrast "$RASPICAM_CONTRAST" \
|
||
--brightness "$RASPICAM_BRIGHTNESS" \
|
||
--saturation "$RASPICAM_SATURATION" \
|
||
--ISO "$RASPICAM_ISO" \
|
||
--qp "$RASPICAM_QP" \
|
||
--exposure "$RASPICAM_EXPOSURE" \
|
||
--flicker "$RASPICAM_FLICKER" \
|
||
--awb "$RASPICAM_AWB" \
|
||
--imxfx "$RASPICAM_IMXFX" \
|
||
--metering "$RASPICAM_METERING" \
|
||
--drc "$RASPICAM_DRC" \
|
||
-o - | ffmpeg -framerate "$RASPICAM_FPS" -i - ${RASPICAM_AUDIO} -map 0:v -map 1:a -codec:v copy -codec:a aac -b:a "${RASPICAM_AUDIOBITRATE}k" -shortest -f flv "${RTMP_URL}" > /dev/null 2>&1
|
||
elif [ "${RS_MODE}" = "USBCAM" ]; then
|
||
npm start &
|
||
NGINX_RUNNING=0
|
||
until [ "$NGINX_RUNNING" = "1" ]; do
|
||
if pgrep "nginx" > /dev/null
|
||
then
|
||
NGINX_RUNNING=1
|
||
else
|
||
NGINX_RUNNING=0
|
||
sleep 5
|
||
fi
|
||
done
|
||
|
||
# https://trac.ffmpeg.org/wiki/Capture/Webcam
|
||
# https://www.ffmpeg.org/ffmpeg-devices.html#video4linux2_002c-v4l2
|
||
# https://trac.ffmpeg.org/wiki/Capture/ALSA
|
||
# https://ffmpeg.org/ffmpeg-devices.html#alsa
|
||
|
||
USBCAM_VIDEODEVICE=${RS_USBCAM_VIDEODEVICE:="/dev/video"}
|
||
USBCAM_AUDIODEVICE=${RS_USBCAM_AUDIODEVICE:="0"}
|
||
|
||
USBCAM_FPS=25
|
||
USBCAM_GOP=50
|
||
|
||
if [ -n "$RS_USBCAM_FPS" ]; then
|
||
USBCAM_FPS=$RS_USBCAM_FPS
|
||
USBCAM_GOP=$((USBCAM_FPS * 2))
|
||
fi
|
||
|
||
if [ -n "$RS_USBCAM_GOP" ]; then
|
||
USBCAM_GOP=$USBCAM_GOP
|
||
fi
|
||
|
||
USBCAM_BITRATE=${RS_USBCAM_BITRATE:=5000000}
|
||
USBCAM_H264PRESET=${RS_USBCAM_H264PRESET:="ultrafast"}
|
||
USBCAM_H264PROFILE=${RS_USBCAM_H264PROFILE:="baseline"}
|
||
USBCAM_WIDTH=${RS_USBCAM_WIDTH:=1280}
|
||
USBCAM_HEIGHT=${RS_USBCAM_HEIGHT:=720}
|
||
|
||
USBCAM_BITRATE=$(($USBCAM_BITRATE / 1024))
|
||
USBCAM_BUFFER=$(($USBCAM_BITRATE * 2))
|
||
|
||
RTMP_URL="rtmp://127.0.0.1:1935/live/usbcam.stream"
|
||
|
||
if [ -n "$RS_TOKEN" ]; then
|
||
RTMP_URL="${RTMP_URL}?token=${RS_TOKEN}"
|
||
fi
|
||
|
||
USBCAM_VIDEOENCODER="-codec:v libx264 -preset:v ${USBCAM_H264PRESET} -vf format=yuv420p"
|
||
|
||
if [ "$DEVICE" = "raspi" ]; then
|
||
USBCAM_VIDEOENCODER="-codec:v h264_omx -profile:v ${USBCAM_H264PROFILE}"
|
||
fi
|
||
|
||
USBCAM_AUDIOBITRATE=${RS_USBCAM_AUDIOBITRATE:="0"}
|
||
USBCAM_AUDIOCHANNELS=${RS_USBCAM_AUDIOCHANNELS:="1"}
|
||
USBCAM_AUDIOLAYOUT=${RS_USBCAM_AUDIOLAYOUT:="mono"}
|
||
USBCAM_AUDIOSAMPLING=${RS_USBCAM_AUDIOSAMPLING:="44100"}
|
||
|
||
USBCAM_AUDIO="-f lavfi -i anullsrc=r=${USBCAM_AUDIOSAMPLING}:cl=${USBCAM_AUDIOLAYOUT}"
|
||
|
||
if [ "$RS_USBCAM_AUDIO" = "true" ]; then
|
||
USBCAM_AUDIO="-thread_queue_size 512 -f alsa -ac ${USBCAM_AUDIOCHANNELS} -ar ${USBCAM_AUDIOSAMPLING} -i hw:${USBCAM_AUDIODEVICE}"
|
||
USBCAM_AUDIOBITRATE=${RS_USBCAM_AUDIOBITRATE:="64000"}
|
||
fi
|
||
|
||
USBCAM_AUDIOBITRATE=$(($USBCAM_AUDIOBITRATE / 1024))
|
||
|
||
ffmpeg -thread_queue_size 512 -f v4l2 -framerate "$USBCAM_FPS" -video_size "${USBCAM_WIDTH}x${USBCAM_HEIGHT}" -i "${USBCAM_VIDEODEVICE}" ${USBCAM_AUDIO} -map 0:v -map 1:a ${USBCAM_VIDEOENCODER} -r "$USBCAM_FPS" -g "${USBCAM_GOP}" -b:v "${USBCAM_BITRATE}k" -bufsize "${USBCAM_BUFFER}k" -codec:a aac -b:a "${USBCAM_AUDIOBITRATE}k" -shortest -f flv "${RTMP_URL}" > /dev/null 2>&1
|
||
else
|
||
npm start
|
||
fi
|