fmerst
Goto Top

Powershell - Elemente einer Auflistung nicht ansprechbar

Hallo Community,
nach ersten guten Erfahrungen mit dieser Gruppe hier noch einmal eine hoffentlich interessante Frage

Ich habe einige Songs, die als MP3 mit 320kBit/s vorliegen.
Alle Songs haben ID3-Tags, also die Infos zu Album, Titel, Artist, etc..

Da auf der Speicherkarte meines Mobiles (zu) wenig Platz vorhanden ist, wollte ich die Songs verschlanken, nämlich auf 128kBit/s.
Lame macht das soweit ganz gut, leider gehen dabei die ID3-Tags verloren.

Mit Powershell unter Verwendung der TAGLIB (developer.novell.com/wiki/index.php/TagLib_Sharp)
gelingt es, die Tag Infos auszulesen und auch wieder zu schreiben. Leider ist der Code noch nicht so ganz "state of the art".

Daher folgende Frage:
Das Object $media enthält zur Laufzeit die aktuell im Zugriff befindliche MP3-Datei. Mit $media.tag wird auf die Auflistung aller ID3-Tags zugegriffen.
Unter Verwendung namentlicher Benennung, (siehe im Code z.B. Zeilen 62-65) also z.B. $media.tag.ARTIST oder $media.tag.TITEL läßt sich auch alles verarbeiten.
Jedoch ist das sehr umständlich. Für jede Aktion (Auslesen/Schreiben) ist jedes Tag einzeln zu referenzieren. Auch ist bei der namentlichen Benennung nie ausgeschlossen,
dass eines dieser Tags übersehen oder vergessen wird.
Wie kann man die Verarbeitung in eine ordentliche Zeile Code packen, in der jedes dieser Tags über seien Index in $media.tag angesprochen wird.
Ziel ist es:

- Alle Tags eines Songs auslesen und in Variable(n) zu speichern
- Dann mit Lame aus dem Song eine neue Daei erzeugen, die nur 128kBit/S hat
- Abschließend der neuen Datei die Tags, die ja in der/den Variable(n) gespeichert sind, wieder zufügen.


Mein Ansatz war: Erstellen von Variblen, deren Name aus einem Präfix ($lv_) und dem Namen des Tags (z.B. Artist) besteht, also $lv_Artist. Leider geling mir das nicht.
Im Code zeigt zwar $tag_prop zur Laufzeit mit "ARTIST" oder "TITEL" das gewünschte Tag, aber es läßt sich nicht zur weiteren Verwendung nutzen.
Eine Zeile wie: $testen = get-variable $tag_prop -valueonly
liefert Fehler der Art: Get-Variable : Es kann keine Variable mit dem Namen "Microsoft.PowerShell.Commands.Internal.Format.FormatStartData" gefunden werden.

Wer kann mit einer guten Idee helfen?

Vielen Dank für Eure Bemühungen.


Anbei der Code, wie er bisher gedieen ist:

$TagLib = "C:\Programme Sourcen\ID3_TagLib\taglib-sharp-2.0.3.4-windows\Libraries\taglib-sharp.dll"  
[void][System.Reflection.Assembly]::LoadFile($TagLib)

$ZielDir = "E:\Songs 128 kbit"  
$LameDir = "C:\Program Files\Audiograbber"  


foreach ($ordner in get-childitem "E:\songs\00_to_be_converted" -recurse -filter *. | ? { $_.PSisContainer -eq $true} )   
    # ------------------------------------------------------------------------------------
    # schleife über alle Ordner des Quell-Pfades
    # ------------------------------------------------------------------------------------

   {
	
    foreach ($file in Get-Childitem $ordner.FullName -filter *.mp3 )
   
    # ------------------------------------------------------------------------------------
    # schleifeüber alle mp3 dateien des ordners
    # ------------------------------------------------------------------------------------
    
    {
            
      $currentfile = $ordner.FullName + "\" + $file  
           
      # ---------------------------------------------
      # für das file nun das Tag Objekt erstellen 
      $media = [TagLib.File]::Create( $currentfile )
      # ---------------------------------------------
      
      # jetzt die tags des files auslesen
      
      foreach ($xx in $media.tag)
                # ------------------------------------------------------------------------------------
                # tags der mp3 datei auslesen
                # ------------------------------------------------------------------------------------

                {
                        # listet die namen aller TagMembers auf - also zB. "Titel", "Album", "Artist" , .... 
                        # das Format-Table (abgekürzt ft) funktioniert nur, weil der initialisierung der TAGLIB (allererste Zeilen dieses Skriptes)
                        # ein [void] vorangestellt wurde. Dessen Bedeutung ist (noch) gesondert (zu) erörtern.
                        # http:{{comment_single_line_double_slash:0}}
                        # ------------------------------------------------------
                        # $media.tag | get-member -MemberType Property | ft name
                        # ------------------------------------------------------
                        # mit der so gewonnenen Info können jetzt die Elemente unter Verwendung dynamischer variblen gezielt abgefragt / 
                        # bzw. gespeichert werden.
                                           
                   
                        foreach ($tag_prop in $media.tag | get-member -MemberType Property | ft name  )
                       
                         
			# infos der Tags können nun abgefragt werden
	                'Composers                : '   + $media.tag.Composers                  
        	        'ComposersSort            : '   + $media.tag.ComposersSort              
                	'TitleSort                : '   + $media.tag.TitleSort                  
	               	'AlbumSort                : '   + $media.tag.AlbumSort      
                        # und viele mehr

		
			# infos der Tags sollen in Variable zwischengepuffert werden
                        if ($media.tag.Composers -ne '') {$lv_Composers = $media.tag.Composers} else {$lv_Composers = ''}  
                	if ($media.tag.ComposersSort -ne '') {$lv_ComposersSort = $media.tag.ComposersSort} else {$lv_ComposersSort = ''}  
                	if ($media.tag.TitleSort -ne '') {$lv_TitleSort = $media.tag.TitleSort} else {$lv_TitleSort = ''}  
                	if ($media.tag.AlbumSort -ne '') {$lv_AlbumSort = $media.tag.AlbumSort} else {$lv_AlbumSort = ''}  
               		# und viele mehr
                
                }
                                
                # variable rücksetzen, damit kein versehentlicher Zugriff auf Tags des Original-Files erfolgt
                $media = ''  
                
                # ------------------------------------------------------------------------------------
                #
                # prüfen, ob Name für Zieldatei bereits belegt,
                #          falls ja:
                #          dem Namen für Zieldatei ein Datums-String zufügen
                #
                # ------------------------------------------------------------------------------------
                   
                $Date = get-date -uformat "%Y%m%d-%H%M%S"   
                
                $File_To_Be_Tagged = $ZielDir + "\" + $file  
                $testfile = $File_To_Be_Tagged
                $extension = $file.Extension
                
                # loop bis Namen für Zieldatei noch nicht belegt
                while (test-path $testfile)
                {
                $Date = get-date -uformat "%Y%m%d-%H%M%S"   
                # Achtung GetFileNameWithoutExtension extrahiert auch den Pfad.
                # Also: Hinterher den Pfad einfach wieder voranstellen
                $testfile = [IO.Path]::GetFileNameWithoutExtension($File_To_Be_Tagged) + "_" + $date + $extension  
                $testfile = $ZielDir + "\" + $testfile  
                }
                
                # falls Namen für Zieldate belegt war: nehme die Version, an der Datum zugefügt war
                if  ($File_To_Be_Tagged -ne $testfile) 
                    {
                     $File_To_Be_Tagged = $testfile
                     # setze variable $testfile zurück
                     $testfile =''  
                    }
                             
                # ------------------------------------------------------------------------------------
                #
                # mit lame runterdampfen und dabei in das 128 kb/s verzeichnis kopieren 
                # 
                # ------------------------------------------------------------------------------------
                
                $Programm = """" +$LameDir + "\lame.exe" + """"   
                $ProgrammArguments = " -b 128 -h " + """" + $currentfile + """" + "  " +  """" + $File_To_Be_Tagged + """"  
                                
                $programm
                $ProgrammArguments
                
                # Lame aufrufen   
                # -wait zwingt Schleife zu warten, bis das externe Programm (=lame) beendet ist             
                Start-Process -filepath $Programm -ArgumentList $ProgrammArguments -wait
            
      		# ----------------------------------------------
      		# für das neue file nun das Tag Objekt erstellen 
      		$media = [TagLib.File]::Create( $currentfile )
      		# ----------------------------------------------
                $File_To_Be_Tagged = $ZielDir + "\" + $file   
                #  tag-objekt für neues file öffnen
                "Neues Tag Objekt= " + $File_To_Be_Tagged  
                $media = [TagLib.File]::Create($File_To_Be_Tagged)
                                 
                # ------------------------------------------------------------------------------------
                #
                # dem NEUEN file jetzt die ALTEN tags überbraten 
                # 
                # ------------------------------------------------------------------------------------
           
                if ($lv_Composers -ne '') {$media.tag.Composers = $lv_Composers}   
                if ($lv_ComposersSort -ne '') {$media.tag.ComposersSort = $lv_ComposersSort}   
                if ($lv_TitleSort -ne '') {$media.tag.TitleSort = $lv_TitleSort}   
                if ($lv_AlbumSort -ne '') {$media.tag.AlbumSort = $lv_AlbumSort}   
		# und viele mehr
                
               
                #  tags im neuen File speichern
                $media.Save()
     
     }  # ende von foreach $file

}  # ende von foreach $ordner

Content-Key: 138728

Url: https://administrator.de/contentid/138728

Printed on: April 18, 2024 at 00:04 o'clock