Filmini visti con VLC Media Player in una UserForm
di Mario Teccia e Gianni Giaccaglini
L’utility open source VLC Media Player è giustamente popolare, non solo perché gratuita e capace di supportare una gran varietà di formati audio e video, ma per il fatto meno noto che, una volta installato, fornisce una libreria (plug-in, in gergo) fruibile in ambienti Visual Basic e, per quel che qui interessa, VBA (Visual Basic Application edition).
Il visitatore di questo blog, Mario Teccia se n’è servito per implementare un interessante visore di filmini (.mpg e, volendo, derivati), rivisto con migliorie dal titolare di questo blog. Il modello incorpora tale plugin nella UserForm di un file Excel – FilminiVLC.xls - corredandola con controlli opportuni:
http://home/download/FigFilminiVLC-01.jpg [Figura 0]
Nota. La sostanza dei procedimenti è per lo più farina del sacco Teccia, G. G. ha ripulito il codice con aggiunta di un trucco nonché potenziando il Foglio1 di apertura (che nella versione Teccia prevedeva solo un pulsante di avvio della UserForm, posto nel Foglio1).
La funzione dei vari bottoni o barre di scorrimento, fin d’ora abbastanza chiara, verrà descritta fra breve, qui diciamo subito che a ciascuno è associato codice VBA fornito dal plug-in appena citato.
Operazione preliminare sine qua non:
- Scaricare se non è stato già fatto VLC Media Player, ad esempio da http://vlc-media-player.softonic.it/ ;
- Nell’Editor Visual Basic (Alt+F11 per recarvisi) scegliere Strumenti > Riferimenti poi attivare la casellina VideoLAN VLC ActiveX PlugIn come da figura seguente.
http://home/download/FigFilminiVLC-01.jpg [ Figura 1 ]
Il modello si può poi scaricare da questo link:
http://www.giannigiaccaglini.it/download/FilminiVLC.xls
Utilizzo del programmino
All’apertura si presenta il Foglio1, aperturista :
http://home/download/FigFilminiVLC-02.jpg [ Figura 2 ]
Diciamo subito che in tale foglio sono stati predefiniti i seguenti nomi:
- ElencoFilmini in colonna B, a partire da B2, comprendente i pathname dei film del cuore;
- FilmScelto nella cella unita sotto all’etichetta “Film scelto”.
Come tutti comprendono, la casella a discesa in alto, un Combo box di tipo ActiveX, ha due proprietà basilari: ListFillRange e LinkedCell associate rispettivamente a “ElencoFilmini” e “FilmScelto”, in guisa tale che da essa si attinge dall’elenco dei filmini, e la scelta si riversa nella cella che, in VBA, è Range(“FilmScelto”).
Attenzione. Va da sé che i pathname dei file .mpg di figura appartengono a chi scrive, pertanto vanno sostituiti con quelli di ciascuno. Si sappia poi che inserendo un ulteriore file subito sotto la lista il nome “ElencoFilmini” si adegua automaticamente, grazie alla macro dell’evento Change presente nel modulo Foglio1 (nell’Editor VBA):
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("ElencoFilmini")) Is Nothing Then Exit Sub
With Range("ElencoFilmini")(1)
Range(.Cells(1), .End(xlDown)).Name = "ElencoFilmini"
End With
End Sub
Già che ci siamo (nel modulo Foglio1) esaminiamo altre due macro ivi presenti così non ci pensiamo viepiù (o viemeno?, boh):
Private Sub CommandButton1_Click()
If Range("FilmScelto") = "" Then Exit Sub
UserForm1.Show 1
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
If Intersect(Target, Range("ElencoFilmini")) Is Nothing Then Exit Sub
Range("FilmScelto") = Target
End Sub
La seconda che... ho detto esprime un’alternativa al Combo box in virtù della quale un doppio clic su una delle celle dei film preferiti deposita la scelta in “FilmScelto”.
Una volta che nella cella “FilmScelto” c’è un nome di file corretto (magari immesso a mano) un clic sul CommanButton1 fa comparire la nostra UserForm1:
http://home/download/FigFilminiVLC-03.jpg [ Figura 3 ]
A questo punto l’utilizzo dei vari bottoni di tale finestra di dialogo è lasciata alla libera sperimentazione di chi legge, diciamo solo che delle due barre di scorrimento quella sotto l’area video permette di farlo andare avanti-e-indrè (che bel divertimento), mentre quella a destra regola il sonoro.
Le altre macro...
Al medesimo lettore affidiamo inoltre il non arduo compito di scoprire come è stata inserito l’oggetto che funge da finestra visiva, diciamo solo che, in gergo VBA, ha nome VLCPlugin1 (sarebbe VLCPlugin2, VLCPlugin3 ecc. con successivi incollaggi).
Portarsi nell’Editor VBA, attivare il modulo UserForm1 quindi premere F7, tasto che visualizza le diverse routine, d’evento e non solo. Cominciamo senz’altro con il codice del pulsante Avvia (CommdButton1), che semplicemente richiama l’omonima routine:
Dim SwIniz As Boolean
Sub Avvia()
If Not SwIniz Then
VLCPlugin1.addTarget (Range("FilmScelto")), Null, 0, 0
VLCPlugin1.Play
Do Until VLCPlugin1.Length <> 0
Loop
Dim LungFilm As Long
Dim Ore As Integer, Minuti As Integer, Secondi As Integer
LungFilm = VLCPlugin1.Length
OreMinSec LungFilm, Ore, Minuti, Secondi
Label1.Caption = "Durata = " & Ore & ":" & Minuti & ":" & Secondi
'ScrollBar1.Max = LungFilm 'VLCPlugin1.Lengt 'Di fatto INUTILE…
SwIniz = True
End If
End Sub
Private Sub cmdAvvia_Click()
Avvia
End Sub
Commenti stringati. La variabile a livello modulo SwIniz funge da commutatore per indicare l’avvenuto caricamento e visione di un filmino, effettuato con le due successive istruzioni basate sui metodi addTarget e Play del plug-in. Segue un ciclo che dura finché (Until) il nastro ha lunghezza, proprietà Length, diversa da zero. Ciò crea un’attesa senza che si veda nulla, dopo di che la lunghezza così (brutalmente?) calcolata è registrata in LungFilm (di tipo intero lungo, Long).
La Long serve poi a inserire nella Caption di Label1 un’indicazione del tipo “Durata = 0:12:11” ipotizzando le Ore, Minuti e Secondi che dura il film.
Nota Il film poi riparte dall’inizio e da solo,automaticamente . Il motivo, ignoto a chi scrive, è un fatto la cui scoperta assieme a quella per il calcolo di LungFilm col predetto ciclo Do Until... Loop è tutto merito del sullodato Teccia.
Ma da dove saltano fuori quelle ore, minuti e secondi? Premesso che la proprietà Length si esprime in millisecondi, tali variabili sono ricavate passando LungFilm alla routine seguente, ospitata in un Modulo1, seguita da una Sub di prova:
Sub OreMinSec(ByVal MilliSec As Long, _
ByRef Ore As Integer, Minuti As Integer, Secondi As Integer)
Dim DepSec As Long
DepSec = MilliSec \ 1000 ' Millisecondi => secondi
Ore = DepSec \ 3600
DepSec = DepSec - Ore * 3600
Minuti = DepSec \ 60
Secondi = DepSec - Minuti * 60
End Sub
Sub ProvaOreMinSec()
Dim QuestiMilliSec As Long
Dim Ore As Integer, Minuti As Integer, Secondi As Integer
QuestiMilliSec = 2 * 3600 + 12 * 60 + 25
QuestiMilliSec = QuestiMilliSec * 1000
MsgBox ("Millisecondi = " & QuestiMilliSec)
Dim msg As String
OreMinSec QuestiMilliSec, Ore, Minuti, Secondi
MsgBox Ore & ":" & Minuti & ":" & Secondi
End Sub
Il procedimento è affidato all’esegesi autogestita, con un solo commento: l’aver definito ByRef i tre ultimi argomenti fa sì che OreMinSec li elabori e li restituisca così come calcolati.
Piuttosto va data un’indicazione pragmatica: nel caso di clip corrotte, anche solo alla fine dello stream (come può avvenire con riprese da fotocamere) VLC Player semplicemente termina di brutto, idem il relativo plug-in. Niente di male? Non tanto, perché non c’è modo di intercettare tale errore con un On Error GoTo FileCorrotto o simili. Pazienza.
Chiudiamo il discorso riportando tutte le altre routine.
Private Sub cmdTempo_Click()
' Indica il tempo corrente nella Label2
Dim Ore As Integer
Dim Minuti As Integer
Dim Secondi As Integer
OreMinSec VLCPlugin1.Time, Ore, Minuti, Secondi
Label2.Caption = "Tempo = " & Ore & ":" & Minuti & ":" & Secondi
End Sub
Private Sub cmdPausa_Click()
' Fai una pausa, poi riprendi il filmino
On Error GoTo Fine
VLCPlugin1.pause
With cmdPausa
If .Caption = "Pausa" Then
.Caption = "Riprendi"
Else
.Caption = "Pausa"
End If
End With
Fine:
End Sub
Private Sub cmdStop_Click()
' Ferma il filmino
VLCPlugin1.stop
SwIniz = False
End Sub
Private Sub cmdRallenta_Click()
' Pulsante <<
On Error Resume Next
VLCPlugin1.playSlower
End Sub
Private Sub cmdAccelera_Click()
' Pulsante >>
On Error Resume Next
VLCPlugin1.playFaster
'VLCPlugin1.Time = VLCPlugin1.Time '???
End Sub
Private Sub cmdRiavvolgi_Click()
If SwIniz = True Then
ScrollBar1.Value = 1 ' Trucco sporco...
ScrollBar1.Value = 0
'VLCPlugin1.stop 'Possibile variante: stop anziché daccapo
SwIniz = False
Avvia
End If
End Sub
Private Sub cmdPienoSchermo_Click()
If Not SwIniz Then Exit Sub
Dim msg As String, titolo As String
msg = "Sei proprio sicuro? " & vbLf & "(a pieno schermo la maschera si blocca!"
titolo = "Attenzione, uomo avvisato..."
If MsgBox(msg, vbYesNo, titolo) = vbNo Then Exit Sub
VLCPlugin1.fullscreen
End Sub
Private Sub ScrollBar1_Change()
' Scorri in accordo con la prima scrollbar
VLCPlugin1.shuttle (ScrollBar1.Value)
End Sub
Private Sub ScrollBar2_Change()
' Regola il volume
VLCPlugin1.Volume = ScrollBar2.Value
End Sub
Private Sub ScrollBar3_Change()
End Sub
Private Sub cmdVaiA_Click()
End Sub
Osservazioni. I commenti e i nomi dei vari pulsanti dovrebbero essere parlanti, come i vari metodi e proprietà dell’oggetto VLCPlugin1. Per cui mi limito a dire che:
Ø VLCPlugin1.fullscreen dio sa perché crea un effetto a pieno schermo da cui non c’è verso di uscire (chi scopre l’eventuale segreto lo dica!), di qui il preavviso all’utente;
Ø Lo sporco trucco del pulsante RIAVVOLGI agisce sulla ScrollBar1, azzerandone il Value ma – si badi bene - facendole prima fare un passetto avanti altrimenti nisba, come dicono i liguri; chi sa perché? Non lo so, ma così è, se vi pare (Pirandello docet);
Ø Le ultime routine vuote sono lasciate all’iniziativa dei visitatori più creativi.
Versione pro che sfrutta il controllo CommonDialog
Questa variante che fa intervenire la normale (common) finestra di dialogo per i file di Office, ma adattandola a proprie esigenze, viene suggerita ai più esperti e, soprattutto, a quanti hanno buone doti di pazienza. Infatti il pur utile controllo di cui si parla può creare una situazione anomala: se lo si incorpora nel foglio di lavoro con aggiunta di codice VBA che lo richiama quando si va a salvare il file nascono strane proteste, del tipo “Non posso farlo perché l’oggetto è di sola lettura.” o qualcosa del genere. Chi scrive è riuscito a tirar dritto con successo, ma non lo garantisce a tutti...
Comunque ecco la mosse da compiere:
- Nella scheda Sviluppo di Excel 2007 o nell’equivalente menu di Excel 2003 in modalità Progettazione lanciare Inserisci poi dal tipo Controlli ActiveX scegliere Altri controlli...;
- Dalla lista che si apre scegliere Microsoft Common Dialog, versione 6;
- Trascinare l’oggetto sul foglio, senza preoccuparsi di dimensionarlo (ha forma e dimensioni fisse); volendo si possono fissarne varie proprietà da progetto, ma conviene lasciare quelle default, tra cui Visible = False;
- Aggiungere un pulsante ad hoc, diciamo CommandButton2 etichettato (Caption) “Scegli da disco” e uscire dalla modalità Progettazione.
Nota. Si consiglia di porre il pulsante davanti al Common dialog (più che altro per limitare interventi dell’utente finale, se quest’ultimo non è visibile).
Il cerchio si chiude con la routine associata al clic sul nuovo pulsante. Eccola:
Private Sub CommandButton2_Click()
With CommonDialog1
.DialogTitle = "Scegli il file"
.Enabled = True
'.Visible = True
'.Filter = "*.mpg"
.Filename = "*.mpg"
.ShowOpen
'.LinkedCell = Range("FilmScelto") 'Dà errore!
Range("FilmScelto") = .Filename
End With
End Sub
Tale macro agisce sull’oggetto CommonDialog1 fissandone varie proprietà. Quelle tradotte in commento o hanno dato errore o si sono rivelate superflue almeno ai nostri fini, tra cui Visible = True, sopravanzata dal metodo ShowOpen che visualizza la finestra in modalità appunto Open.
Di fatto si ottiene di navigare con familiarissime mosse, nell’albero del File System in tutti gli archivi di estensione mpg, col pathname completo del file selezionato che viene scaraventato nella nostra cella “FilmScelto”. A quel punto il gioco procede come da copione sopra descritto.
?>
?>