Putar ulang bagian acak dari banyak video yang berubah setiap 5 menit

9

Saya menyiapkan A / V untuk pesta liburan akhir pekan ini dan punya ide bahwa saya tidak yakin bagaimana cara mengimplementasikannya.

Saya memiliki banyak film Natal (Liburan Natal, A Christmas Story, It's a Wonderful Life, dll.) Yang saya ingin terus berjalan di pesta. Penyiapannya adalah MacBook yang terhubung ke proyektor. Saya ingin ini menjadi suasana latar belakang jadi itu akan berjalan diam-diam.

Karena semua film berada dalam kisaran +1 jam, alih-alih hanya memutarnya dari awal hingga akhir, saya ingin menampilkan sampel kecil secara acak dan terus menerus. Idealnya cara kerjanya adalah bahwa setiap lima menit ia akan memilih sampel 5 menit acak dari film acak dalam daftar putar / direktori dan menampilkannya. Setelah klip itu selesai, ia harus memilih klip lain dan melakukan semacam fade / wipe ke klip yang dipilih.

Saya tidak yakin harus mulai dari mana, mulai dengan pemain apa yang harus saya gunakan. Bisakah VLC melakukan sesuatu seperti ini? MPlayer? Jika ada pemain dengan bahasa skrip yang luas (dukungan untuk rand (), penemuan panjang video, akses video acak). Jika demikian, saya mungkin akan dapat RTFM dan membuatnya berfungsi; hanya saja saya tidak punya waktu untuk mundur dari jalan buntu jadi saya ingin memulai di jalur yang benar. Ada saran?

Brian
sumber

Jawaban:

11

Setelah tidak mendapatkan jawaban tepat waktu (seharusnya diposting ini seminggu sebelumnya), saya akhirnya menyelam ke VLC otomatis. Saya menemukan permata ini dari posting blog tentang cara mengontrol VLC menggunakan soket UNIX. Intinya adalah jika Anda mengkonfigurasi VLC dengan benar, Anda dapat mengirim perintah kepadanya melalui sintaks baris perintah:

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

di mana [Perintah VLC] adalah perintah apa pun yang didukung VLC (Anda dapat menemukan daftar perintah dengan mengirim perintah " longhelp ").

Saya akhirnya menulis skrip Python untuk secara otomatis memuat direktori yang penuh dengan film dan kemudian secara acak memilih klip untuk ditampilkan. Script pertama menempatkan semua avis ke daftar putar VLC. Itu kemudian memilih file acak dari daftar putar dan memilih titik awal acak dalam video yang akan diputar. Script kemudian menunggu jumlah waktu yang ditentukan dan mengulangi prosesnya. Ini dia, bukan untuk yang lemah hati:

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 dan sebagai catatan, kami menjalankan ini di proyektor dan itu adalah hit partai. Semua orang senang bermain-main dengan nilai detik dan memilih video baru untuk ditambahkan. Tidak membuat saya terbaring , tetapi hampir!

EDIT: Saya menghapus baris yang membuka VLC karena ada masalah waktu di mana VLC hanya akan setengah dimuat ketika skrip mulai menambahkan file ke daftar putar. Sekarang saya hanya membuka VLC secara manual dan menunggu sampai selesai memuat sebelum memulai skrip.

Brian
sumber
Wow, itu solusi yang sangat apik. Kudos menjalankannya tepat seperti yang Anda maksudkan secara real-time.
fideli
1
Saya berpikir untuk memperluas ide itu ke util media kecil, yang memiliki fitur: urutan tertentu, cut-out yang disukai, filter blending, menyimpan konfigurasi / membacanya dari file, dan memainkan media berdasarkan peristiwa. Apakah seseorang juga tertarik dengan proyek semacam itu?
joecks
4

Saya lebih suka berkomentar, daripada mengirim setengah jawaban, tetapi saya tidak memiliki reputasi yang cukup. Mungkin orang lain bisa membangun ini.

Saya menyarankan untuk membuat seluruh video sebelumnya. Tulis skrip bash untuk menggunakan mencoder untuk menghasilkan klip menggunakan perintah seperti berikut:

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

Dalam perintah itu, MULAI akan menjadi titik awal acak, MOVIE.AVI adalah film sumber acak, dan MOVIE-CLIP - ## .vi adalah salah satu klip yang dihasilkan. Switch -oac dan -ovc menentukan bahwa codec output harus sama dengan sumbernya. Sakelar-akhir menentukan panjang klip, diatur ke 300 s. Perhatikan bahwa ini tidak memiliki penemuan panjang video, yang saya anggap sebagai masalah yang mudah dipecahkan secara manual untuk setiap film (mengingat bahwa Anda hanya memiliki sedikit). Script Anda dapat mengulangi perintah itu untuk menghasilkan sejumlah klip.

Untuk bergabung dengan klip, Anda dapat menggunakan perintah seperti:

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

Di sinilah saya akan menyarankan seseorang dengan pengalaman lebih banyak mengambil dari. Saya tidak yakin apakah ada cara dalam mencoder untuk menambahkan transisi fading / melarutkan antara klip.

fideli
sumber