Catturare con il componente gb.media quanto mostrato dalla finestra di un programma e farne un file video

Da Gambas-it.org - Wikipedia.

Con le risorse del Componente "gb.media" è possibile catturare immagini di quanto avviene in una finestra di un programma e farne un file video.

Va detto che questa possibilità di registrazione video è estesa ovviamente anche alla Scrivania (Desktop), e che in tal caso sarà catturato anche il puntatore del mouse.

Per individuare la finestra, che si intende registrare, bisognerà passare alla Proprietà "xid" del MediaControl "ximagesrc" il numero identificativo della finestra medesima. Per la Scrivania è anche possibile impostare più semplicemente il suo ID di default uguale a 0 (zero).

Creare un file video in formato MP4

Nel seguente esempio si cattureranno i dati video (senza audio) mostrati in un Controllo MediaView, dai quali si creerà un file video, privo di audio, in formato MP4.

Private pl As MediaPipeline


Public Sub Form_Open()

 Dim src, cnv, enc, mux, snk As MediaControl

 pl = New MediaPipeline 

 src = New MediaControl(pl, "ximagesrc")
' Assegna alla proprietà "xid" del plugin "ximagesrc" il numero idetificativo della "DrawingArea", affinché catturi quanto da essa visualizzato:
 src["xid"] = 0
 cnv = New MediaControl(pl, "videoconvert")
 enc = New MediaControl(pl, "x264enc")
 enc["pass"] = 5
 enc["quantizer"] = 26
 enc["speed-preset"] = 6
 mux = New MediaControl(pl, "mp4mux")
 mux["fragment-duration"] = 2048
 snk = New MediaControl(pl, "filesink")
' Imposta il percorso del file video finale del formato "mkv" (Matroska):
 snk["location"] = "/tmp/file.mp4"

' Collega i plugin di "GStreamer" utilizzati:
 src.LinkTo(cnv)
 cnv.LinkTo(enc)
 enc.LinkTo(mux)
 mux.LinkTo(snk)

End

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

End

Public Sub Button2_Click()

' Ferma la registrazione:
 pl.Stop
 pl.Close

 Print "Registrazione terminata"

End


Creare un file video in formato Matroska

Nel seguente esempio si cattureranno i dati video (senza audio) mostrati in un Controllo MediaView, dai quali si creerà un file video, privo di audio, in formato Matroska (.mkv).
Ai fini dell'esempio si dovrà utilizzare le Classi "MediaControl" e "MediaPipeline" del Componente gb.media
Va precisato che il Controllo "MediaView" è composto da "Figli" e "Figli secondari" (...nipoti). Uno di questi "sub-Children" è una "DrawingArea", che in sostanza è l'Oggetto con cui il Controllo "MediaView" visualizza immagini e video.
Identificheremo innanzitutto il numero identificativo di questa "DrawingArea", costitutiva del Controllo "MediaView", e con una particolare Proprietà del plugin "ximagesrc" cattureremo il video che essa mostra.

Event Evento


Public Sub Form_Open()

 Me.Show
 Wait 0.1

 MediaView1.URL = "/percorso/del/media/da/catturare"

 Repeat 
    Wait 0.01
 Until MediaView1.Position > 0.0

 Raise Evento

End

Public Sub Form_Evento()

 Dim ob As Object
 Dim pn1, pn2 As Panel
 Dim DrawingArea1 As DrawingArea
 Dim pl As MediaPipeline
 Dim src, cnv, enc, mux, snk As MediaControl
 
' Una parte dell'ampia "famiglia" che compone il Controllo "MediaView":
 ob = MediaView1.Children[0]
 pn1 = ob.Children[0]
 pn2 = pn1.Children[0]
 DrawingArea1 = pn2.Children[0]
 
 pl = New MediaPipeline 
 
 src = New MediaControl(pl, "ximagesrc")
' Assegna alla proprietà "xid" del plugin "ximagesrc" il numero idetificativo della "DrawingArea", affinché catturi quanto da essa visualizzato:
 src["xid"] = DrawingArea1.Id
 cnv = New MediaControl(pl, "videoconvert")
 enc = New MediaControl(pl, "x264enc")
 mux = New MediaControl(pl, "matroskamux") 
 snk = New MediaControl(pl, "filesink")
' Imposta il percorso del file video finale del formato "mkv" (Matroska):
 snk["location"] = "/tmp/file.mkv"
  
' Collega i plugin di "GStreamer" utilizzati:
 src.LinkTo(cnv)
 cnv.LinkTo(enc)
 enc.LinkTo(mux)
 mux.LinkTo(snk)

 pl.play

 Wait MediaView1.Duration
 
 Print "File video creato !"

End

In quest'altro esempio verrà catturata la Scrivania:

Private pl As MediaPipeline


Public Sub Form_Open()

 Dim src, cnv, enc, mux, snk As MediaControl

 pl = New MediaPipeline 

 src = New MediaControl(pl, "ximagesrc")
' Assegna alla proprietà "xid" del plugin "ximagesrc" il numero idetificativo della "Scrivania", affinché catturi quanto da essa visualizzato:
 src["xid"] = 0
 cnv = New MediaControl(pl, "videoconvert")
 enc = New MediaControl(pl, "x264enc")
 mux = New MediaControl(pl, "matroskamux") 
 snk = New MediaControl(pl, "filesink")
' Imposta il percorso del file video finale del formato "mkv" (Matroska):
 snk["location"] = "/tmp/file.mkv"

 src.LinkTo(cnv)
 cnv.LinkTo(enc)
 enc.LinkTo(mux)
 mux.LinkTo(snk)

End

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

Public Sub Button2_Click()

' Ferma la registrazione:
 pl.Stop
 pl.Close

 Print "Registrazione Terminata"

End


Creare un file video in formato OGV-Theora

Creare un video privo di audio

In questo paragrafo mostreremo alcuni esempi per generare un file video OGV, però privo di audio.

In particolare di seguito mostriamo un esempio pratico, nel quale si cattureranno immagini di quanto accade sulla Scrivania e si produrrà con esse un file video OGV muto.

Private pl As MediaPipeline


Public Sub Form_Open()
 
  Dim src, cnv, enc, mux, snk As MediaControl
  Dim ftr As MediaFilter

  pl = New MediaPipeline 
  
  src = New MediaControl(pl, "ximagesrc")
' Si assegna alla proprietà "xid" il numero identificativo della finestra da registrare:
  src["xid"] = 0
' La cattura avviene con 1 frame al secondo:
  ftr = New MediaFilter(pl, "video/x-raw,framerate=4/1")
  cnv = New MediaControl(pl, "videoconvert")
  enc = New MediaControl(pl, "theoraenc")
  mux = New MediaControl(pl, "oggmux")
  snk = New MediaControl(pl, "filesink")
' Si imposta il percorso del file video finale di formato .ogg:
  snk["location"] = "/tmp/video.ogv"
  
' Si collegano fra loro i plugin di "GStreamer" sopra utilizzati:
  src.LinkTo(ftr)
  ftr.LinkTo(cnv)
  cnv.LinkTo(enc)
  enc.LinkTo(mux)
  mux.LinkTo(snk)
  
End

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

Public Sub Button2_Click()
 
' Ferma la registrazione:
 pl.Stop
 pl.Close
 
 Print "Registrazione fermata"
  
End

Un'altra modalità, sempre con il fine di ottenere un video di formato "OGG" privo di audio, può essere quella in cui una prima fase vengono creati i file immagine in formato .png, che rappresentano vari screenshot della finestra del programma prescelto, e in una seconda fase si genera da tali molteplici file immagine il vero e proprio file video di formato "OGG".
Va precisato che le schermate rappresenteranno esclusivamente quanto accade "all'interno" della finestra aperta prescelta. Pertanto, qualora un'altra finestra o un'altro elemento grafico presente sulla Scrivania dovesse coprire in tutto o in parte la finestra prescelta per gli screenshot, essi non saranno registrati nelle schermate, e pertanto non appariranno nel video finale.

E' necessario attivare, oltre ovviamente al Componente gb.media, anche i Componenti "gb.desktop" e "gb.desktop.x11".

Nell'esempio, che segue, faremo gli screenshot ed il successivo video OGG di quanto accade esclusivamente "all'interno" della finestra aperta di un Terminale.

Private pl As MediaPipeline


Public Sub Form_Open()
 
  Dim wid As Integer
  Dim src, sca, con, png, snk As MediaControl
  Dim flt As MediaFilter

' Innanzitutto verifica l'esistenza della Cartella, ove verranno salvati i file immagini delle schermate. Se non esiste, la crea.
  If Not Exist("/tmp/VIDEO") Then Mkdir "/tmp/VIDEO"
 
' Passa il nome visibile della finestra prescelta e ne individua il numero identificativo:
  wid = ID_Finestra("Terminal")
  
  pl = New MediaPipeline
  
  src = New MediaControl(pl, "ximagesrc")
' Imposta l'angolo x in alto a sinistra della schermata rispetto alla superficie del Terminale:
  src["startx"] = 0
  src["use-damage"] = 0
  src["xid"] = wid
  sca = New MediaControl(pl, "videoscale")
  sca["method"] = 0
' Imposta la dimensione del file immagine finale, nonché il valore di 4 fotogrammi al secondo:
  flt = New MediaFilter(pl, "video/x-raw,width=640,height=480,framerate=4/1")
  con = New MediaControl(pl, "videoconvert")
  png = New MediaControl(pl, "pngenc")
  snk = New MediaControl(pl, "multifilesink")
  snk["location"] = "/tmp/VIDEO/fotogramma%01d.png" 
  
' Vengono collegati i vari plug-in di GStreamer utilizzati:
  src.LinkTo(sca)
  sca.LinkTo(flt)
  flt.LinkTo(con)
  con.LinkTo(png)
  png.LinkTo(snk)
  
End

Public Sub Button1_Click()
 
' Effettua le schermate:
 pl.Play()
  
End

Public Sub Button2_Click()
 
' Chiude il flusso arrestando la produzione delle schermate:
 pl.Stop()
 pl.Close()
  
 Genera_Video()
 
End

Private Function ID_Finestra(titolo As String) As Integer
 
  Dim i As Integer
 
  i = Desktop.FindWindow(titolo, Null, Null)[0]
  
  Return i
  
End

Private Procedure Genera_Video()
 
  Dim src, png, con, rat, thr, mux, snk As MediaControl
 
  pl = New MediaPipeline
  
  src = New MediaControl(pl, "multifilesrc")
  src["location"] = "/tmp/VIDEO/fotogramma%01d.png"
  src["index"] = 0
' Imposta il valore di 4 fotogrammi al secondo:
  src["caps"] = "image/png,framerate=4/1"
  png = New MediaControl(pl, "pngdec")
  con = New MediaControl(pl, "videoconvert")
  rat = New MediaControl(pl, "videorate")
  thr = New MediaControl(pl, "theoraenc")
  mux = New MediaControl(pl, "oggmux")
  snk = New MediaControl(pl, "filesink")
  snk["location"] = "/tmp/video.ogg"
   
' Vengono collegati i vari plug-in di GStreamer utilizzati:
  src.LinkTo(png)
  png.LinkTo(con)
  con.LinkTo(rat)
  rat.LinkTo(thr)
  thr.LinkTo(mux)
  mux.LinkTo(snk)
   
End

Public Sub Button3_Click()
 
' Genera il file video finale:
 pl.Play()
 
End

Nella seguente terza modalità si utilizzerà il Componente gb.media soltanto nella seconda fase, ossia quella in cui viene generato il file video ".ogv".
Bisognerà comunque attivare anche i Componenti gb.desktop e gb.desktop.x11, che permetteranno di utilizzare il Metodo ".GetScreenshot()" della Classe DesktopWindow, per ottenere gli screenshot della finestra prescelta.

Anche in questo esempio pratico che segue, faremo gli screenshot ed il successivo video OGG di quanto accade nella finestra aperta di un Terminale.

Va comunque precisato che in questo caso, differentemnte dalla mosdalità precedentemente vista, sarà registrato, non solo quanto accade "nella", ma anche quanto accade eventualmente al di sopra (ad esempio la sovrapposizione di un'altra finestra o il passaggio del puntatore del mouse).

Private i As Integer
Private tempus As Timer
Private dw As DesktopWindow
Private pl As MediaPipeline


Public Sub Form_Open()
 
  Dim wid As Integer

' Innanzitutto verifica l'esistenza della Cartella, ove verranno salvati i file immagini delle schermate. Se non esiste, la crea.
  If Not Exist("/tmp/VIDEO") Then Mkdir "/tmp/VIDEO"
  
' Individua il numero identificativo della finestra del Terminale...
  wid = Desktop.FindWindow("Terminal", Null, Null)[0] 
  
' ...e lo passa all'oggetto "DesktopWindow" da creare:
  dw = New DesktopWindow(wid)
  
End

Public Sub Button1_Click()
 
 With tempus = New Timer As "Tempus"
' Imposta 250 millisecondi, per ottenere 4 schermate al secondo:
   .Delay = 250
   .Start
 End With
  
End

Public Sub Tempus_Timer()
 
  Dim pc As Picture
 
  pc = dw.GetScreenshot()
  
  pc.Save("/tmp/VIDEO/fotogramma" & CStr(i) & ".png", 100)
  
  Inc i
  
End

Public Sub Button2_Click()
 
 tempus.Stop
 
 Genera_Video()
 
End

Private Procedure Genera_Video()
 
  Dim src, png, con, rat, thr, mux, snk As MediaControl
 
  pl = New MediaPipeline
  
  src = New MediaControl(pl, "multifilesrc")
  src["location"] = "/tmp/VIDEO/fotogramma%1d.png"
  src["index"] = 0
' Imposta il valore di 4 fotogrammi al secondo:
  src["caps"] = "image/png,framerate=4/1"
  png = New MediaControl(pl, "pngdec")
  con = New MediaControl(pl, "videoconvert")
  rat = New MediaControl(pl, "videorate")
  thr = New MediaControl(pl, "theoraenc")
  mux = New MediaControl(pl, "oggmux")
  snk = New MediaControl(pl, "filesink")
  snk["location"] = "/tmp/video.ogg"

' Vengono collegati i vari plug-in di GStreamer utilizzati:
  src.LinkTo(png)
  png.LinkTo(con)
  con.LinkTo(rat)
  rat.LinkTo(thr)
  thr.LinkTo(mux)
  mux.LinkTo(snk)
  
End

Public Sub Button3_Click()
 
' Genera il file video finale:
 pl.Play()
 
End


Creare un video comprensivo di audio

In questo paragrafo mostreremo un esempio per generare un file video OGV comprensivo di audio, registrato contemporaneamente al video mediante ad esempio un microfono.

Va sottolineato che dopo aver premuto il tasto di avvio della registrazione audio-video, se si sta registrando quanto accade nella finestra di un programma (e dunque non della Scrivania), bisognerà porre come finestra attiva quella del programma interessato (ad esempio con il mouse oppure via codice). Medesima attenzione bisognerà prestare subito dopo aver arrestato la registrazione.

Private pl As MediaPipeline
Private temporaneo as String


Public Sub Form_Open()
 
  Dim srcv, vcon, que1, the, que2, srca, que3, acon, vor, que4, ogg, snk As MediaControl
  Dim flv, fla As MediaFilter
  
  temporaneo = Temp
  
  pl = New MediaPipeline 
  
  srcv = New MediaControl(pl, "ximagesrc")
' Si assegna alla proprietà "xid" il numero identificativo della finestra da registrare:
  srcv["xid"] = numero_identificativo_della_finestra
' La cattura avviene con 2 frame al secondo:
  flv = New MediaFilter(pl, "video/x-raw,framerate=2/1")
  vcon = New MediaControl(pl, "videoconvert")
  que1 = New MediaControl(pl, "queue")
  the = New MediaControl(pl, "theoraenc")
  que2 = New MediaControl(pl, "queue")
  srca = New MediaControl(pl, "alsasrc")
  fla = New MediaFilter(pl, "audio/x-raw,rate=44100,channels=2,depth=16,bit=16")
  que3 = New MediaControl(pl, "queue")
  acon = New MediaControl(pl, "audioconvert")
  vor = New MediaControl(pl, "vorbisenc")
  que4 = New MediaControl(pl, "queue")
  ogg = New MediaControl(pl, "oggmux")
  snk = New MediaControl(pl, "filesink")
  snk["location"] = temporaneo
   
' Parte video:
  srcv.LinkTo(flv)
  flv.LinkTo(vcon)
  vcon.LinkTo(que1)
  que1.LinkTo(the)
  the.LinkTo(que2)
  que2.LinkTo(ogg)
' Parte audio:
  srca.LinkTo(fla)
  fla.LinkTo(que3)
  que3.LinkTo(acon)
  acon.LinkTo(vor)
  vor.LinkTo(que4)
' Combinazione dei dati audio e video:
  que4.LinkTo(ogg)
' Creazione del file .ogv finale:
  ogg.LinkTo(snk)
  
End

Public Sub Button1_Click()
  
' Avvia la ripresa video:
 pl.Play()
 
 Desktop.ActiveWindow = numero_identificativo_della_finestra
  
End

Public Sub Button2_Click()
 
' Ferma la registrazione:
 pl.Stop
 pl.Close
 
 Desktop.ActiveWindow = numero_identificativo_della_finestra
 Copy temporaneo To "/tmp/video.ogv"
 Print "Registrazione fermata"
 Me.close
 
End


Vediamo ora un esempio con un'applicazione a riga di comando.

Anche in questo caso bisognerà avere cura di porre come finestra attiva quella del programma interessato sia dopo l'avvio che dopo l'arresto della registrazione video-audio). Per fare ciò, pur in assenza di ambiente grafico, si potrà comunque attivare il Componente grafico (ad esempio) gb.gtk (meglio non utilizzare le risorse di QT, per non incorrere in eventuali incompatibilità fra le risorse di GSreamer e QT), il quale percmetterà di attivare anche il Componente gb.desktop per il successivo uso della proprietà "ActiveWindow".

Private bo As Boolean


Public Sub Main()
 
  Dim pl As MediaPipeline
  Dim srcv, vcon, que1, the, que2, srca, que3, acon, vor, que4, ogg, snk As MediaControl
  Dim flv, fla As MediaFilter
  Dim temporaneo As String

  temporaneo = Temp
    
  pl = New MediaPipeline 
  
  srcv = New MediaControl(pl, "ximagesrc")
  srcv["xid"] = &05600006
  flv = New MediaFilter(pl, "video/x-raw,framerate=2/1")
  vcon = New MediaControl(pl, "videoconvert")
  que1 = New MediaControl(pl, "queue")
  the = New MediaControl(pl, "theoraenc")
  que2 = New MediaControl(pl, "queue")
  srca = New MediaControl(pl, "alsasrc")
  fla = New MediaFilter(pl, "audio/x-raw,rate=44100,channels=2,width=16,depth=16")
  que3 = New MediaControl(pl, "queue")
  acon = New MediaControl(pl, "audioconvert")
  vor = New MediaControl(pl, "vorbisenc")
  que4 = New MediaControl(pl, "queue")
  ogg = New MediaControl(pl, "oggmux")
  snk = New MediaControl(pl, "filesink")
  snk["location"] = temporaneo
   
' Parte video:
  srcv.LinkTo(flv)
  flv.LinkTo(vcon)
  vcon.LinkTo(que1)
  que1.LinkTo(the)
  the.LinkTo(que2)
  que2.LinkTo(ogg)
' Parte audio:
  srca.LinkTo(fla)
  fla.LinkTo(que3)
  que3.LinkTo(acon)
  acon.LinkTo(vor)
  vor.LinkTo(que4)
' Combinazione dei dati audio e video:
  que4.LinkTo(ogg)
' Creazione del file .ogv finale:
  ogg.LinkTo(snk)
   
' Avvia la ripresa audio-video:
  pl.Play()
  
' Pone come attiva la finestra del programma prescelto:
  Desktop.ActiveWindow = numero_identificativo_della_finestra
  
  Repeat
' Mostra in console/terminale il tempo trascorso dall'inizio della ripresa audio-video:
    Write #File.Out, "\rTempo: " & Time(0, 0, 0, pl.Position * 1000)
    Wait 0.01
  Until bo = True
  
' Pone nuovamente come attiva la finestra del programma prescelto:
  Desktop.ActiveWindow = numero_identificativo_della_finestra
  
  pl.Stop()
  pl.Close()
  Copy temporaneo To "/tmp/prova.ogv"
  
  Print "Termine registrazione"
  Quit
  
End

Public Sub Application_Read()
 
  bo = True
 
End