Multi-Value Tag-Felder formatieren

Hallo,

ich benutze Musicbrainz Picard, MP3Tag und Foobar2000 zum Verwalten meiner Musiksammlung.
MP3s verwenden in allen Programme den ID3V2.4 Standard.
Wenn ich in MP3Tag die Tags der mit Picard gespeicherten MP3s auslese, kann ich sehen, dass Picard die Musiker im Tag MUSICIANCREDITS gespeichert hat, in diesem Format:

bass guitar:Todd Harrell;guitar:Chris Henderson;guitar:Matt Roberts;guest hammond organ:Rick Hopkins;guest drums:Josh Freese;vocal:Brad Arnold;guest strings:David Campbell;guest percussion:Matthew Burgess;

Foobar zeigt sie aber anscheinend nur korrekt an, wenn die Musiker im Tag PERFORMER als Multi-Value Tag gespeichert sind.
Also ändere ich mit Tag-Feld formatieren den Namen des Tags in PERFORMER und splitte ihn mit Tag-Feld aufteilen (Trennzeichen ; ) in ein Multi-Value Tag.

Damit werden die Musiker in MP3Tag so angezeigt:

PERFORMER bass guitar:Todd Harrell
PERFORMER guitar:Chris Henderson
PERFORMER guitar:Matt Roberts
...

Jetzt möchte ich das Feld noch formatieren, dass es so aussieht:

PERFORMER Todd Harrell (bass guitar)
PERFORMER Chris Henderson (guitar)
PERFORMER Matt Roberts (guitar)
...

ich denke, mit einem Single-Value Feld müsste es so funktionieren:

$ifgreater($strstr(%performer%,':'),0,$cutLeft(%performer%,$strstr(%performer%,':'))' ('$left(%performer%,$sub($strstr(%performer%,':'),1))')',%performer%)

Aber wie krieg ich das mit einem Multi-Value Feld hin?

Von ...
MUSICIANCREDITS=bass guitar:Todd Harrell;guitar:Chris Henderson;guitar:Matt Roberts;guest hammond organ:Rick Hopkins;guest drums:Josh Freese;vocal:Brad Arnold;guest strings:David Campbell;guest percussion:Matthew Burgess;

nach ...
PERFORMER=Todd Harrell (bass guitar)
PERFORMER=Chris Henderson (guitar)
PERFORMER=Marc Roberts (guitar)
PERFORMER=Rick Hopkins (guest hammond organ)
PERFORMER=Josh Freese (guest drums)
PERFORMER=Brad Arnold (vocal)
PERFORMER=David Campbell (guest strings)
PERFORMER=Matthew Burgess (guest percussion)

mit ...
Aktion: Tag-Feld formatieren
Feld: PERFORMER
Formatstring: $regexp(%MUSICIANCREDITS%,'([^:]+):([^;]+);','$2 ($1)\\')

DD.20140610.0727.CEST

Danke, das funktioniert schon mal sehr gut!
Eine Frage hätte ich dann noch.. Musicbrainz Picard speichert manche Musiciancredits falsch, z.B. so (nachdem ich sie mit der Aktion oben in Performer geändert habe):

PERFORMER=Nanette Newman (choir vocals vocal)
PERFORMER=Madeline Bell (choir vocals vocal)
PERFORMER=Doris Troy (guest background vocals vocal)
PERFORMER=Nanette Newman (guest background vocals vocal)
....

Wie kann ich den Teil in Klammern ändern, dass es so aussieht:

PERFORMER=Nanette Newman (choir vocals)
PERFORMER=Madeline Bell (choir vocals)
PERFORMER=Doris Troy (guest background vocals)
PERFORMER=Nanette Newman (guest background vocals)
....

PS: Hab ich das richtig verstanden, ich kann den regex string auf jedes Feld eines Multivalue Tags anwenden, wenn ich am Ende "\\" schreibe, weil die einzelnen Tags mit \\ getrennt werden?

Für Änderungen, die alle Einzelwerte eines Mehrfach-Werte Tag-Feldes gleichermaßen betreffen, sollte man die Einzelwerte zusammenfassen in eine gesamte Zeichenkette, und diese dann bearbeiten, bzw. die Berarbeitung sollte man erledigen vor der Aufteilung in ein Mehrfach-Werte Tag-Feld.

Von ...
MUSICIANCREDITS=choir vocals vocal:Nanette Newman;choir vocals vocal:Madeline Bell;guest background vocals vocal:Doris Troy;guest background vocals vocal:Nanette Newman;

nach ...
PERFORMER=Nanette Newman (choir vocals)
PERFORMER=Madeline Bell (choir vocals)
PERFORMER=Doris Troy (guest background vocals)
PERFORMER=Nanette Newman (guest background vocals)

mit ...
Aktion: Tag-Feld formatieren
Feld: MUSICIANCREDITS
Formatstring: $replace(%MUSICIANCREDITS%,' vocal:',':')
... oder ...
Formatstring: $replace(%MUSICIANCREDITS%,' vocals vocal:',' vocals:')

Aktion: Tag-Feld formatieren
Feld: PERFORMER
Formatstring: $regexp(%MUSICIANCREDITS%,'([^:]+):([^;]+);','$2 ($1)\\')

Es gibt Zeichen mit besonderer Bedeutung, wozu auch der Backslash gehört, die in einem regulären Ausdruck mit einem Backslash "entwertet" werden müssen, so wird aus '' dann '\\'.

Wenn man die Einzelwerte eines "multi-value tag-field" z. B. mit der Funktion $meta_sep in einer gemeinsamen "Werteliste" (Zeichenkette) zusammenfasst, dann kann man diese Zeichenkette als eine Einheit umfassend bearbeiten, anschließend kann man die Zeichenkette auch wieder in Einzelwerte zerlegen.
Mit der Funktion $meta(Tagfeldname,n) kann man einen Einzelwert direkt auslesen, jedoch nicht zurück schreiben.

Wenn zwei oder mehr Einzelwerte jeweils mit einer Doppel-Backslash Zeichenkette '\\' verbunden werden, dann erzeugt Mp3tag daraus automatisch beim Speichern ein "multi-value tag-field".

DD.20140610.1627.CEST

So wird aber jedes "vocal" entfernt, oder?
Also auch bei

Mick Jagger (lead vocal)

Also muss ich jeden Performer, der geändert werden soll, spezifisch angeben:

Aktion: Tag-Feld formatieren
Feld: MUSICIANCREDITS
Formatstring: $replace(%MUSICIANCREDITS%,'guest background vocals vocal','guest background vocals')

Aktion: Tag-Feld formatieren
Feld: MUSICIANCREDITS
Formatstring: $replace(%MUSICIANCREDITS%,'choir vocals vocal','choir vocals')

MUSICIANCREDITS möchte ich anschließend löschen, da es sonst im Foobar Filter falsch angezeigt wird. Wenn ich die Aktion dann bei der gleichen Datei 2x hintereinander ausführe, löscht er die PERFORMER Tags, deshalb soll es noch nachschauen, ob das MUSICIANCREDITS Tag überhaupt existiert:

Aktion: Tag-Feld formatieren
Feld: PERFORMER
Formatstring: $if(%MUSICIANCREDITS%,$regexp(%MUSICIANCREDITS%,'([^:]+):frowning:[^;]+);','$2 ($1)\\'),%performer%)

Tag-Felder entfernen: MUSICIANCREDITS

Folgender Fehler von Picard ist mir auch noch aufgefallen:
Bei mp3s erstellt er das Tag INVOLVEDPEOPLE, das von Foobar nicht erkannt wird:

INVOLVEDPEOPLE=producer:Barrett Jones;producer:Foo Fighters;engineer:Steve Culp;mix:Tom Rothrock;mix:Rob Schnapf;

Bei FLACs werden die korrekten Tags erstellt und in MP3Tag und Foobar so angezeigt:

ENGINEER=Steve Culp
MIXER=Tom Rothrock
MIXER=Rob Schnapf
PRODUCER=Barrett Jones
PRODUCER=Foo Fighters

Neben ENGINEER, MIXER, PRODUCER habe ich in INVOLVEDPEOPLE noch gefunden:
(arranger) ->FLAC: ARRANGER
(dj-mix) -> FLAC: DJMIXER

Wie ordne ich INVOLVEDPEOPLE den richtigen Tags zu?

Weil du den Original Musicbrainz Text nicht mit anzeigst, so nehme ich an, dass der Text im Original ist ...
lead vocal:MickJagger;
Das aber ist ein anderer Fall als der zuvor besprochene Fall, bei dem es um einen Text ging, der in einer Zeichenkette eine Aufzählung enthält von unterschiedlichen Rollen und/oder Stilen, getrennt mit einem Leerzeichen, so ausgeliefert von Musicbrainz wie du sagst.

Das Ergebnis "Mick Jagger (lead vocal)" gehört vermutlich zu einer anderen Fallsituation als "Nanette Newman (choir vocals), was umformatiert war aus "choir vocals vocal:Nanette Newman;"

Und wenn nicht, dann stammt "Mick Jagger (lead vocal)" aus "lead vocal vocal:Mick Jagger;", und somit hätte es kein Problem gegeben.

Hmm ... das glaube ich jetzt nicht, das wäre ja auch etwas mühsam ... aber dass man nicht alles über einen Kamm scheren kann, das ist sicherlich zu erwarten, vielleicht kann man bei sorgfältiger Betrachtung der Ausgangslage (Musicbrainz Text) möglicherweise zwei oder drei Fälle unterscheiden.

Es ist im Moment auch nicht klar, ob du das $replace Beispiel richtig nachvollzogen hast.
Wie du erkennen kannst, wird der Doppelpunkt sozusagen als Anker benutzt ...
und es ist fraglich, wie der Originaltext ausgesehen hat, der zu dem Ergebnis "Mick Jagger (lead vocal)" geführt hat.
Außerdem ist unklar, warum du an dem Ergebnis "Mick Jagger (lead vocal)" noch etwas ändern willst?

Das sieht aus wie eine Liste von "Rolle:Name;" Elementen.
Was ist daran ungewöhnlich?

Was sind denn die richtigen Tagfeldnamen?

DD.20140610.2135.CEST

Genau, das ist der Original Text. Sorry, hätte ich dazu schreiben sollen.

In diesem Fall will ich eben nichts ändern, sondern nur bei choir vocals vocal und guest background vocals vocal. Evtl. fallen mir später noch andere ähnliche fehlerhafte Einträge auf. Deshalb würde ich für jeden fehlerhaften Performer Typus einen eigenen Aktionsschritt machen, damit ich nicht fälschlicherweise einen korrekten Performer Typ (wie lead vocal) mitändere.

Für den gleichen Musicbrainz Eintrag (Beispiel Track 1: "This Is a Call") schreibt Picard bei mp3-Dateien andere Tags als bei FLACs.

Wenn ich mir die Tags in MP3Tag ansehe, steht dort in der FLAC-Datei:
ENGINEER=Steve Culp
MIXER=Tom Rothrock
MIXER=Rob Schnapf
PRODUCER=Barrett Jones
PRODUCER=Foo Fighters

Und in der MP3:
INVOLVEDPEOPLE=producer:Barrett Jones;producer:Foo Fighters;engineer:Steve Culp;mix:Tom Rothrock;mix:Rob Schnapf;

In der FLAC sind also die producer-, engineer-, mix-Rollen getrennt in jeweilige Multivalue-Felder gespeichert, in der mp3 sind sie zusammengefasst in INVOLVEDPEOPLE.

Foobar kann aber anscheinend mit INVOLVEDPEOPLE nichts anfangen, denn bei den mp3-Tags zeigt Foobar den Inhalt nicht korrekt an, sondern schneidet den Tag-Inhalt vor dem ersten ':' ab. Bei FLACs werden alle Techniker-Rollen, also Mixer, Engineer (bei anderen Tracks auch Arranger, DJ-Mixer,...) getrennt in eigenen Tags angezeigt:

:slight_smile:

In Mp3tag hast du viele Freiheiten, das zu tun, was du für richtig hältst.

Vielen Dank für die Gegenüberstellung.
Da gibt es bei "MP3" ein Tag-Feld "INVOLVED PEOPLE" ... oder "INVOLVEDPEOPLE"?
Siehe ...
/t/15592/1
http://forums.musicbrainz.org/viewtopic.php?id=3391

Bei FLAC Dateien kommt ein anderes Tagging-System zum Einsatz, VORBIS COMMENT.

DD.20140611.0909.CEST

Also ist es nicht möglich,

INVOLVEDPEOPLE=producer:Barrett Jones;producer:Foo Fighters;engineer:Steve Culp;mix:Tom Rothrock;mix:Rob Schnapf;

in

ENGINEER=Steve Culp
MIXER=Tom Rothrock
MIXER=Rob Schnapf
PRODUCER=Barrett Jones
PRODUCER=Foo Fighters

zu ändern? Ich habe gehofft, dass es dafür einen regulären Ausdruck gibt, aber meine regex-Fähigkeiten reichen dafür nicht ganz aus..

Eigentlich ist es mit der Benutzeroberfläche von Mp3tag nicht möglich, das gewünschte Ergebnis zu erlangen.
Achtung: Benutzer 'seppl' zeigt, dass es doch geht ...
Multi-Value Tag-Felder formatieren

Mp3tag bietet leider keine Funktion zur Bearbeitung von Listen und zum Sortieren.
Mit "dreimal um die Ecke denken" habe ich eine mögliche Lösung gefunden.

  1. Die betreffende Musikdatei muss ein Tag-Feld INVOLVEDPEOPLE haben, ...
    welches eine Liste enthält von "Rolle:Name;" Einträgen, z. B. ...
    INVOLVEDPEOPLE=producer:Barrett Jones;engineer:Steve Culp;mix:Tom Rothrock;mix:Rob Schnapf;producer:Foo Fighters;

  2. Die Musikdatei selektieren und ein Export Skript ausführen.
    Das spezielle Mp3tag MTE Skript (Export) erzeugt aus den Daten im Tag-Feld INVOLVEDPEOPLE ein spezielles Mp3tag MTA Skript (Aktionengruppe).
    Im Export Skript wird je "Rolle:Name;" Eintrag prinzipiell der gleiche Funktionenblock ausgeführt.
    Bei mehreren Einträgen muss das Export Skript entsprechend angepasst werden.

  3. Die Musikdatei selektieren und die neue zuvor erzeugte MTA Aktionengruppe ausführen.

  4. Für das gegebene Beispiel sieht das Ergebnis dann so aus ...
    ENGINEER Steve Culp
    MIX Rob Schnapf
    MIX Tom Rothrock
    PRODUCER Barrett Jones
    PRODUCER Foo Fighters

Auszug aus dem Export Skript ...

01: $puts(K,$regexp(%INVOLVEDPEOPLE%,'^(?:.+;)*(.+?):(.+?);(?:.+?;){0}$','\U$1'))

02: $if($eql($get(K),%INVOLVEDPEOPLE%),,
03: $puts(K_LIST,$ifgreater($strstr($get(K_LIST),$get(K)),0,$get(K_LIST),$get(K_LIST)$char(124)$get(K)))
04: $puts(V,$regexp(%INVOLVEDPEOPLE%,'^(?:.+;)*(.+?):(.+?);(?:.+?;){0}$','$2'))
05: $puts(K_V_LIST,$get(K)'_V_LIST')
06: $puts($get(K_V_LIST),$ifgreater($strstr($get($get(K_V_LIST)),$get(V)),0,$get($get(K_V_LIST)),$get($get(K_V_LIST))$char(124)$get(V)))
07: '[#0]'$get(br)
08: 'T=5'$get(br)
09: 'F='$get(K)$get(br)
10: '1='''$replace($get($get(K_V_LIST)),$char(124),'\\')''$get(br))

Beispiel für ein erzeugtes MTA Skript ...

[#0]
T=5
F=PRODUCER
1='\\\\Barrett Jones'
[#1]
T=5
F=MIX
1='\\\\Rob Schnapf'
[#2]
T=5
F=MIX
1='\\\\Rob Schnapf\\\\Tom Rothrock'
[#3]
T=5
F=ENGINEER
1='\\\\Steve Culp'
[#4]
T=5
F=PRODUCER
1='\\\\Barrett Jones\\\\Foo Fighters'

Export Skript ...
Test.20140612.Split.INVOLVEDPEOPLE.mte (5.91 KB)

DD.20140613.1100.CEST, DD.20140613.2016.CEST

Test.20140612.Split.INVOLVEDPEOPLE.mte (5.91 KB)

Vielen Dank Detlev, ich habe es aber jetzt selbst so gelöst:

Tagfeld formatieren "MIXER": $replace($regexp($regexp(%involvedpeople%,'mix:([^;]+)','$1\\\\'),'(arranger|DJ-mix|engineer|producer):([^;]+)',),';','\\\\')

Tagfeld formatieren "PRODUCER": $replace($regexp($regexp(%involvedpeople%,'producer:([^;]+)','$1\\\\'),'(arranger|DJ-mix|engineer|mix):([^;]+)',),';','\\\\')

Tagfeld formatieren "ENGINEER": $replace($regexp($regexp(%involvedpeople%,'engineer:([^;]+)','$1\\\\'),'(arranger|DJ-mix|mix|producer):([^;]+)',),';','\\\\')

Tagfeld formatieren "DJMIXER": $replace($regexp($regexp(%involvedpeople%,'DJ-mix:([^;]+)','$1\\\\'),'(arranger|engineer|mix|producer):([^;]+)',),';','\\\\')

Tagfeld formatieren "ARRANGER": $replace($regexp($regexp(%involvedpeople%,'arranger:([^;]+)','$1\\\\'),'(DJ-mix|engineer|mix|producer):([^;]+)',),';','\\\\')

Mit
$replace($regexp(%involvedpeople%,'mix:([^;]+)','$1\\'),';','\\')
bekomme ich für

INVOLVEDPEOPLE=producer:Barrett Jones;producer:Foo Fighters;engineer:Steve Culp;mix:Tom Rothrock;mix:Rob Schnapf;

als Ergebnis:

MIXER=producer:Barrett Jones
MIXER=producer:Foo Fighters
MIXER=engineer:Steve Culp
MIXER=Tom Rothrock
MIXER=Rob Schnapf

Vermutlich kann man die überflüssigen Rollen mit dem selben Regex string entfernen, ich hab aber nicht herausgefunden wie, deshalb das zweite regex.
Ansonsten funktioniert es genauso wie gewünscht, und ich kann damit auch mehrere Dateien mit einem Klick formatieren.

Hallo 'seppl', sehr schön, deine Lösung funktioniert, und sie ist eigentlich auch verhältnismäßig einfach.

Darauf hätte ich auch selbst kommen können, bin ich aber nicht, weil ich eine 'hart kodierte' Lösung irgendwie vermeiden wollte, weil ich auch nicht weiß, welche Rollen irgendwie irgendwann vorkommen können.

DD.20140613.1948.CEST

Ich hänge mich mal an den Thread an. Ich habe ein ähnliches Problem, nur umgekehrt.

Ich würde gerne aus einer Liste von Performern mit ihren Rollen:
PERFORMER=Nanette Newman (choir vocals); Madeline Bell (choir vocals); Doris Troy (guest background vocals)

ein Musiciancredits Feld generieren:
Musiciancredits=choir vocals:Nanette Newman;choir vocals:Madeline Bell;guest background vocals:Doris Troy

könnte mir jemand bitte eine $regexp Aktion basteln?

Vielen Dank!

von PERFORMER=

Nanette Newman (choir vocals); Madeline Bell (choir vocals); Doris Troy (guest background vocals)

nach MUSICIANCREDITS=
choir vocals:Nanette Newman;choir vocals:Madeline Bell;guest background vocals:Doris Troy

Aktion "Tag-Feld formatieren" Feld: MUSICIANCREDITS Formatstring: $trimRight($regexp(%PERFORMER%,'(.+?) \((.+?)\)(?:; *)?','$2:$1;'),';') ... oder ... Formatstring: $trimRight($regexp(%PERFORMER%,'(.+?) \((.+?)\)[; ]{0,}','$2:$1;'),';')

DD.20150324.1625.CET

Danke Dir!
Funktioniert perfekt. Hat mir sehr geholfen!