Eseguire un file Video con le funzioni esterne del API di Libmpv

Da Gambas-it.org - Wikipedia.

La libreria esterna Libmpv consente di eseguire diversi formati di file video.

Per poter utilizzare le risorse di Mpv, è necessario avere installata e richiamare in Gambas la libreria condivisa: "libmpv.so.2.3.0 ".

Mostriamo un semplice esempio:

Library "libc:6"

Private Const LC_NUMERIC As Integer = 1

' char *setlocale (int __category, const char *__locale)
' Set and/or return the current locale.
Private Extern setlocale(__category As Integer, __locale As String) As Pointer


Library "libmpv:2.3.0"

Private Enum MPV_FORMAT_NONE = 0, MPV_FORMAT_STRING, MPV_FORMAT_OSD_STRING, MPV_FORMAT_FLAG,
             MPV_FORMAT_INT64, MPV_FORMAT_DOUBLE, MPV_FORMAT_NODE, MPV_FORMAT_NODE_ARRAY,
             MPV_FORMAT_NODE_MAP, MPV_FORMAT_BYTE_ARRAY

' mpv_handle *mpv_create(void)
' Create a new mpv instance.
Private Extern mpv_create() As Pointer

' int mpv_initialize(mpv_handle *ctx)
' Initialize an uninitialized mpv instance.
Private Extern mpv_initialize(ctx As Pointer) As Integer

' int mpv_command(mpv_handle *ctx, const char **args)
' Send a command to the player.
Private Extern mpv_command(ctx As Pointer, args As String[]) As Integer

' int mpv_set_property(mpv_handle *ctx, const char *name, mpv_format format, void *data)
' Set a property.
Private Extern mpv_set_property(ctx As Pointer, name As String, format_ As Integer, data As Pointer) As Integer

' int mpv_get_property(mpv_handle *ctx, const char *name, mpv_format format, void *data)
' Read the value of the given property.
Private Extern mpv_get_property(ctx As Pointer, name As String, format_ As Integer, data As Pointer) As Integer

' void mpv_terminate_destroy(mpv_handle *ctx)
' Disconnect and destroy the mpv_handle.
Private Extern mpv_terminate_destroy(ctx As Pointer)


Public Sub Main()
 
 Dim mpv As Pointer
 Dim fileaudio As String
 Dim d, l, v As Long
 
 fileaudio = "/percorso/del/file/video"
 Print "File audio: "; fileaudio
 Print
 
 setlocale(LC_NUMERIC, "C")
 
 mpv = mpv_create()
 If mpv == 0 Then Error.Raise("Errore !")
 
 mpv_initialize(mpv)
 
 mpv_command(mpv, ["loadfile", fileaudio, Null])
 
' Imposta il volume. 0 significa silenzio; 100 significa nessuna riduzione del volume o amplificazione rispetto al valore originario. Valori superiori a 100 amplificano il volume di uscita rispetto al valore originario.
 v = 50
 mpv_set_property(mpv, "volume", MPV_FORMAT_INT64, VarPtr(v))
 
 Repeat
   mpv_get_property(mpv, "duration", MPV_FORMAT_INT64, VarPtr(d))
 Until d > 0 ' Si esce dal ciclo, solo quando sarà rilevata la durata del file video
 
 Repeat
   mpv_get_property(mpv, "time-pos", MPV_FORMAT_INT64, VarPtr(l))
   Write "\e[0m\rDurata: " & Time(0, 0, 0, CInt(d) * 1000) &
         "   Tempo trascorso: \e[31m" & Time(0, 0, 0, CInt(l) * 1000)
   Wait 0.001
 Until l >= d
 
 mpv_terminate_destroy(mpv)
 
End


Un'altra soluzione simile per ottenere alla fine dell'esecuzione la chiusura del programma:

Library "libc:6"

Private Const LC_NUMERIC As Integer = 1

' char *setlocale (int __category, const char *__locale)
' Set and/or return the current locale.
Private Extern setlocale(__category As Integer, __locale As String) As Pointer


Library "libmpv:2.3.0"

Public Struct mpv_event
  event_id As Integer
  error_ As Integer
  reply_userdata As Long
  data As Pointer
End Struct

Private Const MPV_FORMAT_INT64 As Integer = 4
Private Const MPV_EVENT_END_FILE As Integer = 7

' mpv_handle *mpv_create(void)
' Create a new mpv instance.
Private Extern mpv_create() As Pointer

' int mpv_initialize(mpv_handle *ctx)
' Initialize an uninitialized mpv instance.
Private Extern mpv_initialize(ctx As Pointer) As Integer

' int mpv_command(mpv_handle *ctx, const char **args)
' Send a command to the player.
Private Extern mpv_command(ctx As Pointer, args As String[]) As Integer

' int mpv_set_property(mpv_handle *ctx, const char *name, mpv_format format, void *data)
' Set a property.
Private Extern mpv_set_property(ctx As Pointer, name As String, format_ As Integer, data As Pointer) As Integer

' int mpv_get_property(mpv_handle *ctx, const char *name, mpv_format format, void *data)
' Read the value of the given property.
Private Extern mpv_get_property(ctx As Pointer, name As String, format_ As Integer, data As Pointer) As Integer

' mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
' Wait for the next event, or until the timeout expires.
Private Extern mpv_wait_event(ctx As Pointer, timeout As Float) As Mpv_event

' void mpv_terminate_destroy(mpv_handle *ctx)
' Disconnect and destroy the mpv_handle.
Private Extern mpv_terminate_destroy(ctx As Pointer)


Public Sub Main()
 
 Dim mpv As Pointer
 Dim err As Integer
 Dim v As Long
 Dim cmd As String[] = ["loadfile", Null, Null]
 Dim ev As Mpv_event
 
 cmd[1] = "/percorso/del/file/video"
 
 setlocale(LC_NUMERIC, "C")
 
 mpv = mpv_create()
 If mpv == 0 Then Error.Raise("Errore !")
 
 err = mpv_initialize(mpv)
 If err < 0 Then
   Terminus(mpv)
   Error.Raise("Errore !")
 Endif
 
 err = mpv_command(mpv, cmd)
 If err < 0 Then
   Terminus(mpv)
   Error.Raise("Errore !")
 Endif
 
' Imposta il Volume: 
'    0 = muto;
'  100 = nessuna variazione di volume;
' >100 = aumento del volume rispetto al valore originario.
 v = 50
 mpv_set_property(mpv, "volume", MPV_FORMAT_INT64, VarPtr(v))
 
 Repeat
' Acquisisce la corrente posizione del video espressa in secondi trascorsi dall'inizio dell'esecuzione: 
   mpv_get_property(mpv, "time-pos", MPV_FORMAT_INT64, VarPtr(v))
   Write "\r\e[31m" & Str(Time(0, 0, 0, v * 1000))
   Flush
   ev = mpv_wait_event(mpv, 1)
 Until ev.event_id == MPV_EVENT_END_FILE   ' Il ciclo termina, quando termina l'esecuzione del file video
 
 Terminus(mpv)
 
End


Private Procedure Terminus(po As Pointer)

 mpv_terminate_destroy(po)

End


Con applicazione grafica mostrando il video in una DrawingArea posta sul Form

Nel seguente codice si useranno risorse grafiche e si farà mostrare il video all'interno di una "DrawingArea" posta sul "Form" principale.

Library "libc:6"

Private Const LC_NUMERIC As Integer = 1

' char *setlocale (int __category, const char *__locale)
' Set and/or return the current locale.
Private Extern setlocale(__category As Integer, __locale As String) As Pointer


Library "libmpv:2.3.0"

Public Struct mpv_event
  event_id As Integer
  error_ As Integer
  reply_userdata As Long
  data As Pointer
End Struct

Private Enum MPV_FORMAT_INT64 = 4
Private Const MPV_EVENT_END_FILE As Integer = 7

' mpv_handle *mpv_create(void)
' Create a new mpv instance.
Private Extern mpv_create() As Pointer

' int mpv_initialize(mpv_handle *ctx)
' Initialize an uninitialized mpv instance.
Private Extern mpv_initialize(ctx As Pointer) As Integer

' int mpv_command(mpv_handle *ctx, const char **args)
' Send a command to the player.
Private Extern mpv_command(ctx As Pointer, args As String[]) As Integer

' int mpv_set_property(mpv_handle *ctx, const char *name, mpv_format format, void *data)
' Set a property.
Private Extern mpv_set_property(ctx As Pointer, name As String, format_ As Integer, data As Pointer) As Integer

' int mpv_set_option_string(mpv_handle *ctx, const char *name, const char *data)
' Set an option to a string value.
Private Extern mpv_set_option_string(ctx As Pointer, Name As String, Data As String) As Integer

' int mpv_get_property(mpv_handle *ctx, const char *name, mpv_format format, void *data)
' Read the value of the given property.
Private Extern mpv_get_property(ctx As Pointer, name As String, format_ As Integer, data As Pointer) As Integer

' mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout)
' Wait for the next event, or until the timeout expires.
Private Extern mpv_wait_event(ctx As Pointer, timeout As Float) As Mpv_event

' void mpv_terminate_destroy(mpv_handle *ctx)
' Disconnect and destroy the mpv_handle.
Private Extern mpv_terminate_destroy(ctx As Pointer)


Public Sub Button1_Click()
 
 Dim mpv As Pointer
 Dim err As Integer
 Dim cmd As String[] = ["loadfile", Null, Null]
 Dim v As Long
 Dim ev As Mpv_event
 
 cmd[1] = "/percorso/del/file/video"
 
 setlocale(LC_NUMERIC, "C")
 
 mpv = mpv_create()
 If mpv == 0 Then Error.Raise("Error !")
 
 err = mpv_initialize(mpv)
 If err < 0 Then
   Terminus(mpv)
   Error.Raise("Error !")
 Endif
 
 err = mpv_command(mpv, cmd)
 If err < 0 Then
   Terminus(mpv)
   Error.Raise("Error !")
 Endif
 
' Imposta il Volume: 
'    0 = muto;
'  100 = nessuna variazione di volume;
' >100 = aumento del volume rispetto al valore originario.
 v = 50
 mpv_set_property(mpv, "volume", MPV_FORMAT_INT64, VarPtr(v))
 
' Imposta la superficie grafica (in questo caso la "DrawingArea" posta sul "Form"), ove mostrare il video: 
 mpv_set_option_string(mpv, "wid", CStr(DrawingArea1.Id))
 
 Repeat
' Acquisisce la corrente posizione del video espressa in secondi trascorsi dall'inizio dell'esecuzione: 
   mpv_get_property(mpv, "time-pos", MPV_FORMAT_INT64, VarPtr(v))
   Write "\r\e[31m" & Str(Time(0, 0, 0, v * 1000))
   Flush
   ev = mpv_wait_event(mpv, 1)
 Until ev.event_id == MPV_EVENT_END_FILE   ' Il ciclo termina, quando termina l'esecuzione del file video
 
 Terminus(mpv)
 
End


Private Procedure Terminus(po As Pointer)

 mpv_terminate_destroy(po)

End


Riferimenti