Sección aleatoria de reproducción de múltiples videos que cambia cada 5 minutos

9

Estoy configurando el A / V para una fiesta de fin de semana y tengo una idea que no estoy seguro de cómo implementar.

Tengo un montón de películas navideñas (Vacaciones de Navidad, Una historia de Navidad, Es una vida maravillosa, etc.) que me gustaría tener continuamente en la fiesta. La configuración es una MacBook conectada a un proyector. Quiero que esto sea un ambiente de fondo para que se ejecute en silencio.

Como todas las películas están en el rango de +1 hora, en lugar de reproducirlas de principio a fin, me gustaría mostrar pequeñas muestras de forma aleatoria y continua. Idealmente, la forma en que funcionaría es que cada cinco minutos elegiría una muestra aleatoria de 5 minutos de una película aleatoria en la lista de reproducción / directorio y la mostraría. Una vez que el clip ha terminado, debe elegir otro clip y hacer algún tipo de desvanecimiento / borrado al clip elegido.

No estoy seguro de por dónde empezar con esto, comenzando con qué jugador debo usar. ¿Puede VLC hacer algo como esto? MPlayer? Si hay un reproductor con un lenguaje de scripting extenso (soporte para rand (), descubrimiento de duración de video, acceso de video aleatorio). Si es así, probablemente pueda RTFM y hacerlo funcionar; es solo que no tengo tiempo para retroceder desde callejones sin salida, así que me gustaría comenzar por el camino correcto. ¿Alguna sugerencia?

Brian
fuente

Respuestas:

11

Después de no obtener una respuesta a tiempo (debería haber publicado esto una semana antes), terminé sumergiéndome en la automatización de VLC. Encontré esta joya de una publicación de blog sobre el control de VLC utilizando sockets UNIX. La esencia de esto es que si configura VLC correctamente, puede enviarle comandos a través de la sintaxis de la línea de comando:

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

donde [Comando VLC] es cualquier comando compatible con VLC (puede encontrar una lista de comandos enviando el comando " longhelp ").

Terminé escribiendo un script de Python para cargar automáticamente un directorio lleno de películas y luego elegir aleatoriamente clips para mostrar. El guión primero pone todos los avis en una lista de reproducción VLC. Luego elige un archivo aleatorio de la lista de reproducción y elige un punto de partida aleatorio en ese video para reproducir. El script luego espera el tiempo especificado y repite el proceso. Aquí está, no para los débiles de corazón:

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

Ah, y como nota al margen, teníamos esto funcionando en un proyector y fue el éxito de la fiesta. A todos les encantó jugar con los valores de los segundos y elegir nuevos videos para agregar. No me acostaron , pero casi!

EDITAR: eliminé la línea que abre VLC porque hubo problemas de tiempo en los que VLC solo se cargaba a medias cuando el script comenzó a agregar archivos a la lista de reproducción. Ahora solo abro VLC manualmente y espero a que termine de cargarse antes de comenzar el script.

Brian
fuente
Wow, esa es una solución realmente ingeniosa. Felicitaciones a que se ejecute exactamente como pretendía en tiempo real.
fideli
1
Estoy pensando en extender esa idea a una pequeña utilidad de medios, que presenta: orden específico, cortes preferidos, combinación de filtros, guardar una configuración / leerla desde un archivo y reproducción de medios basada en eventos. ¿Alguien también está interesado en tal proyecto?
joecks
4

Prefiero comentar esto, en lugar de publicar una media respuesta, pero no tengo suficiente reputación. Quizás alguien más pueda construir sobre esto.

Sugeriría crear el video completo de antemano. Escriba un script bash para usar mencoder para generar un clip usando un comando como el siguiente:

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

En ese comando, START sería un punto de partida aleatorio, MOVIE.AVI es una película de origen aleatorio, y MOVIE-CLIP - ##. Avi es un clip generado. Los modificadores -oac y -ovc especifican que los códecs de salida deben ser los mismos que los de la fuente. El modificador -endpos especifica la longitud del clip, establecido en 300 s. Tenga en cuenta que esto no tiene detección de duración de video, lo que considero que es un problema que se resuelve fácilmente de forma manual para cada película (dado que solo tiene un puñado). Su secuencia de comandos podría recorrer ese comando para generar varios clips.

Para unir los clips, puede usar un comando como:

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

Aquí es donde sugeriría que alguien con más experiencia recoja. No estoy seguro de si hay una forma en mencoder para agregar transiciones de desvanecimiento / disolución entre los clips.

fideli
fuente