Linux – VLC “watch folder playlist” auto update/refresh playlist when adding new movies

linuxvlc-media-player

Is there a way to do this?

I want to run VLC in fullscreen mode with an autoloaded playlist. The playlist would be a folder, say /home/user/videos

During the day I want to upload some movies to the computer running VLC with this playlist.
I upload a movie to /home/user/videos

Now I need to reload/restart VLC for the changes to take affect in the playlist.

Is there a way to refresh the playlist without restarting VLC? Maybe let it check for new files every X minutes or something?

Best Answer

I first looked into the possibilities of writing a VLC LUA extentionen, and this seams very possible.

I looked at this extension : http://addons.videolan.org/CONTENT/content-files/140699-addsimilar.lua

Which has all the functionality we need. So modifying it heavily would properly work, but it seamed as too much work for this project.

So I googled some more and stumbled upon this site: http://www.cenolan.com/2013/03/looping-video-playlist-omxplayer-raspberry-pi/

It turns out that this bash script can easily be modified to use VLC or cvlc.

So I did and the result looks like this:

#!/bin/sh

# get rid of the cursor so we don't see it when videos are running
setterm -cursor off

#Time 
TIME=$(date +%H)

# set here the path to the directory containing your videos
VIDEOPATH="/home/user/videos" 

# you can normally leave this alone
SERVICE="cvlc"

# now for our infinite loop!
while true; do
        if ps ax | grep -v grep | grep $SERVICE > /dev/null
        then
        sleep 0;
else
        for entry in $VIDEOPATH/* # You could add .mkv to the end of this or any other file extention, to only play specific extentions
        do
             cvlc --play-and-exit --no-video-title -f "$entry" > /dev/null

        done

fi
done

The reason I need this functionality is for a kiosk video screen like project, where videos are uploaded and deleted at all times.

One con about this solution is that VLC still need to open and close after playing each video, which it does using this script. So the PC running the script, need to have a blank desktop (GUI removed) and a black background. This way you will only see about 0.5 - 1 sec black screen in between each video clip.

The script is still work in progress, since I will be adding some more features to it, so if you find it useful and want my final script, leave a comment and I will update the answer.

If you have a better solution or even a LUA solution, please post it - and I will accept the answer - but for now this works for my project.

Cheers

UPDATE at the request of TheFrost

Here is my final script, I will briefly describe it below: play.sh

#!/bin/bash

xsetroot

# Set the path to the directory containing your videos
VIDEOPATH="/home/pi/vids/" 

# Time & day
set_TIME() {
TIME=$(date +%H)
DAY=$(date +%u) 
}

set_TIME

# Normally leave this alone
SERVICE="omxplayer"

# Get rid of the cursor so we don't see it when videos are running
setterm -cursor off

# # #
#
#  Play files with omxplayer and close the player when the video is finished
#
# # #
play_files () {
 for entry in $1*
    do
    set_TIME
        # Dont try to play dirs
        if [ ! -d "$entry" ]; then 

            omxplayer -p -o hdmi "$entry" > /dev/null
        fi
    done  
} 

# # #
#
#  Check if its time to play files
#  $1 = hour now, $2 = begin hour, $3 = End hour, $4 = folder with video files
#
# # #
check_if_time_to_play() {

  # Make sure the arguments are interpreted as *decimal* integers
  # by evaluating them in an arithmetic context (-i) with prefix '10#', 
  # indicating number base 10.
  # (A leading '0' would cause intepretation as *octal*.)
  local -i hourNow=10#$1 startHour=10#$2 endHour=10#$3 play
  local dir=$4

  # Make sure the folder is not empty.
  if ! find "$dir" -mindepth 1 -print -quit | grep -q .; then
    return # It's empty! Don't play the non-existing clips. 
  fi

  # Determine if current hour is between begin and end time.
  play=0
  if (( startHour < endHour )); then
    if (( hourNow >= startHour && hourNow < endHour )); then
      play=1
    fi
  else # startHour > endHour: overnight hours
    if (( hourNow >= startHour || hourNow < endHour )); then
      play=1
    fi
  fi

  if (( play )); then
    # Play the clips
    play_files "$dir" 
  else
     : # Current hour is not in range, don't play the clips.
  fi
}

# Now for our infinite loop!
while true; do
        if ps ax | grep -v grep | grep $SERVICE > /dev/null
        then
        sleep 0;
else

# # #
#
#  First we check the Video folder if it has any subfolders.
#  If it doesn't, play the files in the folder.
#  If subfolders exists, and follow the naming standard do as the commanded. 
#   
#  A folder named: 18-22 means start at 18 o clock, end at 22, everyday.
#  A folder named: 18-22-07 means start at 18 o clock, end at 22, only during Sunday.
#
#  01 = Monday, 02 = Tuesday and so on, thats why 07 is Sunday.
#
#  Files in subfolders will be playd according to the folders name.
#  
#  If for some reason there is an empty folder or it doesn't follow the standard above, we ignore it.
#
# # #
    cd $VIDEOPATH
    shopt -s nullglob
    FOLDERS=(*/)
    shopt -u nullglob # Turn off nullglob to make sure it doesn't interfere with anything later

    # Check if there is no subfolders
    if (( !${#FOLDERS[@]} )); then
        play_files "$VIDEOPATH" 
    else
        play_files "$VIDEOPATH"
        for entry in "${FOLDERS[@]}"; 
        do
            TEMPVAR=${entry::-1} # Remove trailing /
            IFS='-' read -a PLAYTIME <<< "$TEMPVAR" # PLAYTIME array [0] = Begin time, [1] = End time, [2] = Day
            if (( ${#PLAYTIME[@]} )); then
                #check if day is not set
                if (( !${#PLAYTIME[2]} )); then
                    check_if_time_to_play $TIME "${PLAYTIME[0]}" "${PLAYTIME[1]}" "$VIDEOPATH/$entry" 
                else # Day is set
                    if [ $DAY -eq "${PLAYTIME[2]}" ]; then
                        check_if_time_to_play $TIME "${PLAYTIME[0]}" "${PLAYTIME[1]}" "$VIDEOPATH/$entry"
                    else
                        continue # Not today..
                    fi
                fi
            fi
        done;
    fi

fi
done

So as stated in the comment I switched to OMXplayer - but VLC will work fine as well. Simply change it in SERVICE= and in the play_files() function.

So the script plays files located in VIDEOPATH and if this path has sub-folders it will check if the folders use the naming convention invented for this. Read comments in the script - basically you can create a folder named StartTime-EndTime (fx. name a folder 22-23) and clips in this folder will only play from 10PM to 11PM. And if you only want to play clips a specific day of the week, create a folder StartTime-EndTime-DayOfWeek (Fx. a folder named 22-23-01) clips in this folder will only play from 10PM to 11PM on Monday. Did it end on 02 it would be on Tuesday, 03 Wednesday and so on.

I think the rest is explained in the comments of the script, else feel free to ask if you have any questions. Also please share any improvements :)

I have this script running on 50+ different Raspberry PI's at different locations. They are on 24/7 and are running very stable. I have removed all visible GUI from the PI's. They all run a cronjob that every 15 minutes rsyncs with a main server, My Sync script looks like this: sync.sh

#!/bin/sh

#MountFTP
echo "RASPERRYPIROOTPASSWORD" | sudo umount /home/pi/ftp/
sleep 5
echo "RASPERRYPIROOTPASSWORD" | sudo curlftpfs www-data:MYPASSWORD@MYSERVER.COM /home/pi/ftp -o allow_other

#Sync Videos
rsync -avztr --delete /home/pi/ftp/data/files/CURRENTRASPBERRYPI/ /home/pi/vids/

#sync scripts (so we can remotely update the scripts)
rsync -avztr /home/pi/ftp/data/files/Scripts/syncscript/CURRENTRASPBERRYPI/sync.sh /home/pi #is this script
rsync -avztr /home/pi/ftp/data/files/Scripts/play.sh /home/pi #is they play videos script
chmod +x *.sh

#Write to log
IP="$(curl -s http://whatismyip.akamai.com/)"
DATE="$(date +%d-%m-%Y-%X)"

echo $DATE " - " $IP " - CURRENTRASPBERRYPI " >> /home/pi/CURRENTRASPBERRYPI.txt
cp /home/pi/CURRENTRASPBERRYPI.txt /home/pi/ftp/logs/

Capital letters in the script above, I would manually change for each Computer running the script.

On the server I have used a web-based file-manager called AJAX explorer, now called Pydio. This is so end users can easily upload videos to each computer/location they want (/ftp/data/files/CURRENTRASPBERRYPI/).

Related Question