Conoscere con "proc...fdinfo" la quantità dei dati elaborati di un file audio

Da Gambas-it.org - Wikipedia.

La sottodirectory "/fdinfo/", posta sotto la gerarchia "/proc/[pid]/fdinfo/", contiene un riferimento per ogni file che il processo ha aperto, chiamato dal suo descrittore di file. Il contenuto di ogni file può essere letto per ottenerne le informazioni sul descrittore di file corrispondente.

In particolare, se un programma Gambas oppure un multimediale esegue un file audio, viene generato nella sottodirectory "/proc/[pid]/fd/" un collegamento al file audio in esecuzione. Così nella sottodirectory "/proc/[pid]/fdinfo/" viene generato un file che fa riferimento al file-descriptor, posto in "/proc/[pid]/fd/", collegato con il file audio eseguito.

Il file di riferimento, posto in "/proc/[pid]/fdinfo/", fornisce tre righe (campi) di informazioni. La riga che per l'argomento, trattato in questa pagina, ci interessa, è la prima. Tale primo campo di informazioni è chiamato "pos", e rappresenta un numero intero decimale che mostra l'offset del file in esecuzione, ossia la quantità di byte del file audio sino a quel momento elaborati dal programma lanciato.

Tale risorsa, rappresentata dalla sottodirectory "/proc/[pid]/fdinfo/", può essere utilizzata anche in Gambas per conoscere in tempo reale la quantità di dati elaborati di un file audio da un'applicazione Gambas con le specifiche risorse di un apposto Componente, oppure da un programma esterno multimediale, lanciato dall'applicazione Gambas mediante Shell e gestito con le risorse della Classe Process.


Caso in cui il file audio è eseguito con le risorse native di Gambas

Il seguente esempio mostra come conoscere la quantità di byte audio processati da una risorsa Gambas (in tal caso il Componente gb.media), adatta a eseguire un file audio:

Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim med, prc, s, dati, dt As String
 Dim byte As Integer
 Dim fl As File
  
  med = "/percorso/del/file/audio"
  byte = Stat(med).Size
  Print "File audio: "; File.Name(med)
  Print "Dimensione: "; byte; " byte\n"
  
  pl = New MediaPipeline(Null, "playbin")
  pl["uri"] = Media.URL(med)
  
  pl.Play()
  
  prc = "/proc" &/ CStr(Application.Handle)
  
  Wait 0.3
  
  For Each s In Dir(prc &/ "fd", "*")
 'Se il file descriptor è un link al file audio eseguito,...:"
    If Stat(prc &/ "fd" &/ s).Link = med Then
 '...allora viene eseguito il ciclo per leggere il corrispondente file nella sottodirectory "/proc/[pid]/fdinfo/":"
      Repeat
        fl = Open prc &/ "fdinfo" &/ s For Read
        Line Input #fl, dati
 'Estrapola la parte della stringa afferente ai byte processati:"
        dt = Scan(dati, "*\t*")[1]
        Write "\r  \e[31m" & dt & "\e[0m byte processati"
        fl.Close
        Wait 0.01
 'Il ciclo di norma dura sino a quando non sono stati elaborati tutti i dati del file audio:"
      Until Val(dt) >= byte
      Break
    Endif
    
  Next
  
  pl.Stop
  pl.Close
  
End


Caso in cui il file audio è eseguito da un programma lanciato con Gambas mediante Shell

Mostriamo un esempio in ambiente grafico, nel quale si lancerà il programma multimediale VLC, passandogli un file audio da eseguire, e si mostrerà in una ProgressBar la percentuale corrente dei dati di un file audio eseguiti.

Private media As String
Private i As Integer


Public Sub Form_Open()
 
 media = "/percorso/del/file/audio"
 i = Stat(media).Size
 Label1.Text = "File media: " & media &
               "\nDimensione: " & CStr(i) & " byte"
 
End


Public Sub Button1_Click()
 
 Dim pr As Process
 Dim fl As File
 Dim prc, s, dati As String
  
' Lancia il programma VLC passandogli il percorso del file audio da eseguire:
  pr = Shell "cvlc " & media
' Individua con precisione il numero del processo del programma VLC
' dalla proprietà ".Handle" della variabile "Process", aumentato di un'unità:
  prc = "/proc" &/ CStr(pr.Handle + 1)
  
  Wait 0.3
  For Each s In Dir(prc &/ "fd", "*")
     
' Se il file descriptor è un link al file audio eseguito,...:
    If Stat(prc &/ "fd" &/ s).Link = media Then
' ...allora viene eseguito il ciclo per leggere il corrispondente file nella sottodirectory "/proc/[pid]/fdinfo/":
      Repeat
        fl = Open prc &/ "fdinfo" &/ s For Read
        Line Input #fl, dati
' Aggiorna la proprietà ".value" della "ProgressBar":
        ProgressBar1.Value = Val(Scan(dati, "*\t*")[1]) / i
        fl.Close
        Wait 0.01
' Se è stato chiuso manualmente il Form, allora si esce dal ciclo "Repeat...Until":
        If Object.IsValid(Me) = False Then Break
' Il ciclo di norma dura sino a quando non sono stati elaborati tutti i dati del file audio:
      Until ProgressBar1.Value = 1.00
      pr.Close
' Se è stato chiuso manualmente il Form, allora si esce anche dal ciclo "For...Next":
      If Object.IsValid(Me) = False Then Break
      Me.Close
    Endif
     
  Next
  
End


Public Sub Form_Close()
 
' Se è stato comunque chiuso il Form, allora viene terminato il processo del programma multimediale:
 Shell "killall vlc"
 
End



Riferimenti