Work in progress. Most of concept fleshed out
This commit is contained in:
parent
01e4803ac5
commit
7be5c09934
|
@ -0,0 +1,4 @@
|
||||||
|
.env
|
||||||
|
videos
|
||||||
|
input
|
||||||
|
*.sqlite
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Bash TV
|
||||||
|
|
||||||
|
A simple RTMP streaming TV station in Bash.
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
* Bash
|
||||||
|
* ffmpeg
|
||||||
|
* sqlite3
|
||||||
|
|
||||||
|
### Scripts
|
||||||
|
|
||||||
|
#### tv.sh
|
||||||
|
|
||||||
|
This script runs the TV station by looping over a collection of files in a directory and playing them randomly until they have all been played one time.
|
||||||
|
|
||||||
|
|
||||||
|
#### encode.sh
|
||||||
|
|
||||||
|
This script can be run on a cronjob to detect new video files and re-encode them for playback in the tv station.
|
||||||
|
|
||||||
|
|
||||||
|
#### .env
|
||||||
|
|
||||||
|
This configuration file contains the environment variables that are used by the other scripts to operate the streaming station.
|
||||||
|
|
||||||
|
#### common.sh
|
||||||
|
|
||||||
|
Script containing common helper functions and environment configuration scripts used between the `tv.sh` and `encode.sh` scripts.
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
cp default.env .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
source .env
|
||||||
|
|
||||||
|
if [ ! -d "${INPUT}" ]; then
|
||||||
|
mkdir -p "${INPUT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "${VIDEOS}" ]; then
|
||||||
|
mkdir -p "${VIDEOS}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
HISTORY_SETUP="CREATE TABLE IF NOT EXISTS history (
|
||||||
|
video VARCHAR PRIMARY KEY,
|
||||||
|
playcount INT DEFAULT 0,
|
||||||
|
last INT
|
||||||
|
)"
|
||||||
|
|
||||||
|
PLAYBACK_SETUP="CREATE TABLE IF NOT EXISTS playback (
|
||||||
|
video VARCHAR PRIMARY KEY
|
||||||
|
)"
|
||||||
|
|
||||||
|
SetupHistory () {
|
||||||
|
echo "${HISTORY_SETUP}" | sqlite3 "${HISTORY}"
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupPlayback () {
|
||||||
|
echo "${PLAYBACK_SETUP}" | sqlite3 "${PLAYBACK}"
|
||||||
|
}
|
||||||
|
|
||||||
|
WipePlayback () {
|
||||||
|
rm -f "${PLAYBACK}"
|
||||||
|
}
|
||||||
|
|
||||||
|
PDB () {
|
||||||
|
sqlite3 "${PLAYBACK}" "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
HDB () {
|
||||||
|
sqlite3 "${HISTORY}" "${1}"
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
WIDTH=720
|
||||||
|
HEIGHT=480
|
||||||
|
BUG=""
|
||||||
|
PLAYBACK="playback.sqlite"
|
||||||
|
HISTORY="history.sqlite"
|
||||||
|
VIDEOS="./videos"
|
||||||
|
INPUT="./input"
|
||||||
|
DESTINATION="rtmp://localhost/live"
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source ./common.sh
|
||||||
|
|
||||||
|
count=$(ls -1 "${INPUT}/" | wc -l)
|
||||||
|
|
||||||
|
if [ ${count} == 0 ]; then
|
||||||
|
echo "No files to process"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCALE="scale=${WIDTH}:${HEIGHT}:force_original_aspect_ratio=decrease,pad=${WIDTH}:${HEIGHT}:(ow-iw)/2:(oh-ih)/2"
|
||||||
|
|
||||||
|
Encode () {
|
||||||
|
name=$(basename "${1}")
|
||||||
|
nameNoExt=${name%.*}
|
||||||
|
now=$(date '+%s')
|
||||||
|
output="${VIDEOS}/${nameNoExt}_${now}.flv"
|
||||||
|
if [ -f "${VIDEOS}/${nameNoExt}"*".flv" ]; then
|
||||||
|
echo "File ${name} already exists"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "Encoding ${name}..."
|
||||||
|
ffmpeg -i "${1}" -c:v libx264 -tune zerolatency -pix_fmt yuv420p -vf "${SCALE}" \
|
||||||
|
-c:a aac -b:a 190k -ac 2 -ar 44100 \
|
||||||
|
-f flv "${output}"
|
||||||
|
}
|
||||||
|
|
||||||
|
fileList=$(mktemp)
|
||||||
|
|
||||||
|
ls -1 "${INPUT}/" > "${fileList}"
|
||||||
|
|
||||||
|
while read videoIn; do
|
||||||
|
Encode "${INPUT}/${videoIn}"
|
||||||
|
done < "${fileList}"
|
||||||
|
|
||||||
|
rm -f "${fileList}"
|
43
tv.sh
43
tv.sh
|
@ -1,10 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
WIDTH=720
|
set -e
|
||||||
HEIGHT=480
|
|
||||||
BUG=""
|
source ./common.sh
|
||||||
PLAYBACK="playback.sqlite"
|
|
||||||
HISTORY="history.sqlite"
|
|
||||||
|
|
||||||
# Steps : enumerate all files at beginning of every playback decision
|
# Steps : enumerate all files at beginning of every playback decision
|
||||||
# Compare to files in folder
|
# Compare to files in folder
|
||||||
|
@ -16,4 +14,37 @@ HISTORY="history.sqlite"
|
||||||
# add to playback database
|
# add to playback database
|
||||||
# add to history database
|
# add to history database
|
||||||
# start playback
|
# start playback
|
||||||
#
|
#
|
||||||
|
|
||||||
|
Play () {
|
||||||
|
ffmpeg -threads 1 -re -i "${1}" -c copy -f flv "${DESTINATION}"
|
||||||
|
}
|
||||||
|
|
||||||
|
AllFiles () {
|
||||||
|
fileList=$(mktemp)
|
||||||
|
ls -1 "${VIDEOS}/"*.flv > "${fileList}"
|
||||||
|
echo "${fileList}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SetupHistory
|
||||||
|
SetupPlayback
|
||||||
|
|
||||||
|
last=""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
files=$(AllFiles)
|
||||||
|
fileCount=$(cat "${files}" | wc -l)
|
||||||
|
playbackCount=$(PDB "SELECT COUNT(*) FROM playback")
|
||||||
|
echo $playbackCount
|
||||||
|
|
||||||
|
if [ ${fileCount} -eq 0 ]; then
|
||||||
|
echo "No files to play :("
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
WipePlayback
|
||||||
|
|
Loading…
Reference in New Issue