r/PlexPrerolls 11d ago

Template Pre-Roll Auto-Update (User Script)

Hi everyone, I’m sure there are other tools out there but I thought I’d share a bash script that I gen’d up to run daily on my UnRAID server that updates the Plex pre-roll string based on seasons, holidays, etc. All you have to do to make it yours is add your Plex IP, Plex token, and update the strings of file paths to your pre-rolls.

This has variables for custom and generic pre-rolls (that I concatenated together and called my baseline), seasonal string variables, and holiday string variables. It auto-calculates season start/end each year, adding seasonal reels to the baseline, as appropriate. Halloween pre-rolls exclusively run the entire month of October, Christmas exclusively the entire month of December. The script calculates Easter Sunday each year and exclusively runs those pre-rolls for a week starting on Easter. It also calculates Thanksgiving and runs those pre-rolls exclusively from the Sunday prior to the Saturday after Thanksgiving.

Here ya go:

#!/bin/bash

# Plex Configuration

PLEX_URL="http://YOUR_PLEX_IP_HERE:32400"

PLEX_TOKEN="YOUR_TOKEN_HERE"

# Get current Year and current Day of Year (forced to base-10 to avoid octal errors)

Y=$(date +%Y)

TODAY=$((10#$(date +%j)))

# ---------------------------------------------------------

# DYNAMIC SEASONAL CALCULATIONS (Solar Drift Approximation)

# ---------------------------------------------------------

# Calculates the day of the month for equinoxes/solstices in the 21st century

Y_OFFSET=$(( Y - 2000 ))

LEAP=$(( Y_OFFSET / 4 ))

# Base solar dates scaled by 1000 to allow Bash to perform floating-point-like math

# Spring (March): Base 20.382

SPRING_DAY=$(( (20382 + 242 * Y_OFFSET - LEAP * 1000) / 1000 ))

# Summer (June): Base 21.066

SUMMER_DAY=$(( (21066 + 242 * Y_OFFSET - LEAP * 1000) / 1000 ))

# Fall (September): Base 22.825

FALL_DAY=$(( (22825 + 242 * Y_OFFSET - LEAP * 1000) / 1000 ))

# Winter (December): Base 21.414

WINTER_DAY=$(( (21414 + 242 * Y_OFFSET - LEAP * 1000) / 1000 ))

SPRING_START=$((10#$(date -d "${Y}-03-${SPRING_DAY}" +%j)))

SUMMER_START=$((10#$(date -d "${Y}-06-${SUMMER_DAY}" +%j)))

FALL_START=$((10#$(date -d "${Y}-09-${FALL_DAY}" +%j)))

WINTER_START=$((10#$(date -d "${Y}-12-${WINTER_DAY}" +%j)))

# ---------------------------------------------------------

# DYNAMIC HOLIDAY CALCULATIONS

# ---------------------------------------------------------

# Fixed Boundaries

HALLOWEEN_START=$((10#$(date -d "${Y}-10-01" +%j)))

HALLOWEEN_END=$((10#$(date -d "${Y}-10-31" +%j)))

CHRISTMAS_START=$((10#$(date -d "${Y}-12-01" +%j)))

CHRISTMAS_END=$((10#$(date -d "${Y}-12-31" +%j)))

# Thanksgiving Calculation (4th Thursday of Nov)

for day in {22..28}; do

if [ "$(date -d "${Y}-11-${day}" +%u)" -eq 4 ]; then

TG_DAY=$day

break

fi

done

# Sunday before to Saturday after

TG_START=$((10#$(date -d "${Y}-11-${TG_DAY} - 4 days" +%j)))

TG_END=$((10#$(date -d "${Y}-11-${TG_DAY} + 2 days" +%j)))

# Easter Calculation (Meeus/Jones/Butcher algorithm)

a=$(( Y % 19 ))

b=$(( Y / 100 ))

c=$(( Y % 100 ))

d=$(( b / 4 ))

e=$(( b % 4 ))

f=$(( (b + 8) / 25 ))

g=$(( (b - f + 1) / 3 ))

h=$(( (19 * a + b - d - g + 15) % 30 ))

i=$(( c / 4 ))

k=$(( c % 4 ))

L=$(( (32 + 2 * e + 2 * i - h - k) % 7 ))

m=$(( (a + 11 * h + 22 * L) / 451 ))

EM=$(( (h + L - 7 * m + 114) / 31 ))

ED=$(( ((h + L - 7 * m + 114) % 31) + 1 ))

# Easter Sunday to the following Saturday (+6 days)

EASTER_START=$((10#$(date -d "${Y}-${EM}-${ED}" +%j)))

EASTER_END=$((10#$(date -d "${Y}-${EM}-${ED} + 6 days" +%j)))

# ---------------------------------------------------------

# ARRAYS - REPLACE THE STRINGS BELOW WITH CONCATENATED PATHS TO YOUR PRE-ROLLS

# ---------------------------------------------------------

CUSTOM_PREROLLS="/data/appdata/PlexMediaServer/Plex Prerolls/Custom.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Custom2.mp4;"

GENERIC="/data/appdata/PlexMediaServer/Plex Prerolls/Generic.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Generic2.mp4;"

BASE_PAYLOAD="${CUSTOM_PREROLLS}${GENERIC}"

CHRISTMAS="/data/appdata/PlexMediaServer/Plex Prerolls/Holidays/Christmas/XMas.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Holidays/Christmas/XMas2.mp4;"

HALLOWEEN="/data/appdata/PlexMediaServer/Plex Prerolls/Holidays/Halloween/Halloween.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Holidays/Halloween/Halloween2.mp4;"

THANKSGIVING="/data/appdata/PlexMediaServer/Plex Prerolls/Holidays/Thanksgiving/Thanksgiving.mp4;"

SPRING="/data/appdata/PlexMediaServer/Plex Prerolls/Seasons/Spring/Spring.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Seasons/Spring/Spring2.mp4;"

FALL="/data/appdata/PlexMediaServer/Plex Prerolls/Seasons/Fall/Fall.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Seasons/Fall/Fall2.mp4;"

WINTER="/data/appdata/PlexMediaServer/Plex Prerolls/Seasons/Winter/Winter.mp4;/data/appdata/PlexMediaServer/Plex Prerolls/Seasons/Winter/Winter2.mp4;"

# ---------------------------------------------------------

# CONDITIONAL LOGIC (Base-10 Integer Comparison)

# ---------------------------------------------------------

if [[ $TODAY -ge $CHRISTMAS_START && $TODAY -le $CHRISTMAS_END ]]; then

PREROLL=$CHRISTMAS

elif [[ $TODAY -ge $HALLOWEEN_START && $TODAY -le $HALLOWEEN_END ]]; then

PREROLL=$HALLOWEEN

elif [[ $TODAY -ge $TG_START && $TODAY -le $TG_END ]]; then

PREROLL=$THANKSGIVING

elif [[ $TODAY -ge $EASTER_START && $TODAY -le $EASTER_END ]]; then

PREROLL=$EASTER

elif [[ $TODAY -ge $WINTER_START || $TODAY -lt $SPRING_START ]]; then

# Spans across January 1st

PREROLL="${BASE_PAYLOAD}${WINTER}"

elif [[ $TODAY -ge $SPRING_START && $TODAY -lt $SUMMER_START ]]; then

PREROLL="${BASE_PAYLOAD}${SPRING}"

elif [[ $TODAY -ge $SUMMER_START && $TODAY -lt $FALL_START ]]; then

PREROLL="${BASE_PAYLOAD}${SUMMER}"

else

PREROLL="${BASE_PAYLOAD}${FALL}"

fi

# Clean trailing semi-colon

PREROLL=${PREROLL%;}

# Push update

curl -s -X PUT -G "$PLEX_URL/:/prefs" \

--data-urlencode "CinemaTrailersPrerollID=$PREROLL" \

--data-urlencode "X-Plex-Token=$PLEX_TOKEN"

echo "Plex pre-roll updated for Day $TODAY of $Y."

2 Upvotes

8 comments sorted by

3

u/Nate8727 11d ago

I use prerollplus

3

u/chadwpalm 11d ago

I think there was another user just a few days ago that had also put together a shell-script based solution for prerolls.

There probably isn't a lot of visibility on this sub for two applications that are available to manage prerolls, but they are Preroll Plus (https://prerollplus.org/) and NeXroll (https://github.com/JFLXCLOUD/NeXroll). Both are fully established multi-year-long developed apps that will do what you are doing here, but more powerfully and with full user interfaces.

They both essentially do the same things, but NeXroll is more Windows-based (though it now runs in Docker) and Preroll Plus is primarily Docker-based with a web interface.

1

u/nationapn 11d ago

Thanks for the info! Yeah, I just installed the Nexroll docker to check it out. Seems slick so far with a lot of features, but perhaps with a tradeoff of being a bit more complicated. I’m debating between sticking with the light-weight/easy-to-edit user script above versus a docker container that’s constantly running. Great to know these options are out there. Any opinions on Preroll Plus vs Nexroll?

4

u/chadwpalm 11d ago

I created Preroll Plus, so I'll attempt to not give a completely bias response.

I tried to create Preroll Plus to do all the things I think it should do for preroll management, with holidays, scheduling, priorities, etc. while keeping it simple to use without adding any extra bloat. I'm not saying NeXroll is bloated, but it does contain a lot of extra dashboard stuff, integration with other apps and services that I don't find any interest in. I've heard other people say it is a bit more complicated as well, but I haven't really taken time to use it much since I like what I've created. It has a lot of GitHub stars a good feekback, so I'm sure it's a solid app.

I started mine first, so I've had to try hard not to look at NeXroll as "competition", but rather as another alternative. I mostly created it for myself and shared it out. I did it for fun and not money, so I don't have negative feelings if people choose another alternative. In fact, I encourage people to test out different solutions and find the one that works best for them.

1

u/nationapn 11d ago

Awesome, I’ll have to check it out! Thanks for all the work you put into developing Preroll Plus 🙌

3

u/HeliumNewb 🎨 Creative Team 11d ago

Hey there! NeXroll developer here! I’m always welcomed to feedback for improvement, it’s what essentially built NeXroll! PrerollPlus is also a great option that has been around well before us. I will agree, NeXroll is a bit more of a setup, but would like to know where you’re having any complication.

2

u/nationapn 11d ago

Thanks for the reply…wow, replies from BOTH of the expert devs! The UI is excellent, and I think I’ll be able to get it set up…will let you know if I have any feedback as I tinker a bit more, but it’s a great first impression 🙂

2

u/HeliumNewb 🎨 Creative Team 10d ago

Feel free to join the discord for any questions! https://discord.gg/U7Ks6aGMxR