Lecture aléatoire de plusieurs vidéos changeant toutes les 5 minutes

9

J'installe l'A / V pour une fête de vacances ce week-end et j'ai une idée que je ne sais pas comment mettre en œuvre.

J'ai un tas de films de Noël (vacances de Noël, une histoire de Noël, c'est une vie merveilleuse, etc.) que j'aimerais avoir en continu à la fête. La configuration est un MacBook connecté à un projecteur. Je veux que ce soit une ambiance d'ambiance donc ça va fonctionner silencieusement.

Étant donné que tous les films sont dans la plage +1 heure, au lieu de simplement les lire du début à la fin, je voudrais montrer de petits échantillons de manière aléatoire et continue. Idéalement, la façon dont cela fonctionnerait est que toutes les cinq minutes, il choisit un échantillon aléatoire de 5 minutes dans un film aléatoire dans la liste de lecture / répertoire et l'affiche. Une fois ce clip terminé, il doit choisir un autre clip et faire une sorte de fondu / volet sur le clip choisi.

Je ne sais pas par où commencer, à commencer par le joueur que je devrais utiliser. VLC peut-il faire quelque chose comme ça? MPlayer? S'il existe un lecteur avec un langage de script étendu (prise en charge de rand (), découverte de la longueur de la vidéo, accès vidéo aléatoire). Si c'est le cas, je serai probablement en mesure de RTFM et de le faire fonctionner; c'est juste que je n'ai pas le temps de revenir en arrière dans des impasses donc je voudrais commencer sur la bonne voie. Aucune suggestion?

Brian
la source

Réponses:

11

Après n'avoir pas reçu de réponse à temps (j'aurais dû le poster une semaine plus tôt), j'ai fini par plonger dans l'automatisation de VLC. J'ai trouvé ce petit bijou de blog sur le contrôle de VLC à l'aide de sockets UNIX. L'essentiel est que si vous configurez correctement VLC, vous pouvez lui envoyer des commandes via la syntaxe de ligne de commande:

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

[Commande VLC] est une commande prise en charge par VLC (vous pouvez trouver une liste de commandes en envoyant la commande " longhelp ").

J'ai fini par écrire un script Python pour charger automatiquement un répertoire plein de films, puis choisir au hasard les clips à afficher. Le script met d'abord tous les avis dans une liste de lecture VLC. Il choisit ensuite un fichier aléatoire dans la liste de lecture et choisit un point de départ aléatoire dans cette vidéo à lire. Le script attend ensuite la durée spécifiée et répète le processus. Le voici, pas pour les faibles de cœur:

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 et comme note de côté, nous l'avons fait tourner sur un projecteur et c'était le succès de la fête. Tout le monde a adoré jouer avec les valeurs des secondes et choisir de nouvelles vidéos à ajouter. Je ne me suis pas couché , mais presque!

EDIT: J'ai supprimé la ligne qui ouvre VLC car il y avait des problèmes de synchronisation où VLC ne serait qu'à moitié chargé lorsque le script commençait à ajouter des fichiers à la liste de lecture. Maintenant, j'ouvre manuellement VLC et j'attends qu'il termine le chargement avant de démarrer le script.

Brian
la source
Wow, c'est une solution vraiment délicate. Bravo de le faire fonctionner exactement comme vous l'aviez prévu en temps réel.
fideli
1
Je pense à étendre cette idée à un petit média, qui comprend: ordre spécifique, découpes préférées, mélange de filtres, enregistrement d'une configuration / lecture dans un fichier et lecture de médias basée sur les événements. Quelqu'un s'intéresse-t-il également à un tel projet?
joecks
4

Je préférerais commenter cela, plutôt que de poster une demi-réponse, mais je n'ai pas assez de réputation. Peut-être que quelqu'un d'autre peut s'appuyer sur cela.

Je suggère de créer la vidéo entière au préalable. Écrivez un script bash pour utiliser mencoder pour générer un clip à l'aide d'une commande telle que la suivante:

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

Dans cette commande, START serait un point de départ aléatoire, MOVIE.AVI est un film source aléatoire et MOVIE-CLIP - ##. Avi est un clip généré. Les commutateurs -oac et -ovc spécifient que les codecs de sortie doivent être identiques à la source. Le commutateur -endpos spécifie la longueur du clip, définie sur 300 s. Notez que cela n'a pas de découverte de longueur de vidéo, ce que je considère comme un problème qui est facilement résolu manuellement pour chaque film (étant donné que vous n'en avez qu'une poignée). Votre script pourrait parcourir cette commande pour générer un certain nombre de clips.

Pour joindre les clips, vous pouvez utiliser une commande comme:

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

C'est là que je proposerais à quelqu'un ayant plus d'expérience de choisir. Je ne sais pas s'il existe un moyen dans mencoder d'ajouter des transitions de fondu / dissolution entre les clips.

fideli
la source