GregMo 21 Posted May 24, 2021 Share Posted May 24, 2021 (edited) I'm sharing this attempt at rotating a playlist so that maybe someone else can save some of the HOURS it took me to piece all of this together. What this does is to read a playlist and identifies the last item of the list. It then searches the list for a previous episode of the same show to see what different show has followed it prior in the list. If it finds a previous episode match, it will then add the next episode of the next show to the end of the list. If it does not find a previous episode, it will start with the beginning of the playlist. As an example, you could create a list with Friends 1x1, Scrubs 1x1, and Fraiser 1x1, and this script will add Friends 1x2 to the end of the list, to allow you to watch several shows in a rotating schedule like you would do if it was a network schedule. There's is some error checking in this but you should only use it if you're comfortable with everything that it does. Also, this relies on `jq` to read JSON responses so you'll have to install that if you don't already have it. Before running this, you will need to set the first 4 variables. This means you'll need to go into the Emby server and setup an API key, and create a playlist to start with and supply the itemid of the playlist. Bear in mind, this is something I put together for my personal use which I'm only sharing for the help of others, and maybe for comments. I will say that as written it works fairly well but I have ran into some issues with the way Emby now handles the period preceeding a folder name. There is some limited error checking built in for that, however. Cheers #!/bin/bash Host="http://10.0.0.107:8096" UserId=501de38c93b6464c80776a945bdf9e6f EmbyXToken="X-Emby-Token: fd9f7c0a60114a4c9f67b4c8a19447da" PlaylistItemId=261198 ######################################################## function set_item_data () { IFS=$'\n' for j in $item_data ; do v=$(echo $j | awk -F' ' '{ for (i=2; i<=NF; i++) print $i }') t=$(echo $j | awk -F' ' '{print $1}' | awk -F'\"' '{print $2}') if [ -z $t ] ; then t="blank"; fi case $t in Name) EpisodeName=$(echo $v | awk -F'\"' '{print $2}') ;; SeriesName) SeriesName=$(echo $v | awk -F'\"' '{print $2}') ;; ParentIndexNumber) SeasonNumber=$(echo $v | awk -F',' '{print $1}') ;; IndexNumber) EpisodeNumber=$(echo $v | awk -F',' '{print $1}') ;; Id) EpisodeId=$(echo $v | awk -F'\"' '{print $2}') ;; SeriesId) SeriesId=$(echo $v | awk -F'\"' '{print $2}') ;; esac done unset IFS } ################################################ # # Get data elements of last item (last Show) in playlist # url=$Host"/Playlists/"$PlaylistItemId"/Items" full_playlist_data=`curl -s -X GET -H "$EmbyXToken" -H "Content-Type: application/json" $url` TotalRecordCount=`echo $full_playlist_data | jq '.TotalRecordCount'` idx_num=$TotalRecordCount ((idx_num--)) item_data=`echo $full_playlist_data | jq --arg idx_num "$idx_num" '.Items[$idx_num|tonumber]'` set_item_data echo echo Last item: $SeriesName" "$SeasonNumber"x"$EpisodeNumber" - "$EpisodeName echo ################################################ # # Look for second to last match of the "Show/Series" in the playlist # idx_num=$TotalRecordCount ((idx_num--)) until [ $idx_num = 0 ] || [ ! -z $found ]; do ((idx_num--)) ptr=`echo $full_playlist_data | jq --arg idx_num "$idx_num" '.Items[$idx_num|tonumber].SeriesId'` ptr=`echo $ptr | sed -e 's/^"//' -e 's/"$//'` if [ $ptr = $SeriesId ] ; then found=true; fi done ################################################ # # If a match was found then we want to select the show that # follows it, elsewise just use the first show of the playlist # # As an aside, you should only ever once reach the start of the list # if [ ! -z $found ]; then ((idx_num++)) else echo echo "Reached start of list" echo fi ################################################ # # Get data elements of the reference show/episode # item_data=`echo $full_playlist_data | jq --arg idx_num "$idx_num" '.Items[$idx_num|tonumber]'` set_item_data echo "Reference show/episode: "$SeriesName" "$SeasonNumber"x"$EpisodeNumber" - "$EpisodeName echo check_dupe=$EpisodeNumber ################################################ # # Get data elements of the reference show/episode # url=$Host"/Shows/"$SeriesId"/Episodes" full_series_data=`curl -s -X GET -H "$EmbyXToken" -H "Content-Type: application/json" $url` unset found idx_num=0 TotalRecordCount=`echo $full_series_data | jq '.TotalRecordCount'` until [ $idx_num = $TotalRecordCount ] || [ ! -z $found ]; do ptr=`echo $full_series_data | jq --arg idx_num "$idx_num" '.Items[$idx_num|tonumber].Id'` ptr=`echo $ptr | sed -e 's/^"//' -e 's/"$//'` if [ $ptr = $EpisodeId ] ; then found=true; fi ((idx_num++)) done if [ $idx_num = $TotalRecordCount ]; then echo echo "Reached end of show (Series) before finding match" ; echo exit fi ################################################ # # Get data elements of the episode to add and add it # item_data=`echo $full_series_data | jq --arg idx_num "$idx_num" '.Items[$idx_num|tonumber]'` set_item_data echo Episode to add: $SeriesName" "$SeasonNumber"x"$EpisodeNumber" - "$EpisodeName echo if [ $check_dupe = $EpisodeNumber ]; then echo !!! Duplicate episodes found !!! echo echo Check for multiple copies, possible with folders echo starting with a period that are no longer hidden. echo exit fi url=$Host"/Playlists/"$PlaylistItemId"/Items" curl -s -X POST -H "$EmbyXToken" -H "Content-Type: application/json" $url \ --data-binary @- <<DATA { "Ids": $EpisodeId, "UserId": $UserId } DATA Edited May 25, 2021 by GregMo Link to comment Share on other sites More sharing options...
Luke 37069 Posted May 24, 2021 Share Posted May 24, 2021 Very cool, thanks for sharing. Link to comment Share on other sites More sharing options...
GregMo 21 Posted May 25, 2021 Author Share Posted May 25, 2021 20 hours ago, Luke said: Very cool, thanks for sharing. I'm glad you liked it. After sleeping on the issue, I found a much better methodology so I rewrote a lot of it so I've updated the post. I truly hope someone gets some use out of it besides me. 1 Link to comment Share on other sites More sharing options...
GregMo 21 Posted May 26, 2021 Author Share Posted May 26, 2021 (edited) Now, after you watch a few episodes you'll want to remove them from the beginning of the playlist because if the playlist gets too big it'll bog down some clients. Using the context menu of Emby can be a bit tedious so let's make it a bit easier. The following bash script will start at the first item of the playlist, discern all the consecutive items that have been played, and then remove them from the playlist. As written the script runs in a test mode which outputs the episodes it sees as being played but doesn't delete them. To get the script to run with no testing use the parameter "--commit". #!/bin/bash Host="http://10.0.0.107:8096" UserId=501de38c93b6464c80776a945bdf9e6f EmbyXToken="X-Emby-Token: fd9f7c0a60114a4c9f67b4c8a19447da" PlaylistItemNum=261198 testing=$1 if [ -z $testing ]; then testing=true ; fi if [ $testing = --commit ]; then unset testing ; fi ######################################################## function set_item_data () { IFS=$'\n' for j in $item_data ; do v=$(echo $j | awk -F' ' '{ for (i=2; i<=NF; i++) print $i }') t=$(echo $j | awk -F' ' '{print $1}' | awk -F'\"' '{print $2}') if [ -z $t ] ; then t="blank"; fi case $t in Name) EpisodeName=$(echo $v | awk -F'\"' '{print $2}') ;; SeriesName) SeriesName=$(echo $v | awk -F'\"' '{print $2}') ;; ParentIndexNumber) SeasonNumber=$(echo $v | awk -F',' '{print $1}') ;; IndexNumber) EpisodeNumber=$(echo $v | awk -F',' '{print $1}') ;; Id) EpisodeId=$(echo $v | awk -F'\"' '{print $2}') ;; SeriesId) SeriesId=$(echo $v | awk -F'\"' '{print $2}') ;; PlaylistItemId) PlaylistItemId=$(echo $v | awk -F'\"' '{print $2}') ;; esac done unset IFS } ################################################ echo url=$Host"/Playlists/"$PlaylistItemNum"/Items" full_playlist_data=`curl -s -X GET -H "$EmbyXToken" -H "Content-Type: application/json" $url` idx_num=0 ItemPlayed=true while [ $ItemPlayed ]; do item_data=`echo $full_playlist_data | jq --arg idx_num "$idx_num" '.Items[$idx_num|tonumber]'` set_item_data url=$Host"/Users/"$UserId"/Items/"$EpisodeId item_data=`curl -s -X GET -H "$EmbyXToken" -H "Content-Type: application/json" $url` ItemPlayed=`echo $item_data | jq '.UserData.Played'` if [ $ItemPlayed = true ]; then echo Played: $SeriesName" "$SeasonNumber"x"$EpisodeNumber" - "$EpisodeName ; echo if [ $DeletePlaylistItems ]; then DeletePlaylistItems=$DeletePlaylistItems","$PlaylistItemId else DeletePlaylistItems=$PlaylistItemId fi else unset ItemPlayed fi ((idx_num++)) done if [ ! $testing ]; then url=$Host"/Playlists/"$PlaylistItemNum"/Items/?EntryIds="$DeletePlaylistItems curl -s -X DELETE -H "$EmbyXToken" -H "Content-Type: application/json" $url fi Edited May 26, 2021 by GregMo Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now