Mit RunProgram() metaflac ausführen

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
jogo
Beiträge: 64
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint Mate

Mit RunProgram() metaflac ausführen

Beitrag von jogo »

metaflac ist ein KommandozeilenTool aus dem Paket flac und dient dem Tagging von Audio.flac Dateien.
Ich möchte damit eine Reihe eigener .flac Dateien mit Tags versehen.

Ein Test mit dem Terminal funktioniert. Den entsprechenden Terminalaufruf habe ich im Democode als Debugausgabe zum raus kopieren generiert.
Das Problem ist, das exakt der gleiche Aufruf über RunProgram() zwar durchgeht, aber die Tag-Daten pro Tag immer nur bis zum ersten Leerzeichen eingetragen werden. ZB: Anstelle "Pink Floyd" wird nur "Pink getaggt. Das Gleiche auch bei den anderen Tags.

Liegt sicherlich nicht an PB, sondern an die Art des Kommando Aufrufs.
Ich seh da aber nix, wo es da klemmen könnte - eigtl. muß das gehen...

Hab dafür einen Demo-Code gebaut, der das veranschaulicht. Zum Testen ist allerdings eine .flac-Datei und das Paket 'flac' notwendig.

Code: Alles auswählen

;metaflac-test, um eine .flac-Datei zu taggen
;das tool 'metaflac' ist bestandteil des pakets 'flac' und in den offiz. paketquellen vorhanden

EnableExplicit ;deklarierungszwang
Global.s pfd,ku,ti,al


Procedure.s ruf_auf(pn.s,pr.s,f.i)
  ;startet ein script oder programm & gibt ggf. den ausgabe & exitcode zurück / 
  ;pn= programm-name
  ;pr= parameter für program-name(kann auch der name/pfad eines weiteren programms/scripts sein(zb. bei sudo)) | 
  ;f=  flag: 1=datenausgabe wird benötigt, 2=Exitcode wird benötigt, 0=nichts wird benötigt
  Protected pnr.i,ec.i,aus.s  
  aus = "" ;für kommandozeilenausgabe
  pnr = RunProgram(pn, pr, "", #PB_Program_Open | #PB_Program_Read)
  If pnr                  ;wenn programm erfolgreich gestartet    
    While ProgramRunning(pnr)                   ; wenn programm noch läuft    
      If f = 1 And AvailableProgramOutput(pnr)  ;wenn das programm daten ausgibt und diese auch benötigt werden (f=1)       
        aus + ReadProgramString(pnr) + Chr(13)  ;programmausgabe (wenn vorhanden) in aus sammeln
      EndIf
    Wend    
    ec = ProgramExitCode(pnr)  ;exitcode des programms    
    CloseProgram(pnr)          ; Schließt die Verbindung zum Programm
  EndIf  
  Select f  ;flag für programmausgabedaten auswerten
    Case 1  ;wenn ausgabedaten benötigt      
      ProcedureReturn aus
    Case 2  ;wenn exitcode benötigt      
      ProcedureReturn Str(ec)
  EndSelect  
EndProcedure

; -----------------------------------------------------------------------

If ruf_auf("which","metaflac",1) = ""        ;prüfen ob das kommandotool 'metaflac' installiert ist // dann wird der Pfad zurückgegeben, sonst leerstring
  MessageRequester("metaflc fehlt","Lösung: sudo install flac")
  End  
EndIf 

;pfad zur test.flac datei
pfd = GetHomeDirectory() + "Musik/test.flac"  ;ggf. anpassen

; tag-daten:
ku = "Cooler Interpret"
ti = "Super Titel"
al = "Mein Album"

;string zum testen im terminal (einfach aus dem debugger ins terminal kopieren))
Debug "funktioniert im terminal, wie erwartet:"
Debug "metaflac --remove-all-tags --no-utf8-convert --set-tag Artist=" + Chr(34) + ku + Chr(34) + " --set-tag Title=" + Chr(34) + ti + Chr(34) + " --set-tag Album=" + Chr(34) + al + Chr(34) + " " + pfd

;der exakt gleiche aufruf via RunProgramm über ruf_auf() //parameter siehe dort:
ruf_auf("metaflac"," --remove-all-tags --no-utf8-convert --set-tag Artist=" + Chr(34) + ku + Chr(34) + " --set-tag Title=" + Chr(34) + ti + Chr(34) + " --set-tag Album=" + Chr(34) + al + Chr(34) + " " + pfd,0)

;ergebnis: die tag-daten werden je nur bis zum ersten leerzeichen hinzugefügt
--
Ideen gibt es viele - man muss sie nur haben...
Mint 18.3/19.3/21.x/LMDE5 // PureBasic 5.73 / 6.02
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Mit RunProgram() metaflac ausführen

Beitrag von mk-soft »

Wenn ein Parameter Leerzeichen enthält, must du diesen mit Doublequotes versehen

#DQUOTE$ + Param.s + #DQUOTE$
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
jogo
Beiträge: 64
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint Mate

Re: Mit RunProgram() metaflac ausführen

Beitrag von jogo »

klappt in diesem Fall leider nicht..
das mit den doppelten Anführungszeichen hab ich schon getestet.
Hab das mit aber chr(34)+chr(34) + Param.s + chr(34)+chr(34) gemacht, weil mir #DQUOTE$ nicht bekannt war.
Aber eben extra noch mal alle chr(34) durch #DQUOTE$ ersetz und probiert - Ergebnis ist das gleiche.

Komisch ist auch, das über das Terminal im Tag Pink Floyd steht, und über RunProgramm() steht da "Pink
Also im Tag steht tatsächlich ein Anführungszeichen vor Pink.
--
Ideen gibt es viele - man muss sie nur haben...
Mint 18.3/19.3/21.x/LMDE5 // PureBasic 5.73 / 6.02
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Mit RunProgram() metaflac ausführen

Beitrag von HeX0R »

Versuch's mal so:

Code: Alles auswählen

ruf_auf("metaflac",~"--remove-all-tags --no-utf8-convert \"--set-tag Artist="  + ku + ~"\" \"--set-tag Title=" + ti + ~"\" \"--set-tag Album=" + al + ~"\" \"" + pfd + ~"\"",0)
jogo
Beiträge: 64
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint Mate

Re: Mit RunProgram() metaflac ausführen

Beitrag von jogo »

moin HeXOR
dein Ansatz hat zum Ziel geführt - wenn auch nicht auf Anhieb ;-)
Dein obiger Vorschlag führte dazu, dass metaflac das Kommando gar nicht ausgeführt hat.

Aber angeregt durch deinen Vorschlag habe mit dieser 'Maskierung' etwas rumgespielt und den jeweiligen Anfang der Tag-Option etwas verschoben.
Und schwupp - hat's funktioniert^^ - Danke für die Mühe :-)

Code: Alles auswählen

ruf_auf("metaflac",~"--remove-all-tags --no-utf8-convert --set-tag \"Artist="  + ku + ~"\" --set-tag \"Title=" + ti + ~"\" --set-tag \"Album=" + al + ~"\" \"" + pfd + ~"\"",0)
Allerdings kann ich vom Verständnis her dem ganzen nicht ganz folgen. Was bewirkt zum Bsp. diese Tilde?
Hab also bei diesen ganzen Wald von Slash und Anführungszeichen etwas den Faden verloren, um das auf ähnliche Szenarien anwenden zu können.

Könntest du vllt. in paar kurzen Sätzen die Logic dieser Methode erklären?
--
Ideen gibt es viele - man muss sie nur haben...
Mint 18.3/19.3/21.x/LMDE5 // PureBasic 5.73 / 6.02
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Mit RunProgram() metaflac ausführen

Beitrag von HeX0R »

Das ~ Zeichen wurde irgendwann eingeführt.
Du kannst damit relativ einfach (ohne das lästige " + CHR(xx) + ") Sonderzeichen einfügen.

Die werden mit Backslash gekennzeichnet, also z.B.:

Code: Alles auswählen

Debug ~"Anführungszeichen: \", hier ein Tab: \t, und noch ein Carriage return: \r Willst du ein Backslash schreiben, machst Du \\"
Siehe auch in der Hilfe => Literale Strings / Escape-Sequenzen

Es ist aber tatsächlich nichts anderes als eine andere Schreibweise.
Du kannst genauso Deine " + Chr(xx) + " Versionen weiter nutzen, tatsächlich war ja am Ende das Anführungszeichen (bei uns beiden wohl) nur an der falschen Stelle.
jogo
Beiträge: 64
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint Mate

Re: Mit RunProgram() metaflac ausführen

Beitrag von jogo »

alles klar - soweit verstanden - Danke.
--
Ideen gibt es viele - man muss sie nur haben...
Mint 18.3/19.3/21.x/LMDE5 // PureBasic 5.73 / 6.02
Benubi
Beiträge: 186
Registriert: 22.10.2004 17:51
Wohnort: Berlin, Wedding

Re: Mit RunProgram() metaflac ausführen

Beitrag von Benubi »

Du könntest auch zusätzlich prüfen ob das ausgeführte Programm eine Fehlermeldung ausgibt, und diese an den User oder das aufrufende Programm weitergeben (MessageRequester, ConsoleError, EditorGadget, StatusBar...). Fehlermeldungen sind der beste Freund des Programmierers oder Anwenders, ohne sie wirds meistens noch schwieriger den Fehler zu finden ;)
jogo
Beiträge: 64
Registriert: 22.11.2020 20:05
Computerausstattung: 'ne Handvoll gebrauchte Laptops & PCs mit Mint Mate

Re: Mit RunProgram() metaflac ausführen

Beitrag von jogo »

da haste Recht - sollte ich mit Parameter #PB_Program_Error einbauen.
Wird das über AvailableProgramOutput() bereitgestellt oder kann ich das ähnlich wie den ProgramExitCode() kurz vor dem CloseProgram() auslesen?
--
Ideen gibt es viele - man muss sie nur haben...
Mint 18.3/19.3/21.x/LMDE5 // PureBasic 5.73 / 6.02
Benubi
Beiträge: 186
Registriert: 22.10.2004 17:51
Wohnort: Berlin, Wedding

Re: Mit RunProgram() metaflac ausführen

Beitrag von Benubi »

Mit ReadProgramError(). Ist nicht blockierend.

Allerdings solltest Du da eine Schleife einbauen wenn mehrere Zeilen im Fehlerport ausgegeben werden; und wenn mehrere ausgegeben werden dann mit #CRLF$ oder dem entsprechenden Zeilenende vom OS zwischen den Zeilen versehen.

Code: Alles auswählen

ErrorMessage$=""
#EOL$ = #CRLF$
Repeat
  errline$ = ReadProgramError()
  If errline$<>#Empty$
    ErrorMessage$=ErrorMessage$+#EOL$
  EndIf
Until errline$=""

If ErrorMessage$<>#Empty$
   ; HandleError(ErrorMessage$)
EndIf
Manchmal gillt das Programm als bereits beendet, aber es befinden sich noch Daten im Output oder im Fehlerkanal. Daher solltest Du auch den Output bzw. den Fehlerkanal noch nach der Ausführung des Programmes ein oder zweimal abfragen weil sonst verpasst Du manchmal einige Daten oder gerade die Fehlermeldung die zum Programmende ausgegeben wurde.
Antworten