Registrare e salvare in un file video un flusso di dati da una IPTV con le funzioni esterne del API di VLC

Da Gambas-it.org - Wikipedia.

E' possibile rgistrare e salvare in un file video un flusso di dati da una IPTV (web-TV) con le funzioni esterne del API di VLC.

Sarà necessario avere installata nel sistema e richiamare nell'applicazione Gambas la libreria condivisa: "libvlc.so.5.6.1 ".

Mostriamo di seguito un semplice esempio pratico in ambiente grafico:

Private bo As Boolean


Library "libvlc:5.6.1"

' libvlc_instance_t * libvlc_new (int argc, const char *const *argv)
' Create And initialize a libvlc instance.
Private Extern libvlc_new(argc As Integer, argv As String[]) As Pointer

' libvlc_media_t *libvlc_media_new_location (libvlc_instance_t *p_instance, const char * psz_mrl)
' Create a media with a certain given media resource location, for instance a valid URL.
Private Extern libvlc_media_new_location(p_instance As Pointer, path As String) As Pointer

' void libvlc_media_add_option (libvlc_media_t *p_md, const char *psz_options)
' Add an option to the media.
Private Extern libvlc_media_add_option(p_mi As Pointer, psz_options As String)

' libvlc_media_player_t * libvlc_media_player_new (libvlc_instance_t *p_libvlc_instance)
' Create an empty Media Player object.
Private Extern libvlc_media_player_new(p_libvlc_instance As Pointer) As Pointer

' void libvlc_media_player_set_media (libvlc_media_player_t *p_mi, libvlc_media_t *p_md)
' Set the media that will be used by the media_player.
Private Extern libvlc_media_player_set_media(p_md As Pointer, mp As Pointer)

' int libvlc_media_player_play (libvlc_media_player_t * p_mi)
' Play the video file.
Private Extern libvlc_media_player_play(p_mi As Pointer) As Integer

' libvlc_time_t libvlc_media_player_get_time (libvlc_media_player_t * p_mi)
' Get the current movie time (in ms).
Private Extern libvlc_media_player_get_time(p_mi As Pointer) As Integer

' void libvlc_media_player_release (libvlc_media_player_t * p_mi)
' Release a media_player after use Decrement the reference count of a media player object.
Private Extern libvlc_media_player_release(p_mi As Pointer)

' void libvlc_media_release (libvlc_media_t *p_md)
' Decrement the reference count of a media descriptor object.
Private Extern libvlc_media_release(p_md As Pointer)

' libvlc_release (libvlc_instance_t * p_instance)
' Decrement the reference count of a libvlc instance, and destroy it if it reaches zero.
Private Extern libvlc_release(p_instance As Pointer)


Public Sub ToggleButton1_Click()

 Dim inst, mp, m As Pointer 

 If ToggleButton1.Value Then 
' Inizializza e imposta le opzioni relative al video.
' Se si vuole ottenere un file video MP4: ["vcodec=mp4v,fps=30,vb=512"]
' Se si vuole ottenere un file video MPG: ["vcodec=mp2v,fps=30,vb=512"]
' Se si vuole ottenere un file video FLV: ["vcodec=flv,fps=30,vb=512"]
' Se si vuole ottenere un file video AVI: ["vcodec=h264,fps=30,vb=512"]
' oppure anche: ["vcodec=h265,fps=30,vb=512"]
   inst = libvlc_new(1, ["vcodec=h264,fps=30,vb=512"])  
   If inst == 0 Then Error.Raise("Impossibile inizializzare la libreria VLC !")

' Crea il media player:
   mp = libvlc_media_player_new(inst)
   If mp == 0 Then Error.Raise("Impossibile creare il media player !")

' Crea un nuovo oggetto multimedia.
' Nel secondo argomento della funzione va specificato il percorso del file-device video:
   m = libvlc_media_new_location(inst, "http://wzstreaming.rai.it/TVlive/liveStream/playlist.m3u8")
   If m == 0 Then Error.Raise("Impossibile creare un oggetto multimediale !")

' Viene aggiunta l'opzione per la registrazione dell'audio mediante il sistema ALSA e per la creazione del file video.
' Se si vuole ottenere un file video MP4: ":sout=#transcode{acodec=mp3,ab=192,channels=2,samplerate=44100,deinterlace,audio-sync} :duplicate{dst=display,dst=std{access=file,mux=mp4,dst=/tmp/video.mp4}}"
' Se si vuole ottenere un file video MPG: ":sout=#transcode{acodec=mp3,ab=192,channels=2,samplerate=44100,deinterlace,audio-sync} :duplicate{dst=display,dst=std{access=file,mux=ts,dst=/tmp/video.mpg}}"
' Se si vuole ottenere un file video FLV: ":sout=#transcode{acodec=mp3,ab=192,channels=2,samplerate=44100,deinterlace,audio-sync} :duplicate{dst=display,dst=std{access=file,mux=flv,dst=/tmp/video.flv}}"
' Se si vuole ottenere un file video AVI: ":sout=#transcode{acodec=mp3,ab=192,channels=2,samplerate=44100,deinterlace,audio-sync} :duplicate{dst=display,dst=std{access=file,mux=avi,dst=/tmp/video.avi}}"
   libvlc_media_add_option(m, ":sout=#transcode{acodec=mp3,ab=192,channels=2,samplerate=44100,deinterlace,audio-sync} :duplicate{dst=display,dst=std{access=file,mux=avi,dst=/tmp/video.avi}}")

   libvlc_media_player_set_media(mp, m)
 
' Avvia la cattura del video-audio da parte del media player:
   libvlc_media_player_play(mp)

   While bo = False
     Me.Title = Str(Time(0, 0, 0, libvlc_media_player_get_time(mp)))
' Il Wait consente di agire su altri oggetti posti sul Form:
     Wait 0.01
   Wend

' Chiude la libreria VLC ed il programma:
   libvlc_media_player_release(mp)
   libvlc_media_release(m)
   libvlc_release(inst)
   Me.Close
 Else
' Causa l'arresto della registrazione, la chiusura della libreria VLC e del programma:
   bo = True
 Endif

End


Registrare a comando dell'utente

Se si intende avviare la registrazione in modo arbitrario, ossia a comando dell'utente, del video di una web-TV bisognerà impostare tale istruzione con la funzione esterna "libvlc_media_add_option()" ovviamente dopo l'avvio del video, sarà avvenuto con l'uso della funzione esterna "libvlc_media_player_play()".
A tal riguardo si deve considerare che, volendo avviare la registrazione dopo l'inizio del video della web-TV, non si otterrà la registrazione. Si è per ora constatato che l'uso della funzione esterna "libvlc_media_add_option()" deve avvenire sempre prima dell'attivazione e uso della funzione esterna "libvlc_media_player_play()".
Pertanto, si rende necessario arrestare l'esecuzione del video della web-TV mediante la funzione esterna "libvlc_media_player_stop()", richiamare la funzione esterna "libvlc_media_add_option()" con le necessarie opzione utili alla registrazione del video e, quindi, riprendere l'esecuzione del video richiamando nuovamente la funzione esterna "libvlc_media_player_play()".
Va aggiunto che ovviamente nella prima funzione esterna "libvlc_media_add_option()", saranno impostate le opzioni utili alla sola visualizzazione del video della web-TV. Come già detto, le opzioni per la visualizzazione del video e della contestuale sua registrazione dovranno essere poste nella seconda funzione esterna "libvlc_media_add_option()".

Dunque, riprendendo il codice sopra esposto, avremo che il contenuto degli argomenti della prima saranno soltanto quelli utili per la visualizzazione del video della web-TV:

libvlc_media_add_option(m, ":sout=#transcode{acodec=mp3,ab=192,channels=2,samplerate=44100,deinterlace,audio-sync} :duplicate{dst=display}")

Per la registrazione a comando potremo porre un Button, che al suo clic con il seguente codice si attiverà la registrazione del video contestualmente alla sua visualizzazione.
Per arrestare il video basterà cliccare sul ToggleButton, con il quale si era inizialmente avviata la visualizzazione della TV-web.