staging.inyokaproject.org

Für diese Funktion musst du eingeloggt sein.

Bash-Skript: jeder 2. Dateipfad wird am Anfang merkwürdig abgeschnitten

Status: Ungelöst | Ubuntu-Version: Ubuntu 24.04 (Noble Numbat)
Antworten |

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

shiro schrieb:

Jein. Sinngemäß ja, aber deine Variante liefert auch Verzeichnisse, in denen keine ".flac" Dateien vorhanden sind.

Ja klar, ich meinte mit "macht dasselbe" nur die andere umschließende Syntax drumherum und die dadurch im Verlauf andere Reihenfolge der Kommandos.

Ansonsten habe ich jetzt alles perfekt verstanden und kann mich so dem (vermeintlich) eigentlichen Problem mit bc zuwenden. Besten Dank dafür.

Hier aber das Beispiel, wie man das Aufsplitten des Streams durch "tee" nicht in eine Datei sondern in eine Variable macht:

$ # Tee mit Split der Ausgabe in die Variable "var1"
$ { var1=$(find Ablage/ -type f -iname "*.flac" | sort | tee /dev/fd/3); } 3>&1
Ablage/Album1/test1.flac
Ablage/Album1/test 2.flac
Ablage/Album2/Test 3.flac
$ echo "$var1"
Ablage/Album1/test1.flac
Ablage/Album1/test 2.flac
Ablage/Album2/Test 3.flac
$ 

Verstanden?

Ich denke schon. Danke für das tolle Beispiel. Wäre – abgespeckt – vielleicht eine Ergänzung im Artikel tee wert.

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

shiro schrieb:

Hinweis: "ffmpeg" frisst ein Zeichen von stdin (siehe "Press [q] to stop, [?] for help" in der "ffmpeg" Ausgabe). Daher bekommt das Programm dieses über den Here-String (<<<" ").

Ich habe nun herausgefunden, dass ffmpeg die Optionen -stdin und -nostdin bereitstellt, um das Lesen von stdin zu (de)aktivieren. Das ist wohl die sauberere Variante.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@UlfZibis: Gibt es eigentlich einen guten Grund für Bash? Es ist ja nicht nur Bash, man muss dann auch noch Syntax und Eigenheiten von find, grep, bc und was auch sonst noch so benötigt wird, lernen. Das ist alles ziemlich archaisch und ”hässlich” und voller Fallstricke was angebliche Sonderzeichen und Shell-Eigenheiten wie „word splitting“, globbing, Subshells, usw. angeht. Wenn man stattdessen eine ”richtige” Programmiersprache verwendet, hat man nur eine Syntax. Selbst wenn man reguläre Ausdrücke dazu nimmt und als eigene Sprache ansieht hat man da eine Variante und nicht vier Programme die jeweils ein bis zwei leicht unterschiedliche Arten von regulären Ausdrücken verstehen.

Was bei ”richtigen” Programmiersprachen meistens etwas umständlicher ist als bei Shell-Skripten ist das starten von externen Programmen, weil dafür sind Shells ja erfunden worden.

Mal ein bisschen Quelltext in Python, aber da könnte man auch etwas anderes nehmen. Perl oder Ruby beispielsweise. Alles besser als Shell. Ungetestet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env python3
import re
import subprocess
from pathlib import Path


def detect_volumes(flac_file_path):
    result = subprocess.run(
        [
            "ffmpeg",
            "-hide_banner",
            "-nostdin",
            *("-i", str(flac_file_path)),
            *("-af", "volumedetect"),
            *("-f", "null"),
            "/dev/null",
        ],
        universal_newlines=True,
        capture_output=True,
        check=True,
    )
    return {
        match[1]: float(match[2])
        for match in re.finditer(r"(mean|max)_volume: (.*?) dB", result.stderr)
    }


def main():
    flac_directory_count = 0

    directory_paths = sorted(
        path for path in Path("Ablage").rglob("*") if path.is_dir()
    )
    for directory_path in directory_paths:
        flac_file_paths = sorted(directory_path.glob("*.flac"))
        for flac_file_path in flac_file_paths:
            print(flac_file_path)
            volumes = detect_volumes(flac_file_path)
            print(
                "mean volume:",
                volumes["mean"],
                "dB, max_volume:",
                volumes["max"],
                "dB",
            )

        if flac_file_paths:
            flac_directory_count += 1
            print("files:", len(flac_file_paths))
            print()

    print("Number of dirs total:", len(directory_paths))
    print("Number of dirs with flac files:", flac_directory_count)
    print("\n")


if __name__ == "__main__":
    main()

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

Marc_BlackJack_Rintsch schrieb:

@UlfZibis: Gibt es eigentlich einen guten Grund für Bash? ..... Das ist alles ziemlich archaisch und ”hässlich” und ...

Da hast Du recht. Hätte vorher auch nicht gedacht, dass das mit Bash so hakelig und aufwändig wird. Für eine Sache, die ich nur genau einmal zu tun habe, denke ich immer, dafür lohnt sich ein "richtiges" Programm nicht, doch hier ist de Grenze wohl überschritten. Mit der Spar-Syntax von Python tue ich mir aber auch noch schwer, denn ich komme von Java und C. Aber für die hiesige Aufgabe ist Python wohl der beste Mittelweg, weil Kompilieren etc. wegfällt.
Du kommst gerade zu richtigen Zeitpunkt mit Deinem Vorschlag, denn so kann ich mir die Syntax-Schlacht gegen bc sparen.

Mal ein bisschen Quelltext in Python, ... Ungetestet:

Toll, dass Du Dir die Mühe gemacht hast, eine gute Basis für das, was ich noch damit vor habe.

Das Programm läuft erst mal gut an und spuckt die gewünschten Resultate aus, aber nach einer Weile crashed es dann leider mit:

[.....]
Ablage/Soundtrack Saturday Night Fever (1977)/17 - Disco Inferno.flac
mean volume: -12.2 dB, max_volume: -0.0 dB
files: 17

Ablage/Suzanne Vega - 99.9F° (1992)/01-suzanne_vega-rock_in_this_pocket_(song_of_david).flac
Traceback (most recent call last):
  File "/mnt/Daten/Users/ich/Momentum/./vol_dedect.py", line 58, in <module>
    main()
  File "/mnt/Daten/Users/ich/Momentum/./vol_dedect.py", line 38, in main
    volumes = detect_volumes(flac_file_path)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/Daten/Users/ich/Momentum/./vol_dedect.py", line 8, in detect_volumes
    result = subprocess.run(
             ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 550, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 1209, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 2157, in _communicate
    stderr = self._translate_newlines(stderr,
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 1086, in _translate_newlines
    data = data.decode(encoding, errors)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 605: invalid start byte

Da ist wohl ein krummes Zeichen im Dateipfad, nur leider kann ich mit Position 605 nix anfangen, denn der Pfad ist ja gar nicht so lang. Wie kann man den Pfad zum Test in Hex-Notation ausgeben?

Dann hätte ich noch 2 Fragen:
1. Was ist das für ein merkwürdiger Rückgabetyp in detect_volumes()? Ist das eine key-value-map?
2. Wie finde ich .FLAC-Dateien, also so wie find -iname sie finden würde?

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 266

Wenn das do ist, werf ich doch gleich mal Powershell mit in den Ring. Die Syntax ist ziemlich simpel, es hat so ziemlich das beste RegEx-Flavour dass ich bisher gesehen habe, ist mächtig ohne Ende und kann externe Programme eben so simpel wie Bash aufrufen.

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

TK87 schrieb:

Wenn das do ist, werf ich doch gleich mal Powershell mit in den Ring.

Das ist doch wohl Windoof, oder wie geht das auf Ubuntu?

Und wenn jemand der Meinung ist, dass das jetzt OT ist, kann der Thread gerne ab 9483718 abgeschnitten werden mit dem Titel "Python: .flac-Audios analysieren und normalisiert transkodieren" und mit dem Hinweis: Fortsetzung von bash-skript-rechnen-mit-bc.

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

UlfZibis schrieb:

Da ist wohl ein krummes Zeichen im Dateipfad, nur leider kann ich mit Position 605 nix anfangen, denn der Pfad ist ja gar nicht so lang. Wie kann man den Pfad zum Test in Hex-Notation ausgeben?

Es ist wohl eher das defekte Zeichen im Album-Tag , das ist ungefähr an Position 605:

$ ffmpeg -hide_banner -nostdin -i "Ablage/Suzanne Vega - 99.9F° (1992)/01-suzanne_vega-rock_in_this_pocket_(song_of_david).flac" -af volumedetect -f null /dev/null
Input #0, flac, from 'Ablage/Suzanne Vega - 99.9F° (1992)/01-suzanne_vega-rock_in_this_pocket_(song_of_david).flac':
  Metadata:
    artist          : Suzanne Vega
    title           : Rock In This Pocket (Song Of David)
    date            : 1992
    track           : 1
    genre           : Pop
    Language        : English
    Rip Date        : 2012-04-19
    Retail Date     : 1992-09-08
    Media           : CD
    Encoder         : FLAC 1.2.1
    Ripping Tool    : Exact Audio Copy (Secure Mode)
    Release Type    : Normal release
    ORGANIZATION    : A&M Records
    Album           : 99.9F�
  Duration: 00:03:31.09, start: 0.000000, bitrate: 869 kb/s
  Stream #0:0: Audio: flac, 44100 Hz, stereo, s16
[Parsed_volumedetect_0 @ 0x6348c611f5c0] n_samples: 0
Stream mapping:
  Stream #0:0 -> #0:0 (flac (native) -> pcm_s16le (native))
Output #0, null, to '/dev/null':
  Metadata:
    artist          : Suzanne Vega
    title           : Rock In This Pocket (Song Of David)
    date            : 1992
    track           : 1
    genre           : Pop
    Language        : English
    Rip Date        : 2012-04-19
    Retail Date     : 1992-09-08
    Media           : CD
    Album           : 99.9F�
    Ripping Tool    : Exact Audio Copy (Secure Mode)
    Release Type    : Normal release
    ORGANIZATION    : A&M Records
    encoder         : Lavf60.16.100
  Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
    Metadata:
      encoder         : Lavc60.31.102 pcm_s16le
[out#0/null @ 0x6348c611ef40] video:0kB audio:36364kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
size=N/A time=00:03:31.02 bitrate=N/A speed=2.22e+03x    
[Parsed_volumedetect_0 @ 0x6348c619b780] n_samples: 18618432
[Parsed_volumedetect_0 @ 0x6348c619b780] mean_volume: -15.6 dB
[Parsed_volumedetect_0 @ 0x6348c619b780] max_volume: -0.2 dB
[Parsed_volumedetect_0 @ 0x6348c619b780] histogram_0db: 1026
[Parsed_volumedetect_0 @ 0x6348c619b780] histogram_1db: 2841
[Parsed_volumedetect_0 @ 0x6348c619b780] histogram_2db: 8501
[Parsed_volumedetect_0 @ 0x6348c619b780] histogram_3db: 20676

Die Tags in der Datei sind wohl nicht UTF-8 kodiert und ffmpeg kodiert sie nicht richtig um für die Ausgabe in stdout.

Wie kann man denn den Fehler abfangen, damit das Programm normal weiterläuft? Auch die nachfolgende RegEx-Analyse von dem Output sollte an der Stelle nicht kapitulieren.

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 266

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

TK87 schrieb:

https://learn.microsoft.com/de-de/powershell/scripting/install/install-ubuntu?view=powershell-7.5

Nein, lieber nicht, weil ...

  • Closed Source mit "Nach Hause telefonieren"

  • Sich selbst ändernde apt key Verwaltung

  • Riesiger Footprint mit .NET Paketen

  • typische M$-Lizenz "Big Brother ist watching you"

  • Hab' nach 20 durchstöberten Links immer noch kein mir anschauliches Beispiel gefunden.

  • Eine mir völlig fremde Syntax und Dateipfade wieder mit 'C:' und '\'

  • Kein UbuntuUsers.de-Support

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 266

UlfZibis schrieb:

TK87 schrieb:

https://learn.microsoft.com/de-de/powershell/scripting/install/install-ubuntu?view=powershell-7.5

Nein, lieber nicht, weil ...

  • Closed Source mit "Nach Hause telefonieren"

Falsch, Open Source!

  • Sich selbst ändernde apt key Verwaltung

Machen die Repos von Debian, Ubuntu, Raspberry Pi usw. genauso. Du kannst aber auch alternativ das standalone Paket installieren oder den Tarball herunterladen, entpacken und ausführbar machen. Musst dann halt nur immer manuell updaten.

  • Riesiger Footprint mit .NET Paketen

Nicht bei Powershell Core, welches man unter Linux nutzt.

  • typische M$-Lizenz "Big Brother ist watching you"

Nein, MIT-Lizenz, die so ziemlich freiheste Lizenz überhaupt.

  • Eine mir völlig fremde Syntax und Dateipfade wieder mit 'C:' und '\'

Nein, "C:" und Backslash hast du nur unter Windows, auf Linux hast du die Handelsüblichen Linuxpfade (und selbst unter Windows kannst du auch Slash statt Backslash bei Pfaden nutzen).

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@UlfZibis: Python war ja auch nur ein Vorschlag, weil's meine Lieblingssprache ist. Es gibt wie gesagt auch andere und für Ruby zum Beispiel hier im Forum auch jemanden der da gut helfen kann.

Ja der Rückgabetyp ist ein Wörterbuch (dict), also was bei Bash ein „assoziatives Array“ oder bei Java eine HashMap ist.

Da Wörterbücher mit einem festen Satz an Schlüsseln ja eigentlich Objekte sind, würde ich das in der Regel so nicht machen, aber ich wollte erst einmal nur so knapp wie möglich das Bash-Beispiel umsetzen. Man könnte da auch ein Tupel mit den zwei Werten zurückgeben, oder mit collections.namedtuple() einen Datentyp erstellen, oder gar eine kleine Datenklasse schreiben. Ich habe es mal auf ein Tupel geändert.

Das Kodierungsproblem ist jetzt auch weg. Ich habe einfach die Dekodierung der Ausgabe von ffmpeg raus genommen, dann werden bytes geliefert. Das wonach gesucht wird ist ja reines ASCII und eine Bytefolge, die eine Gleitkommazahl in ASCII beschreibt, kann man float() auch geben.

Falls auch Flac, fLaC, und so weiter gehen darf, also „case insensitive“, dann gibt es dafür ab Python 3.12 bei glob() das case_sensitive-Argument. Davor kann man als Muster "*.[fF][lL][aA][cC]" angeben. Was zugegebenermassen ein bisschen hässlich ist.

Ungetestet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env python3
import re
import subprocess
from pathlib import Path


def detect_volumes(flac_file_path):
    result = subprocess.run(
        [
            "ffmpeg",
            "-hide_banner",
            "-nostdin",
            *("-i", str(flac_file_path)),
            *("-af", "volumedetect"),
            *("-f", "null"),
            "/dev/null",
        ],
        capture_output=True,
        check=True,
    )
    volumes = {
        match[1]: float(match[2])
        for match in re.finditer(
            rb"(mean|max)_volume: (.*?) dB", result.stderr
        )
    }
    return (volumes[b"mean"], volumes[b"max"])


def main():
    flac_directory_count = 0

    directory_paths = sorted(
        path for path in Path("Ablage").rglob("*") if path.is_dir()
    )
    for directory_path in directory_paths:
        #
        # Vor Python 3.12:
        # 
        flac_file_paths = sorted(directory_path.glob("*.[fF][lL][aA][cC]"))
        #
        # Ab Python 3.12:
        #
        flac_file_paths = sorted(
            directory_path.glob("*.flac", case_sensitive=False)
        )
        for flac_file_path in flac_file_paths:
            print(flac_file_path)
            mean_volume, max_volume = detect_volumes(flac_file_path)
            print(
                f"mean volume: {mean_volume} dB, max_volume: {max_volume} dB"
            )

        if flac_file_paths:
            flac_directory_count += 1
            print("files:", len(flac_file_paths))
            print()

    print("Number of dirs total:", len(directory_paths))
    print("Number of dirs with flac files:", flac_directory_count)
    print("\n")


if __name__ == "__main__":
    main()

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

TK87 schrieb:

Falsch, Open Source!

Echt, wo kann man die finden? Bei der URL "microsoft.com" bin ich da erst mal gar nicht drauf gekommen, dass es die geben könnte.
Und bist Du sicher, dass da keine binären BLOB's drin sind, so wie es bei VSCode der Fall ist.

Machen die Repos von Debian, Ubuntu, Raspberry Pi usw. genauso.

Bzgl. des OS-Herstellers selbst finde ich das OK. Bei Fremdsoftware hätte ich aber gerne selber die Kontrolle. Wozu machen die MSofties das, wenn es auch mit festem Schlüssel genauso gut ginge?

Nein, MIT-Lizenz, die so ziemlich freiheste Lizenz überhaupt.

Mag sein.

Nein, "C:" und Backslash hast du nur unter Windows, auf Linux hast du die Handelsüblichen Linuxpfade

Das Tutorial ist dann erstmal nur für Windoof-Nutzer, denn da finde ich nur '\'-Beispiele.
Im übrigen finde ich das Tutorial sehr unübersichtlich.

(und selbst unter Windows kannst du auch Slash statt Backslash bei Pfaden nutzen).

Probier da mal dir /B. Wetten, dass Du dann nicht den Inhalt von Verzeichnis B angezeigt bekommst.

Nun ja, gut zu wissen, das es das gibt. Sicher hilfreich für Windoof-Umsteiger, doch ich bin schon seit über 15 Jahren da raus.
Viele meiner Bedenken konntest Du tatsächlich zumindest entkräften 👍 Aber noch eine Skript-Engine installieren, wo ich doch schon etliche out-of-the-box habe? Und noch eine neue Sprache und wieder M$-Denklogik lernen? Nach erstem Anschauen finde ich die Syntax auch ziemlich grässlich.

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

Marc_BlackJack_Rintsch schrieb:

@UlfZibis: Python war ja auch nur ein Vorschlag,

Mich nicht falsch verstehen. Mir gefällt Python durchaus gut, nur braucht's halt immer wieder Eingewöhnung.

Man könnte da auch ein Tupel mit den zwei Werten zurückgeben,

Ziemlich cool, vermisse ich in Java schon lange. Immerhin gib's seit kurzem den record-Typ, ist aber ein bisschen aufwendiger und hakelig in der Nutzung.

Das Kodierungsproblem ist jetzt auch weg. Ich habe einfach die Dekodierung der Ausgabe von ffmpeg raus genommen, dann werden bytes geliefert. Das wonach gesucht wird ist ja reines ASCII ...

Genau, fein. Dass "universal_newlines" Kodierung bedeutet, muss man erst mal drauf kommen. 💡

... dann gibt es dafür ab Python 3.12 bei glob() das case_sensitive-Argument.

Cool, ich hab' Version 3.12.4.

Davor kann man als Muster "*.[fF][lL][aA][cC]" angeben. Was zugegebenermassen ein bisschen hässlich ist.

Geht schon, erinnert an RegEx.

Ungetestet:

Wieder mal super lieben Dank für die Mühe.

Warum waren im vorherigen print-Ausdruck noch mal zusätzliche Klammern "()" im Argument?

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@UlfZibis: Text ist eigentlich text=True, aber es ist auch in den Argumenten universal_newlines=... und encoding=... implizit enthalten, weil die beiden jeweils nur Sinn machen wenn man Text statt Bytes haben will. Kodierung wollte ich nicht vorgeben, kann ja sein, dass was anderes im System eingestellt ist, und universal_newlines ist in der Regel ganz praktisch. Das bedeutet das alle möglichen Varianten/Kombinationen vom Wagenrücklauf und Zeilenvorschub erkannt und in einen Zeilenvorschub "\n" umgewandelt werden.

Das ist tatsächlich ein „globbing“-Muster das auch Shells verstehen:

1
2
3
4
5
6
$ ls *.jpg
test.jpg
$ ls *.JPG
TEST.JPG
$ ls *.[jJ][pP][gG]
test.jpg  TEST.JPG

Welches print() meinst Du? Ich hatte ja auf Tupel umgestellt und die beiden enthaltenen Werte an der Aufrufstelle dann gleich an zwei Namen zugewiesen. Und dem print() dann nicht mehr mehrere Argumente übergeben, sondern nur eine f-Zeichenkette, wo man Werte/Ausdrücke mit {...} rein formatieren kann. Das hatte ich vorher nicht gemacht, weil in den Ausdrücken Anführungszeichen vorkamen. Ältere Python-Versionen können in den Ausdrücken innerhalb von f-Zeichenketten nicht die gleichen Anführungszeichen verwenden, die auch von der f-Zeichenkette verwendet werden. Bei aktuellen Python-Versionen geht das mittlerweile, hätte bei Dir also auch funktioniert. Ich bin da immer etwas konservativ was Neuerungen angeht, weil ich beruflich teilweise mit älteren Python-Versionen zu tun habe, die ich auch nicht einfach aktualisieren kann.

Edit: dir /B würde man in der PowerShell ja auch nicht schreiben und das ist ein ”Problem” von/mit dir weil das Programm den / nicht als Pfadtrenner behandelt sondern für Optionen/Schalter verwendet. Wobei dir in der PowerShell wohl ein Alias ist und nicht das dir-Kommando von der CMD.EXE. Get-ChildItem -Path /B sollte funktionieren und den Inhalt von /B auflisten.

UlfZibis

(Themenstarter)

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

Marc_BlackJack_Rintsch schrieb:

... Das bedeutet das alle möglichen Varianten/Kombinationen vom Wagenrücklauf und Zeilenvorschub erkannt und in einen Zeilenvorschub "\n" umgewandelt werden.

Fein.

Welches print() meinst Du?

Oh, falsch geguckt. Ich meinte das hier:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    result = subprocess.run(
        [
            "ffmpeg",
            "-hide_banner",
            "-nostdin",
            *("-i", str(flac_file_path)),
            *("-af", "volumedetect"),
            *("-f", "null"),
            "/dev/null",
        ],

Ich hatte ja auf Tupel umgestellt und die beiden enthaltenen Werte an der Aufrufstelle dann gleich an zwei Namen zugewiesen.

Wäre es da nicht einfacher und vielleicht auch performanter (zumindest wenn vorher bis "Parsed_volumedetect_0 " vorgespult wird), gleich sowas wie:

1
2
mean = re.find(rb"(mean_volume: )(\S*)", result.stderr).match(2)
max = re.find(rb"(max_volume: )(\S*)", result.stderr).match(2)

zu nehmen? Oder sowas:

1
2
mean, remain = re.find(rb"(.*)(mean_volume: )(\S*)(.*)", result.stderr).match(3, 4)
max = re.find(rb"(.*)(max_volume: )(\S*)", remain).match(3)

... wo man Werte/Ausdrücke mit {...} rein formatieren kann. Das hatte ich vorher nicht gemacht, weil in den Ausdrücken Anführungszeichen vorkamen. Ältere Python-Versionen können in den Ausdrücken innerhalb von f-Zeichenketten nicht die gleichen Anführungszeichen verwenden, die auch von der f-Zeichenkette verwendet werden. ...

Auch interessant.

Edit: dir /B würde man in der PowerShell ja auch nicht schreiben und das ist ein ”Problem” von/mit dir weil das Programm den / nicht als Pfadtrenner behandelt sondern für Optionen/Schalter verwendet. Wobei dir in der PowerShell wohl ein Alias ist und nicht das dir-Kommando von der CMD.EXE.

Danke für die Auflärung.

Get-ChildItem -Path /B

Das ist dann also die vielgelobte Syntax anstatt einfach nur: dir \B

Inzwischen habe ich das neue Script getestet. Nach längerer Laufzeit bekam ich dann leider noch einen Fehler, der auch abgefangen werden müsste:

Ablage/The Rolling Stones - Beggars Banquet (1968 Japan 2008)/10 - The Rolling Stones - On With The Show.flac
Traceback (most recent call last):
  File "/mnt/Daten/Users/ich/Momentum/./vol_dedect_2.py", line 65, in <module>
    main()
  File "/mnt/Daten/Users/ich/Momentum/./vol_dedect_2.py", line 49, in main
    mean_volume, max_volume = detect_volumes(flac_file_path)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/Daten/Users/ich/Momentum/./vol_dedect_2.py", line 8, in detect_volumes
    result = subprocess.run(
             ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['ffmpeg', '-hide_banner', '-nostdin', '-i', 'Ablage/The Rolling Stones - Beggars Banquet (1968 Japan 2008)/10 - The Rolling Stones - On With The Show.flac', '-af', 'volumedetect', '-f', 'null', '/dev/null']' returned non-zero exit status 183.

Offensichtlich werden Fehler, die ffmpeg selbst auswirft, noch nicht behandelt. Die ausführliche Fehlermeldung sieht so aus:

$ ffmpeg -hide_banner -nostdin -i "Ablage/The Rolling Stones - Beggars Banquet (1968 Japan 2008)/10 - The Rolling Stones - On With The Show.flac" -af volumedetect -f null /dev/null
[flac @ 0x636779fa5ec0] Format flac detected only with low score of 1, misdetection possible!
[flac @ 0x636779fa5ec0] Could not find codec parameters for stream 0 (Audio: flac, 0 channels): unspecified sample format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, flac, from 'Ablage/The Rolling Stones - Beggars Banquet (1968 Japan 2008)/10 - The Rolling Stones - On With The Show.flac':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Audio: flac, 0 channels
[Parsed_volumedetect_0 @ 0x636779fa71c0] n_samples: 0
Stream mapping:
  Stream #0:0 -> #0:0 (flac (native) -> pcm_s16le (native))
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Error while filtering: Invalid data found when processing input
[out#0/null @ 0x636779fa79c0] Nothing was written into output file, because at least one of its streams received no packets.
size=       0kB time=N/A bitrate=N/A speed=N/A    
Conversion failed!

PS: Die Datei lässt sich auch nicht abspielen, ist also kaputt und muss nur mit Hinweismeldung (am Schluss, damit ich es nicht übersehe) übersprungen werden.