Differenze tra le versioni di "Effettuare una ripresa video mediante una WebCam con il Componente gb.media"

Da Gambas-it.org - Wikipedia.
 
(17 versioni intermedie di uno stesso utente non sono mostrate)
Riga 35: Riga 35:
 
    
 
    
 
  <FONT Color=gray>' ''Imposta la "DrawingArea" come superficie ove sarà mostrata la ripresa video:''</font>
 
  <FONT Color=gray>' ''Imposta la "DrawingArea" come superficie ove sarà mostrata la ripresa video:''</font>
   mp.SetWindow(dr)
+
   mp.SetWindow(dr) ' <SUP>&#091;[[#Note|Nota 1]]&#093;</sup>
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 70: Riga 70:
 
  '''Public''' Sub Form_Open()
 
  '''Public''' Sub Form_Open()
 
    
 
    
   Dim src, tim, snk As MediaControl
+
   Dim src, cnv, tim, bal, snk As MediaControl
 
   Dim ftr As MediaFilter
 
   Dim ftr As MediaFilter
 
    
 
    
Riga 85: Riga 85:
 
    
 
    
 
   src = New MediaControl(pl, "v4l2src")
 
   src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 +
  cnv = New MediaControl(pl, "videoconvert")
 
  <FONT Color=gray>' ''Nella finestra del video sarà mostrato anche il tempo trascorso dall'inizio della ripresa video:''</font>
 
  <FONT Color=gray>' ''Nella finestra del video sarà mostrato anche il tempo trascorso dall'inizio della ripresa video:''</font>
 
   tim = New MediaControl(pl, "timeoverlay")
 
   tim = New MediaControl(pl, "timeoverlay")
 +
<FONT Color=gray>' ''Inseriamo il plugin "videobalance" di GStreamer...''</font>
 +
  bal = New MediaControl(pl, "videobalance")
 +
<FONT Color=gray>' ''...e ne usiamo ad esempio la proprietà "brightness" impostando il suo valore a 0.8:''</font>
 +
  bal["brightness"] = 0.8
 
   snk = New MediaControl(pl, "xvimagesink")
 
   snk = New MediaControl(pl, "xvimagesink")
 
    
 
    
  <FONT Color=gray>' ''Colleghiamo fra loro i due plugin di "GStreamer":''</font>
+
  <FONT Color=gray>' ''Colleghiamo fra loro i cinque plugin di "GStreamer":''</font>
   src.LinkTo(tim)
+
   src.LinkTo(ftr)
   tim.LinkTo(ftr)
+
  ftr.LinkTo(cnv)
   ftr.LinkTo(snk)
+
  cnv.LinkTo(tim)
 +
   tim.LinkTo(bal)
 +
   bal.LinkTo(snk)
 
   snk.SetWindow(dr)
 
   snk.SetWindow(dr)
 
    
 
    
Riga 102: Riga 110:
 
    
 
    
 
  <FONT Color=gray>' ''Avvia la ripresa video:''</font>
 
  <FONT Color=gray>' ''Avvia la ripresa video:''</font>
  pl.State = Media.Playing
 
 
   pl.Play()
 
   pl.Play()
 
      
 
      
Riga 121: Riga 128:
 
    
 
    
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
   Dim src, snk As MediaControl
+
   Dim src, cnv, snk As MediaControl
 
   Dim ftr As MediaFilter
 
   Dim ftr As MediaFilter
 
    
 
    
Riga 127: Riga 134:
 
      
 
      
 
   src = New MediaControl(pl, "v4l2src")
 
   src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 +
  cnv = New MediaControl(pl, "videoconvert")
 
   snk = New MediaControl(pl, "xvimagesink")
 
   snk = New MediaControl(pl, "xvimagesink")
 
    
 
    
 
  <FONT Color=gray>' ''Colleghiamo fra loro i due plugin di "GStreamer":''</font>
 
  <FONT Color=gray>' ''Colleghiamo fra loro i due plugin di "GStreamer":''</font>
 
   src.LinkTo(ftr)
 
   src.LinkTo(ftr)
   ftr.LinkTo(snk)
+
   ftr.LinkTo(cnv)
 +
  cnv.LinkTo(snk)
 
    
 
    
 
  <FONT Color=gray>' ''Avvia la ripresa video:''</font>
 
  <FONT Color=gray>' ''Avvia la ripresa video:''</font>
  pl.State = Media.Playing
 
 
   pl.Play()
 
   pl.Play()
 
    
 
    
 
   While True
 
   While True
 
  <FONT Color=gray>' ''Il tempo trascorso dall'inizio della ripresa video viene mostrato in console/Terminale:''</font>
 
  <FONT Color=gray>' ''Il tempo trascorso dall'inizio della ripresa video viene mostrato in console/Terminale:''</font>
     Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
+
     Write "\rTempo: " & Time(0, 0, 0, pl.Position * 1000)
 +
    Wait 0.001
 
   Wend
 
   Wend
 
        
 
        
Riga 150: Riga 160:
 
    
 
    
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
   Dim src, tim, snk As MediaControl
+
   Dim src, cnv, tim, snk As MediaControl
 
   Dim ftr As MediaFilter
 
   Dim ftr As MediaFilter
 
    
 
    
Riga 156: Riga 166:
 
      
 
      
 
   src = New MediaControl(pl, "v4l2src")
 
   src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 
   ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 +
  cnv = New MediaControl(pl, "videoconvert")
 
   tim = New MediaControl(pl, "<FONT Color=#B22222>timeoverlay</font>")
 
   tim = New MediaControl(pl, "<FONT Color=#B22222>timeoverlay</font>")
 
   snk = New MediaControl(pl, "xvimagesink")
 
   snk = New MediaControl(pl, "xvimagesink")
 
    
 
    
  <FONT Color=gray>' ''Colleghiamo fra loro i due plugin di "GStreamer":''</font>
+
  <FONT Color=gray>' ''Colleghiamo fra loro i tre plugin di "GStreamer":''</font>
 
   src.LinkTo(ftr)
 
   src.LinkTo(ftr)
   ftr.LinkTo(tim)
+
   ftr.LinkTo(cnv)
 +
  cnv.LinkTo(tim)
 
   tim.LinkTo(snk)
 
   tim.LinkTo(snk)
 
    
 
    
 
  <FONT Color=gray>' ''Avvia la ripresa video:''</font>
 
  <FONT Color=gray>' ''Avvia la ripresa video:''</font>
  pl.State = Media.Playing
 
 
   pl.Play()
 
   pl.Play()
 
    
 
    
Riga 174: Riga 186:
 
    
 
    
 
  '''End'''
 
  '''End'''
 +
 +
 +
===Effettuare le riprese video con due o più WebCam contemporaneamente===
 +
Per effettuare le riprese video con due o più WebCam contemporaneamente è necessario creare e gestire in modo separato una ''PipeLine'' per il flusso dati video di ciscuna WebCam.
 +
 +
Mostriamo un esempio pratico, nel quale si effettua la ripresa video di due WebCam. Il video di ciascuna WebCam sarà mostrato in due distinte ''DrawingArea'' poste sul ''Form'':
 +
Private dr1 As DrawingArea
 +
Private dr2 As DrawingArea
 +
Private pl1 As MediaPipeline
 +
Private pl2 As MediaPipeline
 +
Private bo As Boolean
 +
 +
 +
'''Public''' Sub Form_Open()
 +
 
 +
  With dr1 = New DrawingArea(Me)
 +
    .X = 10
 +
    .Y = 10
 +
    .W = 480
 +
    .H = 320
 +
<FONT Color=gray>' ''Affinché la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":''</font>
 +
    .Background = Color.Black
 +
  End With
 +
 
 +
  With dr2 = New DrawingArea(Me)
 +
    .X = dr1.W + 40
 +
    .Y = 10
 +
    .W = 480
 +
    .H = 320
 +
<FONT Color=gray>' ''Affinché la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":''</font>
 +
    .Background = Color.Black
 +
  End With
 +
 
 +
  bo = True
 +
 
 +
'''End'''
 +
 +
 +
'''Public''' Sub Button1_Click()
 +
 
 +
  Dim src1, src2, cnv1, cnv2, snk1, snk2 As MediaControl
 +
 
 +
  pl1 = New MediaPipeline
 +
  pl2 = New MediaPipeline
 +
 
 +
  src1 = New MediaControl(pl1, "v4l2src")
 +
  src1["device"] = "/dev/video0"
 +
 
 +
  src2 = New MediaControl(pl2, "v4l2src")
 +
  src2["device"] = "/dev/video1"
 +
 
 +
  cnv1 = New MediaControl(pl1, "videoconvert")
 +
  cnv2 = New MediaControl(pl2, "videoconvert")
 +
 
 +
  snk1 = New MediaControl(pl1, "xvimagesink")
 +
  snk2 = New MediaControl(pl2, "xvimagesink")
 +
 
 +
<FONT Color=gray>' ''Colleghiamo fra loro i plugin di "GStreamer" della 1^ PipeLine:''</font>
 +
  src1.LinkTo(cnv1)
 +
  cnv1.LinkTo(snk1)
 +
 
 +
<FONT Color=gray>' ''Colleghiamo fra loro i plugin di "GStreamer" della 2^ PipeLine:''</font>
 +
  src2.LinkTo(cnv2)
 +
  cnv2.LinkTo(snk2)
 +
 
 +
<FONT Color=gray>' ''Impostiamo le due "DrawingArea" come superfici ove mostrare il video delle due WebCam:''</font>
 +
  snk1.SetWindow(dr1)
 +
  snk2.SetWindow(dr2)
 +
 
 +
<FONT Color=gray>' ''Avvia la ripresa video delle due webcam:''</font>
 +
  pl1.Play()
 +
  pl2.Play()
 +
 
 +
  While bo
 +
    Wait 0.001
 +
  Wend
 +
 
 +
<FONT Color=gray>' ''Chiude il flusso di dati video dalle webcam e libera la memoria:''</font>
 +
  pl1.Close
 +
  pl2.Close
 +
 
 +
<FONT Color=gray>' ''Chiude il Form:''</font>
 +
  Me.Close
 +
 
 +
'''End'''
 +
 
 +
 +
'''Public''' Sub Button2_Click()
 +
 
 +
  bo = False
 +
 
 +
'''End'''
 +
 +
Va detto che in taluni casi la parte finale della routine " ''Public Sub Button1_Click()''" può creare un errore nell'impostazione dello status del media. Pertanto essa va sostituita con il seguente frammento di codice:
 +
  ......
 +
  ......
 +
<FONT Color=gray>' ''Avvia la ripresa video delle due webcam:''</font>
 +
  While bo
 +
    pl1.Play()
 +
<FONT Color=gray>' ''Potrebbe anche rendersi necessario porre uno stop momentaneo alla ripresa video,''
 +
' ''al fine di evitare un errore di status del media. (Verificare questa eventuale necessità).''
 +
    ' '''pl1.Stop'''</font>
 +
   
 +
    pl2.Play()
 +
<FONT Color=gray>' ''Potrebbe anche rendersi necessario porre uno stop momentaneo alla ripresa video,''
 +
' ''al fine di evitare un errore di status del media. (Verificare questa eventuale necessità).''
 +
    ' '''pl2.Stop'''</font>
 +
    Wait 0.001
 +
  Wend
 +
 
 +
<FONT Color=gray>' ''Chiude il flusso di dati video dalle webcam e libera la memoria:''</font>
 +
  pl1.Close
 +
  pl2.Close
 +
 
 +
<FONT Color=gray>' ''Chiude il Form:''</font>
 +
  Me.Close
 +
 
 +
'''End'''
 +
Al riguardo va rilevato che questa soluzione rallenta la fluidità della ripresa video.
 +
 +
 +
===Ruotare il video mostrato===
 +
Per ruotare il video di una ripresa, è possibile utilizzare il ''plugin'' "videoflip" di GStreamer. <SUP>&#091;[[#Note|Nota 2]]&#093;</sup>
 +
 +
Nel seguente esempio pratico si userà una "Enumerazione" (come riportato nelle risorse del ''plugin'' "videoflip" di GStreamer, ma bisognerà cambiare il trattino - presente nel nome di alcuni identificatori - in un trattino in basso.
 +
 +
Private Enum none = 0, clockwise, rotate_180, counterclockwise, horizontal_flip,
 +
              vertical_flip, upper_left_diagonal, upper_right_diagonal, automatic
 +
     
 +
 +
'''Public''' Sub Main()
 +
 
 +
  Dim pl As MediaPipeline
 +
  Dim src, cnv, flp, snk As MediaControl
 +
  Dim ftr As MediaFilter
 +
 
 +
  pl = New MediaPipeline
 +
 
 +
  src = New MediaControl(pl, "v4l2src")
 +
  src["device"] = "/dev/video0"
 +
  ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 +
  flp = New MediaControl(pl, "videoflip")
 +
  flp["method"] = rotate_180
 +
  cnv = New MediaControl(pl, "videoconvert")
 +
  snk = New MediaControl(pl, "xvimagesink")
 +
 
 +
<FONT Color=gray>' ''Colleghiamo fra loro i plugin di "GStreamer":''</font>
 +
  src.LinkTo(ftr)
 +
  ftr.LinkTo(flp)
 +
  flp.LinkTo(cnv)
 +
  cnv.LinkTo(snk)
 +
 
 +
<FONT Color=gray>' ''Avvia la ripresa video:''</font>
 +
  pl.Play()
 +
 
 +
  While True
 +
<FONT Color=gray>' ''Il tempo trascorso dall'inizio della ripresa video viene mostrato in console/Terminale:''</font>
 +
    Write "\rTempo: " & Time(0, 0, 0, pl.Position * 1000)
 +
    Wait 0.001
 +
  Wend
 +
 
 +
'''End'''
 +
 +
 +
 +
=Note=
 +
[1] Riguardo all'Oggetto grafico da usare con il Metodo ".SetWindow()" della Classe "MediaPlayer", B. Minisini ha chiarito che esso necessita di un controllo che abbia una vera finestra X11 (o Wayland), altrimenti si userà il primo controllo genitore con una finestra reale, che di solito è quella di primo livello.
 +
 +
[2] Vedere la pagina di GStreamer relativa al plugin "videoflip": https://gstreamer.freedesktop.org/documentation/videofilter/videoflip.html?gi-language=c

Versione attuale delle 08:02, 5 ott 2021

Il Componente gb.media, utilizzando particolari plugin di GStreamer, consente di effettuare una ripresa video mediante una WebCam.


Uso della Classe MediaPlayer

Questa modalità standard prevede l'utilizzo della Classe MediaPlayer.

Esempio in un'applicazione grafica

Mostriamo di seguito un esempio essenziale con un'applicazione grafica. Il video sarà mostrato all'interno di una DrawingArea posta sul Form principale.

Private dr As DrawingArea
Private mp As MediaPlayer


Public Sub Form_Open()
 
 Dim snk As MediaControl
       
  With dr = New DrawingArea(Me)
    .X = 10
    .Y = 10
    .W = 640
    .H = 480
' Affinche la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":
    .Background = Color.Black
  End With
  
  With mp = New MediaPlayer
' Imposta il dispositivo sorgente video della WebCam (presumiamo che sia il file-device "/dev/video0"):
    .Url = "v4l2:///dev/video0"
  End With
  
  snk = New MediaControl(mp, "xvimagesink")
' Imposta "xvimagesink" come plugin per l'uscita video:
  mp.Video.Output = snk
  
' Imposta la "DrawingArea" come superficie ove sarà mostrata la ripresa video:
  mp.SetWindow(dr)  ' [Nota 1]
 
End


Public Sub Button1_Click()
  
' Avvia la ripresa video:
  mp.Play()
    
End


Public Sub Button2_Click()
 
' Arresta la ripresa video:
  mp.Stop()
  
End



Uso della Classe MediaPipeline

Questa modalità prevede l'utilizzo della Classe MediaPipeline che fornisce il supporto di collegamento dei vari plugin di GStreamer per consentire la ripresa video.

Esempio in un'applicazione grafica

Mostriamo di seguito un esempio essenziale con un'applicazione grafica. Il video sarà mostrato all'interno di una DrawingArea posta sul Form principale.

Private dr As DrawingArea
Private pl As MediaPipeline


Public Sub Form_Open()
 
 Dim src, cnv, tim, bal, snk As MediaControl
 Dim ftr As MediaFilter
  
  With dr = New DrawingArea(Me)
    .X = 10
    .Y = 10
    .W = 640
    .H = 480
' Affinche la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":
    .Background = Color.Black
  End With
  
  pl = New MediaPipeline 
  
  src = New MediaControl(pl, "v4l2src")
  src["device"] = "/dev/video0"
  ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
  cnv = New MediaControl(pl, "videoconvert")
' Nella finestra del video sarà mostrato anche il tempo trascorso dall'inizio della ripresa video:
  tim = New MediaControl(pl, "timeoverlay")
' Inseriamo il plugin "videobalance" di GStreamer...
  bal = New MediaControl(pl, "videobalance")
' ...e ne usiamo ad esempio la proprietà "brightness" impostando il suo valore a 0.8:
  bal["brightness"] = 0.8
  snk = New MediaControl(pl, "xvimagesink")
  
' Colleghiamo fra loro i cinque plugin di "GStreamer":
  src.LinkTo(ftr)
  ftr.LinkTo(cnv)
  cnv.LinkTo(tim)
  tim.LinkTo(bal)
  bal.LinkTo(snk)
  snk.SetWindow(dr)
 
End


Public Sub Button1_Click()
  
' Avvia la ripresa video:
  pl.Play()
    
End


Public Sub Button2_Click()
 
' Arresta la ripresa video:
  pl.Stop
  
End


Esempio in un'applicazione a riga di comando

Mostriamo di seguito un esempio essenziale con un'applicazione a riga di comando:

Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim src, cnv, snk As MediaControl
 Dim ftr As MediaFilter
 
  pl = New MediaPipeline 
   
  src = New MediaControl(pl, "v4l2src")
  src["device"] = "/dev/video0"
  ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
  cnv = New MediaControl(pl, "videoconvert")
  snk = New MediaControl(pl, "xvimagesink")
 
' Colleghiamo fra loro i due plugin di "GStreamer":
  src.LinkTo(ftr)
  ftr.LinkTo(cnv)
  cnv.LinkTo(snk)
  
' Avvia la ripresa video:
  pl.Play()
  
  While True
' Il tempo trascorso dall'inizio della ripresa video viene mostrato in console/Terminale:
    Write "\rTempo: " & Time(0, 0, 0, pl.Position * 1000)
    Wait 0.001
  Wend
     
End

Mostrare nel video anche il tempo trascorso

Per mostrare nella finestra del video anche il tempo trascorso dall'inizio della ripresa video, è necessario utilizzare (come abbiamo già visto nell'esempio con un'applicazione grafica) il plugin timeoverlay fornito da GStreamer:

Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim src, cnv, tim, snk As MediaControl
 Dim ftr As MediaFilter
 
  pl = New MediaPipeline 
   
  src = New MediaControl(pl, "v4l2src")
  src["device"] = "/dev/video0"
  ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
  cnv = New MediaControl(pl, "videoconvert")
  tim = New MediaControl(pl, "timeoverlay")
  snk = New MediaControl(pl, "xvimagesink")
  
' Colleghiamo fra loro i tre plugin di "GStreamer":
  src.LinkTo(ftr)
  ftr.LinkTo(cnv)
  cnv.LinkTo(tim)
  tim.LinkTo(snk)
  
' Avvia la ripresa video:
  pl.Play()
  
  While True
    Sleep 0.01
  Wend
  
End


Effettuare le riprese video con due o più WebCam contemporaneamente

Per effettuare le riprese video con due o più WebCam contemporaneamente è necessario creare e gestire in modo separato una PipeLine per il flusso dati video di ciscuna WebCam.

Mostriamo un esempio pratico, nel quale si effettua la ripresa video di due WebCam. Il video di ciascuna WebCam sarà mostrato in due distinte DrawingArea poste sul Form:

Private dr1 As DrawingArea
Private dr2 As DrawingArea
Private pl1 As MediaPipeline
Private pl2 As MediaPipeline
Private bo As Boolean


Public Sub Form_Open()
 
 With dr1 = New DrawingArea(Me)
   .X = 10
   .Y = 10
   .W = 480
   .H = 320
' Affinché la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":
   .Background = Color.Black
 End With
 
 With dr2 = New DrawingArea(Me)
   .X = dr1.W + 40
   .Y = 10
   .W = 480
   .H = 320
' Affinché la "DrawingArea" mostri il video, è assolutamente necessario attribuire un colore qualsiasi alla sua proprietà ".Background":
   .Background = Color.Black
 End With
 
 bo = True
  
End


Public Sub Button1_Click()
 
 Dim src1, src2, cnv1, cnv2, snk1, snk2 As MediaControl
 
  pl1 = New MediaPipeline 
  pl2 = New MediaPipeline 
  
  src1 = New MediaControl(pl1, "v4l2src")
  src1["device"] = "/dev/video0"
  
  src2 = New MediaControl(pl2, "v4l2src")
  src2["device"] = "/dev/video1"
  
  cnv1 = New MediaControl(pl1, "videoconvert")
  cnv2 = New MediaControl(pl2, "videoconvert")
  
  snk1 = New MediaControl(pl1, "xvimagesink")
  snk2 = New MediaControl(pl2, "xvimagesink")
  
' Colleghiamo fra loro i plugin di "GStreamer" della 1^ PipeLine:
  src1.LinkTo(cnv1)
  cnv1.LinkTo(snk1)
  
' Colleghiamo fra loro i plugin di "GStreamer" della 2^ PipeLine:
  src2.LinkTo(cnv2)
  cnv2.LinkTo(snk2)
  
' Impostiamo le due "DrawingArea" come superfici ove mostrare il video delle due WebCam:
  snk1.SetWindow(dr1)
  snk2.SetWindow(dr2)
  
' Avvia la ripresa video delle due webcam:
  pl1.Play()
  pl2.Play()
  
  While bo
    Wait 0.001
  Wend
  
' Chiude il flusso di dati video dalle webcam e libera la memoria:
  pl1.Close
  pl2.Close
  
' Chiude il Form:
  Me.Close
  
End
  

Public Sub Button2_Click()
 
 bo = False
 
End

Va detto che in taluni casi la parte finale della routine " Public Sub Button1_Click()" può creare un errore nell'impostazione dello status del media. Pertanto essa va sostituita con il seguente frammento di codice:

  ......
  ......
' Avvia la ripresa video delle due webcam:
  While bo
    pl1.Play()
' Potrebbe anche rendersi necessario porre uno stop momentaneo alla ripresa video,
' al fine di evitare un errore di status del media. (Verificare questa eventuale necessità).
    ' pl1.Stop
    
    pl2.Play()
' Potrebbe anche rendersi necessario porre uno stop momentaneo alla ripresa video,
' al fine di evitare un errore di status del media. (Verificare questa eventuale necessità).
    ' pl2.Stop
    Wait 0.001
  Wend
  
' Chiude il flusso di dati video dalle webcam e libera la memoria:
  pl1.Close
  pl2.Close
  
' Chiude il Form:
  Me.Close
  
End

Al riguardo va rilevato che questa soluzione rallenta la fluidità della ripresa video.


Ruotare il video mostrato

Per ruotare il video di una ripresa, è possibile utilizzare il plugin "videoflip" di GStreamer. [Nota 2]

Nel seguente esempio pratico si userà una "Enumerazione" (come riportato nelle risorse del plugin "videoflip" di GStreamer, ma bisognerà cambiare il trattino - presente nel nome di alcuni identificatori - in un trattino in basso.

Private Enum none = 0, clockwise, rotate_180, counterclockwise, horizontal_flip,
             vertical_flip, upper_left_diagonal, upper_right_diagonal, automatic
      

Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim src, cnv, flp, snk As MediaControl
 Dim ftr As MediaFilter
 
 pl = New MediaPipeline 
  
 src = New MediaControl(pl, "v4l2src")
 src["device"] = "/dev/video0"
 ftr = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=30/1")
 flp = New MediaControl(pl, "videoflip")
 flp["method"] = rotate_180
 cnv = New MediaControl(pl, "videoconvert")
 snk = New MediaControl(pl, "xvimagesink")
 
' Colleghiamo fra loro i plugin di "GStreamer":
 src.LinkTo(ftr)
 ftr.LinkTo(flp)
 flp.LinkTo(cnv)
 cnv.LinkTo(snk)
 
' Avvia la ripresa video:
 pl.Play()
 
 While True
' Il tempo trascorso dall'inizio della ripresa video viene mostrato in console/Terminale:
   Write "\rTempo: " & Time(0, 0, 0, pl.Position * 1000)
   Wait 0.001
 Wend
  
End


Note

[1] Riguardo all'Oggetto grafico da usare con il Metodo ".SetWindow()" della Classe "MediaPlayer", B. Minisini ha chiarito che esso necessita di un controllo che abbia una vera finestra X11 (o Wayland), altrimenti si userà il primo controllo genitore con una finestra reale, che di solito è quella di primo livello.

[2] Vedere la pagina di GStreamer relativa al plugin "videoflip": https://gstreamer.freedesktop.org/documentation/videofilter/videoflip.html?gi-language=c