Comunidad Gambas-es
Dialogando con Procesos del S.O. desde Gambas - Versión para impresión

+- Comunidad Gambas-es (https://gambas-es.org)
+-- Foro: Otros (https://gambas-es.org/forum-18.html)
+--- Foro: Videotutoriales (https://gambas-es.org/forum-20.html)
+--- Tema: Dialogando con Procesos del S.O. desde Gambas (/thread-524.html)



Dialogando con Procesos del S.O. desde Gambas - Shordi - 08-08-2021

No es infrecuente necesitar lanzar un proceso del sistema que nos pregunte cosas vía consola. En este video tutorial podéis ver una manera de dialogar con esos procesos abiertos con EXEC o con SHELL desde un programa de gambas.
En la descripción del vídeo tenéis un enlace al proyecto que en él se maneja.

Espero que os sea útil.




RE: Dialogando con Procesos del S.O. desde Gambas - tincho - 09-08-2021

Hola Shordi.
Estoy tratando de seguir el ejemplo que hiciste pero para el programa de terminal mpg123 pero tira un error diciendo que se trata de un stream y no de un texto lo cual tiene sentido ya que estoy usando un archivo mp3
El caso es que par aoperar con este programa de terminal es necesario poder enviar teclas al programa y recuperar el texto que sale por la erminal (que no es visible)
Dejo el código aquí por si alguien desea hacer algún test.

Código:
Private hProcess As Process
Private sBufer As String
Private sLast As String

Public Sub Form_Open()
 
  If Exist(Config.CurrentFile) Then
    If Stat(Config.CurrentFile).Type = gb.File Then
      ButtonBox1.Text = User.Home &/ "test.mp3"
    Endif
  Endif
 
End

Public Sub Button1_Click()
 
  Dim sCommand As String
 
  sCommand = "mpg123 '" & ButtonBox1.Text & "'"
 
  hProcess = Shell sCommand For Input As "Process"
 
End

Public Sub Process_Read()
 
  Read #Process, sLast, -1024
  TextArea1.Text &= sLast
 
End



RE: Dialogando con Procesos del S.O. desde Gambas - Shordi - 09-08-2021

No se pueden mezclar churras con merinas, que se dice por mi tierra. La solución que yo he puesto es sólo para dialogar con las entradas y salidas estándar en forma de texto. No he profundizado en lo de manejar streams, pero supongo que estudiando la clase Process, puedes descubrir la manera.

De todas formas, si lo que quieres es oír música, enlaza el componente gb.sdl2.sound con tu proyecto y despúes con éste código es suficiente.

 
Código:
   music.Load(user.home &/ "Escritorio/marea.mp3")
    music.play()
   

Saludos

Perdón si he dicho una simpleza, pero es que yo nunca había utilizado gambas para oír música. He visto la clase music y, descubrimiento nuevo para mí, he comenazado a hacerme un reproductor propio... Big Grin Big Grin Big Grin Big Grin

Ya que estamos... ¿Alguien sabe cómo averiguar cuántos segundos de duración tiene un mp3?


Saludos.

ah... Vale, con ffmpeg. No he preguntado nada.


RE: Dialogando con Procesos del S.O. desde Gambas - tincho - 09-08-2021

(09-08-2021, 19:07)Shordi escribió: De todas formas, si lo que quieres es oír música, enlaza el componente gb.sdl2.sound con tu proyecto y despúes con éste código es suficiente.

Gracias por el comentario, pero ya vengo usando eso en mi programa Vinilo.
Mi interés en usar este programa de terminal mpg123 es debido a  que la calidad del sonido con gb.sdl2 es mas pobre que la de mpg123 pero tal vez exista otra forma como ffmpeg o algo similar. se siguen aceptando ideas.
(09-08-2021, 19:07)Shordi escribió: Ya que estamos... ¿Alguien sabe cómo averiguar cuántos segundos de duración tiene un mp3?
Yo uso esto:
Código:
' Source:
' https://www.gambas-it.org/wiki/index.php?title=Estrarre_informazioni_e_TAG_da_file_audio_con_le_funzioni_esterne_del_API_di_Libtag_c
'
Export
Library "libtag_c:0.0.0"

Public Struct TagLib_File
  dummy As Integer
End Struct

Public Struct TagLib_Tag
  dummy As Integer
End Struct

Public Struct TagLib_AudioProperties
  dummy As Integer
End Struct

' void taglib_set_strings_unicode(BOOL unicode)
' By default all strings coming into or out of TagLib's C API are in UTF8.
' However, it may be desirable For TagLib To operate On Latin1(ISO - 8859 - 1) strings In which Case this should be set To FALSE.
Private Extern taglib_set_strings_unicode(unicode As Boolean)

' TagLib_File *taglib_file_new_type(const char *filename)
' Creates a TagLib file based on \a filename.
Private Extern taglib_file_new(filename As String) As TagLib_File

' TagLib_Tag *taglib_file_tag(const TagLib_File *file)
' Returns a pointer to the tag associated with this file.
Private Extern taglib_file_tag(_file As TagLib_File) As TagLib_Tag

' char *taglib_tag_title(const TagLib_Tag *tag)
' Returns a string with this tag's title.
Private Extern taglib_tag_title(tag As TagLib_Tag) As String

' char *taglib_tag_artist(const TagLib_Tag *tag)
' Returns a string with this tag's artist.
Private Extern taglib_tag_artist(tag As TagLib_Tag) As String

' char *taglib_tag_album(const TagLib_Tag *tag)
' Returns a string with this tag's album name.
Private Extern taglib_tag_album(tag As TagLib_Tag) As String

' unsigned int taglib_tag_year(const TagLib_Tag *tag)
' Returns the tag's year or 0 if year is not set.
Private Extern taglib_tag_year(tag As TagLib_Tag) As Integer

' char *taglib_tag_comment(const TagLib_Tag *tag)
' Returns a string with this tag's comment.
Private Extern taglib_tag_comment(tag As TagLib_Tag) As String

' unsigned int taglib_tag_track(const TagLib_Tag *tag)
' Returns the tag's track number or 0 if track number is not set.
Private Extern taglib_tag_track(tag As TagLib_Tag) As Integer

'Private Extern taglib_tag_encoder(tag As TagLib_Tag) As String
'Private Extern taglib_tag_volume_number(tag As TagLib_Tag) As Integer

' char *taglib_tag_genre(const TagLib_Tag *tag)
' Returns a string with this tag's genre.
Private Extern taglib_tag_genre(tag As TagLib_Tag) As String

' const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file)
' Returns a pointer to the the audio properties associated with this file.
Private Extern taglib_file_audioproperties(_file As TagLib_File) As TagLib_AudioProperties

' int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties)
' Returns the length of the file in seconds.
Private Extern taglib_audioproperties_length(audioProperties As TagLib_AudioProperties) As Integer

' int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties)
' Returns the bitrate of the file in kb/s.
Private Extern taglib_audioproperties_bitrate(audioProperties As TagLib_AudioProperties) As Integer

' int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties)
' Returns the sample rate of the file in Hz.
Private Extern taglib_audioproperties_samplerate(audioProperties As TagLib_AudioProperties) As Integer

' int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties)
' Returns the number of channels in the audio stream.
Private Extern taglib_audioproperties_channels(audioProperties As TagLib_AudioProperties) As Integer

' void taglib_tag_free_strings(void)
' Frees all of the strings that have been created by the tag.
Private Extern taglib_tag_free_strings()

' void taglib_file_free(TagLib_File *file)
' Frees and closes the file.
Private Extern taglib_file_free(_file As TagLib_File)

Public Function Info(fileaudio As String) As Collection
 
  Dim fl As TagLib_File
  Dim autag As TagLib_Tag
  Dim auprop As TagLib_AudioProperties
  Dim secondi, minuti As Integer
  '
  Dim inf As New Collection
 
  'taglib_set_strings_unicode(False)
  taglib_set_strings_unicode(True)
 
  fl = taglib_file_new(fileaudio)
  If IsNull(fl) Then Error.Raise("Impossibile caricare il file audio: " & fileaudio)
 
  autag = taglib_file_tag(fl)
  If IsNull(autag) Then Error.Raise("Impossibile ottenere i tag dal file audio: " & fileaudio)
 
  inf.Add(taglib_tag_album(autag), "Album")
  inf.Add(taglib_tag_artist(autag), "Artist")
  inf.Add(taglib_tag_track(autag), "Track")
  inf.Add(taglib_tag_title(autag), "Title")
  inf.Add(taglib_tag_year(autag), "Year")
  inf.Add(taglib_tag_genre(autag), "Genre")
  inf.Add(taglib_tag_comment(autag), "Comment")
 
  ' Mostra le proprietà del file audio:
  auprop = taglib_file_audioproperties(fl)
 
  If IsNull(auprop) Then
    inf.Add(True, "AudioError")
  Else
    inf.Add(taglib_audioproperties_length(auprop), "Length")
    inf.Add(taglib_audioproperties_bitrate(auprop), "Bitrate")
    inf.Add(taglib_audioproperties_samplerate(auprop), "Frequency")
    inf.Add(taglib_audioproperties_channels(auprop), "Channels")
  Endif
 
  ' Va in chiusura:
  taglib_tag_free_strings()
  taglib_file_free(fl)
 
  Return inf
 
End



RE: Dialogando con Procesos del S.O. desde Gambas - Shordi - 10-08-2021

Esta clase (de Vuott, supongo) me vendría bien, que ahora uso una llamada a shell ( [code] ) que enlentece un montón cierta función,  pero mi equipo linux Mint no tiene esa librería en sus repositorios. La he buscado y es de Arch... pero requiere un montón de otras para instalarse. ¿No hay una alternativa para Mint? En el sistema existe libtag.so.1.17.0 que parece servir para lo mismo, pero no usa los mismos símbolos, por lo visto y no vale...

Sad Sad Sad

A ver si el reverenciado Consul se pasa por este foro y puede iluminarnos...

Saludos.


RE: Dialogando con Procesos del S.O. desde Gambas - tincho - 11-08-2021

(10-08-2021, 20:16)Shordi escribió: Esta clase (de Vuott, supongo) me vendría bien, que ahora uso una llamada a shell

Si claro, el código es de Vuott.
(10-08-2021, 20:16)Shordi escribió: En el sistema existe libtag.so.1.17.0 que parece servir para lo mismo, pero no usa los mismos símbolos

Voy a hacer unas pruebas y te digo algo.
Saludos.


RE: Dialogando con Procesos del S.O. desde Gambas - Shordi - 11-08-2021

He encontrado en el foto de gambas-it.org otras funciones también de Vuott. Funcionan razonablemente bien... pero con fallos en algunos archivos que no sé identificar. Esta es mi versión:

Código:
Public Function DurataMP3(s As String) As String
 
 Dim ver_mp3, layer As String
 Dim j, durata As Integer
 Dim vB, lB, brB As Byte
 Dim initium, bitrate As Short
 
  s = File.Load(s)
  initium = 1
 
  For j = initium To Len(s) - 1
    If (Asc(s, j) = 255) And (Asc(s, j + 1) > 241) And (Asc(s, j + 2) > 15) Then
      vB = Asc(s, j + 1) And 24
      Select Case vB
        Case 0
          ver_mp3 = "2.5"
        Case 16
          ver_mp3 = "2"
        Case 24
          ver_mp3 = "1"
      End Select
      lB = Asc(s, j + 1) And 6
      Select Case lB
        Case 2
          layer = "III"
        Case 4
          layer = "II"
        Case 6
          layer = "I"
      End Select
      brB = Asc(s, j + 2) And 240
      bitrate = EstraeBitRate(ver_mp3, layer, brB)
 
      Exit
      
    Endif
  Next
  durata = Fix((Len(s) / bitrate) * 8)
  Return tiempo(Format(Time(0, 0, 0, durata), "hh:nn:ss"))
 
End


Private Function EstraeBitRate(Vmpeg As String, layB As String, bitB As Byte) As Short
 
 Dim velCamp As Short
 Dim abit8 As Integer[]
 Dim avelcamp As Integer[]
 
  abit8 = [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224]    
  If Vmpeg = "1" Then   
    Select Case layB    
      Case "I"
        Return bitB * 2
      Case "II"
        aVelcamp = [32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384]
      Case "III"
        aVelcamp = [32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320]
    End Select
  Else
    Select Case layB     
      Case "I"
        aVelcamp = [32, 40, 56, 64, 80, 96, 112, 128, 160, 176, 192, 224, 256]
      Case "II" To "III"
        aVelcamp = [8, 16, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 320]
    End Select
  Endif
        velcamp = aVelcamp[abit8.Find(bitB)]
  Return velCamp
 
End
Es mucho más rápida que la otra... pero ya te digo, en algunos archivos, no sé por qué, falla.

De momento me quedo con el
Código:
Private Sub cargatiempo(sPath As String) As String
    
    Dim tempo, salida As String
   
    tempo = Temp()
    Shell "ffprobe -hide_banner " & Quote(sPath) & " 2>" & tempo
    Wait 0.1
    If Not Exist(tempo) Then Return
    salida = File.Load(tempo)
    Return tiempo(Between(salida, "Duration: ", "."))
    
End
 Aunque también me da algún fallo que otro, sobre todo si el nombre el archivo contiene caracteres extraños, que todavía estoy investigando.
Es más lenta que la de vuott de arriba pero creo que falla menos... Si yo entendiera de archivos de música probaría a modificar la de Vuott... pero me da mucha pereza meterme en ese potaje sólo por un programeta tontito como el que he hecho.

Saludos