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...
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...
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
|