
Der Anstoss für dieses RPiOS-Projekt kam von Adafruit Quotes, das ist mehr ein Demo-Projekt für diverse Apps und Geräte. Eine deutsche Variante musste her, und auch ein bisschen strukturierter, da ich Zitat und Autor getrennt haben wollte, um gestaltungstechnisch mehr Möglichkeiten zu haben. Und ich wollte Video_looper verwenden, um die Videos automatisch abzuspielen.
Mein Feed liegt hier:http://cargologo.com/feed/quotes/data_rss.xml. Und er lässt sich auch in einen RSS-Viewer einfügen, wie NetNewsWire oder Vienna.
Das Skript lädt den Feed runter, wählt einen Eintrag zufällig aus und erstellt ein Video (anhand eines Hintergrund-Videos und einer Schrift, siehe Assets-Folder). Das Hintergrund-Video (input.mp4) bestimmt die Länge und die Bild-Grösse der erstellten Video-Datei und es könnte auch Bild-Elemente beinhalten. Meine Testumgebung hier ist das ArgonPod-Video-Case mit RPi Zero 2, der ganz gut kleine FFMPEG-Aufgaben erledigen kann, im Gegensatz zum RPi Zero 1. Die Bildschirmgrösse und die Videobildgrösse hier ist 640×480, durch entsprechende Einstellungen bei FFMPEG kann man auch HD-Videos für andere Ausgabegeräte erstellen.
Extension: mit dem Command-Argument ./quotes-rss latest kann man den letzten Eintrag forciert anzeigen lassen.
BTW: jeder andere Feed, der title- und description-entries enthält, geht natürlich auch.
#!/bin/bash
# Usage: ./quotes-rss.sh [latest]
# Home Dir
cd /home/pi/quotes-rss/
# Delete old file
#rm ./data_rss.xml* 2> /dev/null
# Download the latest quotes file
wget http://cargologo.com/feed/quotes/data_rss.xml
# Clean up old videos in video_looper Master Dir
#rm /home/pi/video/*_output.mp4 2> /dev/null
# -- Variables
newstimescreen=$(date '+%A %H-%M')
newstimefile=$(date '+%H%M%S')
modificationtime=$(stat ./data_rss.xml | grep "Modify" | sed 's/Modify:/XML Last Modified/g' | cut -c 1-29 | sed 's/:/\\:/g')
# -- Extraction
xml_file="data_rss.xml"
temp_file=$(mktemp)
# Extract quotes and authors using awk
awk '
BEGIN { RS=""; FS="\n" }
/- / {
title=""; description=""
for(i=1; i<=NF; i++) {
if ($i ~ //) {
sub(".*[ \t]*", "", $i)
sub("[ \t]*.*", "", $i)
title=$i
}
if ($i ~ //) {
sub(".*[ \t]*", "", $i)
sub("[ \t]*.*", "", $i)
gsub("", "", $i)
description=$i }
}
if (title && description) {
print title "|" description >> "'"$temp_file"'"
last_title = title
last_author = description
}
}
END {
if (last_title && last_author) {
print last_title "|" last_author > "'"$temp_file"'.latest"
}
}
' "$xml_file"
# Verify that temp_file is populated
num_items=$(wc -l < "$temp_file")
if [ "$num_items" -eq 0 ]; then
echo "No items found with both title and description."
rm "$temp_file"
exit 1
fi
# Choose latest or random quote
if [[ "$1" == "latest" ]]; then
echo "Showing latest entry..."
latest_item=$(cat "$temp_file.latest")
random_item=$latest_item
else
# Load lines from temp_file into an array
mapfile -t items < "$temp_file"
rm "$temp_file"
# Select a random item
random_index=$((RANDOM % num_items))
random_item=${items[$random_index]}
fi
# Split title and description
quote=$(echo "$random_item" | cut -d'|' -f1)
author=$(echo "$random_item" | cut -d'|' -f2)
# Format text with line breaks (2 line breaks between title & author) This is !
formatted_text=$(echo -e "$quote\n\n$author" | fold -s -w 30)
# Escape special characters and preserve newlines for ffmpeg ! This is !
# this creates \u0027
formatted_text_escaped=$(echo "$formatted_text" | sed "s/'/\\\u0027/g; s/:/\\\\:/g; s/\n/\\\x0A/g")
# create video with ffmpeg
ffmpeg -i ./Assets/input.mp4 -vf \
"drawtext=text='${formatted_text_escaped}':fontfile='./Assets/NotoSans_Condensed-Black.ttf':fontcolor=white:fontsize=42:x=10:y=20:box=1:boxcolor=black@0.5:boxborderw=15, \
drawtext=text='${modificationtime}':fontfile='./Assets/NotoSans_Condensed-Black.ttf':fontcolor=yellow:fontsize=30:x=10:y=420" \
-codec:a copy "${newstimefile}_output.mp4"
# Debug Output
echo "Formatted Text: $formatted_text_escaped"
# echo "Modification Time: $modificationtime"
# Move file to video folder
mv *_output.mp4 /home/pi/video/
Files: Download quotes-rss and Assets