Playback random section from multiple videos changing every 5 minutes

7,727

Solution 1

After not getting an answer in time (should have posted this a week earlier), I ended up diving into automating VLC. I found this gem of a blog post about controlling VLC using UNIX sockets. The gist of it is that you can send commands to VLC via the command line syntax:

echo [VLC Command] | nc -U /Users/vlc.sock

where [VLC Command] is any command that VLC supports (you can find a list of commands by sending the command "longhelp").

I ended up writing a Python script to automatically load up a directory full of movies and then randomly choose clips to show. The script first puts all avis into a VLC playlist. It then chooses a random file from the playlist and chooses a random starting point in that video to play. The script then waits for the specified amount of time and repeats the process. Here it is, not for the faint of heart:

import subprocess
import random
import time
import os
import sys

## Just seed if you want to get the same sequence after restarting the script
## random.seed()

SocketLocation = "/Users/vlc.sock"

## You can enter a directory as a command line argument; otherwise it will use the default
if(len(sys.argv) >= 2):
    MoviesDir = sys.argv[1]
else:
    MoviesDir = "/Users/Movies/Xmas"

## You can enter the interval in seconds as the second command line argument as well
if(len(sys.argv) >= 3):
    IntervalInSeconds = int(sys.argv[2])
else:
    IntervalInSeconds = 240 

## Sends an arbitrary command to VLC
def RunVLCCommand(cmd):
    p = subprocess.Popen("echo " + cmd + " | nc -U " + SocketLocation, shell = True, stdout = subprocess.PIPE)
    errcode = p.wait()
    retval = p.stdout.read()
    print "returning: " + retval
    return retval 

## Clear the playlist
RunVLCCommand("clear")

RawMovieFiles = os.listdir(MoviesDir)
MovieFiles = []
FileLengths = []

## Loop through the directory listing and add each avi or divx file to the playlist
for MovieFile in RawMovieFiles:
    if(MovieFile.endswith(".avi") or MovieFile.endswith(".divx")):
        MovieFiles.append(MovieFile)
        RunVLCCommand("add \"" + MoviesDir + "/" + MovieFile + "\"")

PlayListItemNum = 0

## Loop forever
while 1==1:
    ## Choose a random movie from the playlist
    PlayListItemNum = random.randint(1, len(MovieFiles))
    RunVLCCommand("goto " + str(PlayListItemNum))

    FileLength = "notadigit"
    tries = 0

    ## Sometimes get_length doesn't work right away so retry 50 times
    while tries < 50 and FileLength .strip().isdigit() == False or FileLength.strip() == "0":
        tries+=1
        FileLength = RunVLCCommand("get_length")    

    ## If get_length fails 50 times in a row, just choose another movie
    if tries < 50:
        ## Choose a random start time 
        StartTimeCode = random.randint(30, int(FileLength) - IntervalInSeconds);


        RunVLCCommand("seek " + str(StartTimeCode))

        ## Turn on fullscreen
        RunVLCCommand("f on")

        ## Wait until the interval expires
        time.sleep(IntervalInSeconds)   
        ## Stop the movie
        RunVLCCommand("stop")   
        tries = 0
        ## Wait until the video stops playing or 50 tries, whichever comes first
        while tries < 50 and RunVLCCommand("is_playing").strip() == "1":    
            time.sleep(1) 
            tries+=1

Oh and as a side note, we had this running on a projector and it was the hit of the party. Everyone loved messing around with the seconds values and picking new videos to add.

EDIT: I removed the line that opens VLC because there were timing issues where VLC would only be half loaded when the script started adding files to the playlist. Now I just manually open VLC and wait for it to finish loading before starting the script.

Solution 2

I'd prefer to comment this, rather than post a half-answer, but I don't have enough reputation. Perhaps someone else can build on this.

I would suggest creating the entire video beforehand. Write a bash script to use mencoder to generate a clip using a command such as the following:

mencoder -ss START -endpos 300 MOVIE.AVI -oac copy \
-ovc copy -o MOVIE-CLIP-##.avi

In that command, START would be a random starting point, MOVIE.AVI is a random source movie, and MOVIE-CLIP-##.avi is one generated clip. The -oac and -ovc switches specify that the output codecs should be the same as the source. The -endpos switch specifies the length of the clip, set to 300 s. Note that this doesn't have video length discovery, which I consider to be a problem that is easily-solved manually for each movie (given that you only have a handful). Your script could loop through that command to generate a number of clips.

To join the clips, you can use a command like:

mencoder -oac copy -ovc copy -idx -o MOVIE-CLIPS.AVI \
MOVIE-CLIP-01.AVI MOVIE-CLIP-02.AVI ... MOVIE-CLIP-NN.AVI

This is where I would suggest someone with more experience picks up from. I'm not sure if there's a way in mencoder to add fading/dissolving transitions between the clips.

Share:
7,727
ruby
Author by

ruby

Updated on September 17, 2022

Comments

  • ruby
    ruby almost 2 years

    I'm setting up the A/V for a holiday party this weekend and have an idea that I'm not sure how to implement.

    I have a bunch of Christmas movies (Christmas Vacation, A Christmas Story, It's a Wonderful Life, etc.) that I'd like to have running continuously at the party. The setup is a MacBook connected to a projector. I want this to be a background ambiance thing so it's going to be running silently.

    Since all of the movies are in the 1+ hour range, instead of just playing them all through from beginning to end, I'd like to show small samples randomly and continuously. Ideally the way it would work is that every five minutes it would choose a random 5-minute sample from a random movie in the playlist/directory and display it. Once that clip is over, it should choose another clip and do some sort of fade/wipe to the chosen clip.

    I'm not sure where to start on this, beginning with what player I should use. Can VLC do something like this? MPlayer? If there's a player with an extensive scripting language (support for rand(), video length discovery, random video access). If so, I will probably be able to RTFM and get it working; it's just that I don't have time to backtrack from dead-ends so I'd like to start off on the right track. Any suggestions?

  • fideli
    fideli over 14 years
    Wow, that's a really slick solution. Kudos to having it run exactly as you intended in real-time.
  • joecks
    joecks over 12 years
    I am thinking about extending that idea to a small media util, that features: specific order, preferred cut-outs, filter blending, saving an configuration / reading it from a file, and event based playing of media. Is also someone interested in such a project?