Author Topic: Editing Wma Tags  (Read 116241 times)

Sebastian_Mares

  • Guest
Re:Editing Wma Tags
« Reply #25 on: 25 Jan '04 - 21:13 »
I will contact Gambit via Hydrogenaudio. He hangs around there quite often. :)

Edit: I sent him a private message asking him to check out this thread.
« Last Edit: 25 Jan '04 - 21:17 by Sebastian Mares »

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #26 on: 25 Jan '04 - 22:14 »
Great !  :D

DanaPaul

  • Posts: 335
Re:Editing Wma Tags
« Reply #27 on: 26 Jan '04 - 00:53 »
Except for the WMA implementation, I've already found these units scattered around the Net.  All units are limited in their implementation.  Example, ID3v2 doesn't recognize ID3v4 and it recognizes limited tag name/data types.

Additionally, Ignoring the polination of ID3vX tags with WMA tag names (content type) is futile. Windows Media Player has already contaminated the ID3vX tag pool with it's own reality in accordance with Microsoft.

Thanks for the WMA implementation, I'll use this in my Delphi tag reader/writer class.  BTW, it supports ID3vX, Vorbis Comments, and WMA, all tags, including private, custom, embedded image, 4 text encodings, compressed, encrypted, and binary tags, commercial tag frames, etc.  

A lot of work to be done ;)  Whether using these units available here or rolling your own.

« Last Edit: 26 Jan '04 - 00:54 by DanaPaul »

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #28 on: 26 Jan '04 - 08:49 »
Thanks for the WMA implementation, I'll use this in my Delphi tag reader/writer class.  BTW, it supports ID3vX, Vorbis Comments, and WMA, all tags, including private, custom, embedded image, 4 text encodings, compressed, encrypted, and binary tags, commercial tag frames, etc.

Dana, I'm not sure you can use WMA implementation with ID3vX, you may display the tags properly (bearly) but when it comes to save them, the fields get mismatched. I will play with it more to try and find out where it comes from. The main problem is that there is no " true rules" with ID3vX, some of the software on the market recognize the comments field as "COMM" and some as "Description", the link field can appear under "WM/Url" or "WM/UserWebUrl" which is type of WMT_TYPE_BINARY or under "WXXX". So I came to a conclusion that I'll never be able to satisfy every user - all depands on wich program the file tags were edited in the begining . As far as OGG, WMA can't retreive any of the fields.

DanaPaul

  • Posts: 335
Re:Editing Wma Tags
« Reply #29 on: 26 Jan '04 - 10:15 »
Actually, the world according to Wma isn't cooperative.  Windows Media Player is self centered with its implementation of ID3 tag frames.  To Wit:

FrameName = "PRIV"
ContentType = "WM/MediaClassSecondaryID"
Data = 00h*17 (empty)

FrameName = "PRIV"
ContentType = "WM/MediaClassPrimaryID"
Data = 00h + 16*Byte (binary)

FrameName = "PRIV"
ContentType = "WM/MediaClassPrimaryID"
Data = 00h + 16*Byte (binary)

FrameName = "PRIV"
ContentType = "WM/ContentID"
Data = 00h + 16*Byte (binary)

FrameName = "PRIV"
ContentType = "WM/UniqueFileIdentifier"
Data = Unicode

FrameName = "PRIV"
ContentType = "WM/CollectionID"
Data = 00h + 16*Byte (binary)

FrameName = "PRIV"
ContentType = "WM/CollectionGroupID"
Data = 00h + 16*Byte (binary)

FrameName = "PRIV"
ContentType = "WM/Provider"
Data = Unicode

And anonymous tags...

FrameName = "PRIV"
ContentType = "PeakValue"
Data = (binary)

This does not address (TLEN always = 0) RealJukebox (GEOB = 1674 bytes) and MusicMatch (NCON = as much as 25893 bytes) tags.

Clearly, an end user must process these files within each (jukebox) player application for expected performance even when the ID3 specification includes many of these tags with a well defined data format.

BTW, I would never consider using the WMA MetaData name space with Ogg Comments. Something like that would (pollute) cripple the Vorbis Audio file for an end user that maintains tag data.

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #30 on: 26 Jan '04 - 21:17 »
I may found a bug in Bass_Wma, trying to set tags to Comments / Lyrics with a large text length while encoding using BASS_WMA_EncodeSetTag won't work. The file may be encoded but the respective tags values are not.

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re:Editing Wma Tags
« Reply #31 on: 27 Jan '04 - 11:13 »
Yep, there was a hard-coded tag length limit. An update is now on the BASS page - let me know if you still have trouble with long tags.

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #32 on: 27 Jan '04 - 12:13 »
Ian,

Still can't save long tags, we're talking about 2.0.0.18 version right ?

Chris

  • Posts: 1810
Re:Editing Wma Tags
« Reply #33 on: 27 Jan '04 - 12:19 »
@ Philip I think you have mismatch Bass with Basswma
Ian have  BassWMA updated
Version 2.02
Greets chris

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #34 on: 27 Jan '04 - 12:19 »
Also... It will be nice if each version had a text file describing the change/improvements of the version  ;)

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #35 on: 27 Jan '04 - 12:23 »
Oups... ;D Brain drain - long tags works perfectly.
Thanks Chris

DanaPaul

  • Posts: 335
Re:Editing Wma Tags
« Reply #36 on: 27 Jan '04 - 12:31 »
I came up with a solution for editing Wma tags.

Hey! Sir Philip,

How about pointing me towards a Delphi flavor of the wmvcore header files man...

I would be most grateful.

Dana

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #37 on: 27 Jan '04 - 12:59 »
Lady Dana,

For you - everything  ;)

What do you need ?

Philip

DanaPaul

  • Posts: 335
Re:Editing Wma Tags
« Reply #38 on: 27 Jan '04 - 13:13 »
Lady Dana, ... For you - everything ... What do you need ?

I'm not sure what I need.  I want to be able to enumerate (most) all Wma tags, similar to your MetaData.dll, but without tag pool limitations.  This implementation will be for the Delphi Tag reader/writer class mentioned in previous posts.

Thanks for your time ;)

Dana
(father of 2 boys and proud grandfather of a delightful granddaughter)

Chris

  • Posts: 1810
Re:Editing Wma Tags
« Reply #39 on: 27 Jan '04 - 13:27 »
Lady Dana,

For you - everything  



(father of 2 boys and proud grandfather of a delightful granddaughter)


Ooops hehehehe
« Last Edit: 27 Jan '04 - 13:36 by Chris »

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #40 on: 27 Jan '04 - 15:01 »
(father of 2 boys and proud grandfather of a delightful granddaughter)

Definitely a hard day  :P

Posting the MetaData.Dll sources will help you ? Paul ?
« Last Edit: 27 Jan '04 - 15:03 by Philip Hadar »

Chris

  • Posts: 1810
Re:Editing Wma Tags
« Reply #41 on: 27 Jan '04 - 15:12 »
for me too please.....(if possible)
Greets chris

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #42 on: 27 Jan '04 - 16:36 »
Here's the deal
Enjoy  :)

Code: [Select]
library MetaData;

  { MetaData.Dll (C) 2004 Copyright Philip Hadar }

uses
  ShareMem, SysUtils, Windows, Dialogs;

  {$R *.RES}

  Const
  IID_IWMMetadataEditor: TGUID = '{96406bd9-2b2b-11d3-b36b-00c04f6108ff}';
  IID_IWMHeaderInfo    : TGUID = '{96406bda-2b2b-11d3-b36b-00c04f6108ff}';
  IID_IWMHeaderInfo3   : TGUID = '{15CC68E3-27CC-4ecd-B222-3F5D02D80BD5}';
  IID_IWMHeaderInfo2   : TGUID = '{15cf9781-454e-482e-b393-85fae487a810}';

  LibName = 'WMVCORE.DLL';

  Type
  TTagsData = Packed Record
  Encoder, Version, Genre, Author, Title, Album,
  Composer, Url, Track, Year, CopyRight: String[255];
  Comments, Lyrics: WideString;
  Duration, BitRate, FileSize: LongInt;
  VBR: Boolean;
  End;
  PTagsData = ^TTagsData;

  Type

  WMT_CODEC_INFO_TYPE = LongWord;

  WMT_ATTR_DATATYPE =
  ( WMT_TYPE_DWORD,
    WMT_TYPE_STRING,
    WMT_TYPE_BINARY,
    WMT_TYPE_BOOL,
    WMT_TYPE_QWORD,
    WMT_TYPE_WORD,
    WMT_TYPE_GUID );

  TWMTAttrDataType = WMT_ATTR_DATATYPE;

  Type
  IWMMetadataEditor = interface(IUnknown)
  ['{96406BD9-2B2B-11d3-B36B-00C04F6108FF}']
    Function Open(pwszFilename: PWideChar): HRESULT; stdcall;
    Function Close: HRESULT; stdcall;
    Function Flush: HRESULT; stdcall;
  end;

  Type
  IWMHeaderInfo = interface(IUnknown)
  ['{96406BDA-2B2B-11d3-B36B-00C04F6108FF}']
    Function GetAttributeCount(wStreamNum: Word; out pcAttributes: Word): HRESULT; stdcall;
    Function GetAttributeByIndex(wIndex: Word; var pwStreamNum: Word;
     pwszName: PWideChar; var pcchNameLen: Word;
      out pType: TWMTAttrDataType;pValue: PBYTE;
      var pcbLength: Word): HRESULT; stdcall;
    Function GetAttributeByName(var pwStreamNum: Word; pszName: PWideChar;
      out pType: TWMTAttrDataType;pValue: PBYTE;
      var pcbLength: Word): HRESULT; stdcall;
    Function SetAttribute(wStreamNum: Word; pszName: PWideChar;
      Type_: TWMTAttrDataType; {in} pValue: PBYTE;
      cbLength: Word): HRESULT; stdcall;
    Function GetMarkerCount(out pcMarkers: Word): HRESULT; stdcall;
    Function GetMarker(wIndex: Word;pwszMarkerName: PWideChar;
      var pcchMarkerNameLen: Word; out pcnsMarkerTime: Int64): HRESULT; stdcall;
    Function AddMarker(pwszMarkerName: PWideChar; cnsMarkerTime: Int64): HRESULT; stdcall;
    Function RemoveMarker(wIndex: Word): HRESULT; stdcall;
    Function GetScriptCount(out pcScripts: Word): HRESULT; stdcall;
    Function GetScript(wIndex: Word;pwszType: PWideChar;
      var pcchTypeLen: Word;pwszCommand: PWideChar;
      var pcchCommandLen: Word; out pcnsScriptTime: Int64): HRESULT; stdcall;
    Function AddScript(pwszType, pwszCommand: PWideChar;
      cnsScriptTime: Int64): HRESULT; stdcall;
    Function RemoveScript(wIndex: Word): HRESULT; stdcall;
  end;

  Type
  IWMHeaderInfo2 = interface(IWMHeaderInfo)
  ['{15CF9781-454E-482e-B393-85FAE487A810}']
    Function GetCodecInfoCount(out pcCodecInfos: LongWord): HRESULT; stdcall;
    Function GetCodecInfo(wIndex: LongWord; var pcchName: Word;
     pwszName: PWideChar; var pcchDescription: Word;
     pwszDescription: PWideChar; out pCodecType: WMT_CODEC_INFO_TYPE;
      var pcbCodecInfo: Word;pbCodecInfo: PBYTE): HRESULT; stdcall;
  end;

  Type
  IWMHeaderInfo3 = interface(IWMHeaderInfo2)
  ['{15CC68E3-27CC-4ecd-B222-3F5D02D80BD5}']
    Function GetAttributeCountEx(wStreamNum: Word; out pcAttributes: Word): HRESULT; stdcall;
    Function GetAttributeIndices(wStreamNum: Word; pwszName: PWideChar;
      pwLangIndex: PWORD;pwIndices: PWORD; var pwCount: Word): HRESULT; stdcall;
   Function GetAttributeByIndexEx(wStreamNum: Word; wIndex: Word;pwszName: PWideChar;
     var  pwNameLen: Word; out  pType: TWMTAttrDataType; out  pwLangIndex: Word;
   pValue: PBYTE; var pdwDataLength: LongWord): HRESULT; stdcall;
    Function ModifyAttribute(wStreamNum: Word; wIndex: Word; Type_: TWMTAttrDataType;
      wLangIndex: Word; pValue: PBYTE; dwLength: LongWord): HRESULT; stdcall;
    Function AddAttribute(wStreamNum: Word; pszName: PWideChar;
      out pwIndex: Word; Type_: TWMTAttrDataType; wLangIndex: Word;
      pValue: PBYTE; dwLength: LongWord): HRESULT; stdcall;
    Function DeleteAttribute(wStreamNum, wIndex: Word): HRESULT; stdcall;
    Function AddCodecInfo(pwszName: PWideChar; pwszDescription: PWideChar;
      codecType: WMT_CODEC_INFO_TYPE; cbCodecInfo: Word;
      pbCodecInfo: PBYTE): HRESULT; stdcall;
  end;

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #43 on: 27 Jan '04 - 16:37 »
MetaData Continue

Code: [Select]
 Var
  _WMCreateEditor: Function(out ppEditor: IWMMetadataEditor): HRESULT; stdcall;
  DllHandle: THandle;
  ppEditor: IWMMetadataEditor;
  ppHeaderInfo3: IWMHeaderInfo3;

 
Procedure ResetTagsData(TagsData: PTagsData);
begin

  TagsData.Duration := 0;
  TagsData.BitRate := 0;
  TagsData.FileSize := 0;
  TagsData.Encoder := '';
  TagsData.Version := '';
  TagsData.Genre := '';
  TagsData.Author := '';
  TagsData.Composer := '';
  TagsData.Title := '';
  TagsData.Album := '';
  TagsData.Year := '';
  TagsData.Track := '';
  TagsData.Url := '';
  TagsData.Comments := '';
  TagsData.Lyrics := '';
  TagsData.CopyRight := '';

end;

Function GetAttribIndex(Attrib: String): Integer;
  Var
  AttribName: PWideChar;
  P, Lang: PWord;
  AttribLen: Word;
begin

  Result := -1;

  AttribName := StringToOleStr(Attrib);
  Lang := PWord(0);

  ppHeaderInfo3.GetAttributeIndices($FFFF,AttribName,Lang,Nil,AttribLen);

  if AttribLen <> 0 Then
  Begin
  P := AllocMem(AttribLen);

    Try
    ppHeaderInfo3.GetAttributeIndices($FFFF,AttribName,Lang,P,AttribLen);
    Result := PWord(P)^;
    Finally
    FreeMem(P);
    End;

  End;


End;

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #44 on: 27 Jan '04 - 16:39 »
MetaData Continue

Code: [Select]
Function ShowTags( Var FileName: PWideChar; Var TagsData: PTagsData ): Boolean; stdcall;
  Var
  AttribStream, AttributeCount, AttribLen: Word;
  AttribName: PWideChar;
  pType: TWMTAttrDataType;
  pValue: PByte;
  DataLen: Word;
  I, nSize: Integer;
  HR: HRESULT;
  nVal: Integer;
  P: PInteger;
  Duration: Int64;
begin

  DllHandle := LoadLibrary(LibName);

  if DllHandle = 0 Then
  Begin
  ShowMessage(Format('Could not Load Library ($%x).',[DllHandle]));
  Result := False;
  Exit;
  End
  Else
  _WMCreateEditor := GetProcAddress( DllHandle, 'WMCreateEditor' );

  ResetTagsData(TagsData);

  if Not FileExists(FileName) Then
  Begin
  Raise Exception.Create(Format('The file' + #13#10 +'%S' + #13#10 +'does''nt exists!',[FileName]));
  Exit;
  End;

  Try

    HR := _WMCreateEditor(ppEditor);

    if Failed(HR) Then
    Begin
    Result := False;
    Raise Exception.Create(Format('Could not create Metadata Editor ($%x).',[HR]));
    Exit;
    End;

    ppEditor.Open(FileName);

    HR := ppEditor.QueryInterface( IID_IWMHeaderInfo3, ppHeaderInfo3 );

    if Failed(HR) Then
    Begin
    Result := False;
    Raise Exception.Create(Format('Could not QI for IWMHeaderInfo3 ($%x).',[HR]));
    Exit;
    End;

    Result := True;

    AttribStream := 0;

    ppHeaderInfo3.GetAttributeCount(AttribStream,AttributeCount);

    For I := 0 To AttributeCount -1 Do
    Begin

    ppHeaderInfo3.GetAttributeByIndex(Word(I),AttribStream,Nil,AttribLen,pType,Nil,DataLen);

    nSize := 255;
    AttribName := AllocMem(nSize *2);
    AttribLen := nSize;
    PValue := AllocMem(DataLen);

    ppHeaderInfo3.GetAttributeByIndex(Word(I),AttribStream,PWideChar(AttribName),AttribLen,pType,PByte(PValue),DataLen);

      if pType = WMT_TYPE_STRING Then
      Begin

        if UpperCase(AttribName) = 'WM/ENCODEDBY' Then
        TagsData.Encoder := WideString(PValue);

        if UpperCase(AttribName) = 'WMFSDKVERSION' Then
        TagsData.Version := WideString(PValue);

        if UpperCase(AttribName) = 'WM/GENRE' Then
        TagsData.Genre := WideString(PValue);

        if UpperCase(AttribName) = 'AUTHOR' Then
        TagsData.Author := WideString(PValue);

        if UpperCase(AttribName) = 'TITLE' Then
        TagsData.Title := WideString(PValue);

        if UpperCase(AttribName) = 'WM/ALBUMTITLE' Then
        TagsData.Album := WideString(PValue);

        if UpperCase(AttribName) = 'WM/COMPOSER' Then
        TagsData.Composer := WideString(PValue);

        if UpperCase(AttribName) = 'WM/URL' Then
        TagsData.Url := WideString(PValue);

        if UpperCase(AttribName) = 'WM/YEAR' Then
        TagsData.Year := WideString(PValue);

        if UpperCase(AttribName) = 'WM/TRACKNUMBER' Then
        TagsData.Track := WideString(PValue);

        if UpperCase(AttribName) = 'DESCRIPTION' Then
        Begin
        TagsData.Comments := WideString(PValue);
        End;

        if UpperCase(AttribName) = 'WM/LYRICS' Then
        TagsData.Lyrics := PWideChar(PValue);

        if UpperCase(AttribName) = 'COPYRIGHT' Then
        TagsData.CopyRight := WideString(PValue);

      End;

      if pType = WMT_TYPE_DWORD Then
      Begin
      P := PInteger(PValue);
      nVal := P^;

        if UpperCase(AttribName) = 'BITRATE' Then
        TagsData.BitRate := nVal;

      End;

      if pType = WMT_TYPE_QWORD Then
      Begin
      P := PInteger(PValue);
      nVal := P^;

        if UpperCase(AttribName) = 'FILESIZE' Then
        TagsData.FileSize := nVal;

        if UpperCase(AttribName) = 'DURATION' Then
        Begin
        Duration := nVal Div 10000000;
        TagsData.Duration := Duration;
        End;

      End;

      if pType = WMT_TYPE_BOOL Then
        if UpperCase(AttribName) = 'ISVBR' Then
        Begin
        nVal := pValue^;
        TagsData.VBR := ( nVal <> 0 );
        End;

    FreeMem(AttribName);
    FreeMem(PValue);

    End;

    ppHeaderInfo3 := Nil;

  Finally

  ppEditor.Close;
  ppEditor := Nil;

    if DllHandle <> 0 Then
    Begin
    FreeLibrary(DllHandle);
    _WMCreateEditor := Nil;
    End;

  End;

End;

Philip Hadar

  • Posts: 79
Re:Editing Wma Tags
« Reply #45 on: 27 Jan '04 - 16:40 »
MetaData Last Part

Code: [Select]
Function SaveTags( Var FileName: PWideChar; Var TagsData: PTagsData ): Boolean; stdcall;
  Var
  nIndex, nLength: Integer;
  AttribName, pValue: PWideChar;
  pwIndex: Word;
  HR: HRESULT;
begin

  if Not FileExists(FileName) Then
  Begin
  Raise Exception.Create(Format('The file' + #13#10 +'%S' + #13#10 +'does''nt exists!',[FileName]));
  Exit;
  End;

  DllHandle := LoadLibrary(LibName);

  if DllHandle = 0 Then
  Begin
  ShowMessage(Format('Could not Load Library ($%x).',[DllHandle]));
  Result := False;
  Exit;
  End
  Else
  _WMCreateEditor := GetProcAddress(DllHandle, 'WMCreateEditor');

  Result := True;

  HR := _WMCreateEditor(ppEditor);

  if Failed(HR) Then
  Begin
  Raise Exception.Create(Format('Could not create Metadata Editor ($%x).',[HR]));
  Exit;
  End;

  HR := ppEditor.QueryInterface(IID_IWMHeaderInfo3,ppHeaderInfo3);

  if Failed(HR) Then
  Begin
  Raise Exception.Create(Format('Could not QI for IWMHeaderInfo3 ($%x).',[HR]));
  Exit;
  End;

  ppEditor.Open(FileName);

  Try

    AttribName := 'WM/EncodedBy';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Encoder);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Encoder <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/Genre';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Genre);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Genre <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'Author';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Author);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Author <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/Composer';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Composer);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Composer <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);

    AttribName := 'Title';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Title);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Title <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/AlbumTitle';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Album);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Album <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/Year';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Year);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Year <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/TrackNumber';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Track);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Track <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/URL';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Url);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Url <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'Copyright';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Copyright);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Copyright <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'Description';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Comments);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Comments <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);


    AttribName := 'WM/Lyrics';
    nIndex := GetAttribIndex(AttribName);
    pValue := StringToOleStr(TagsData.Lyrics);
    nLength := Length(pValue) * 2;
    if nIndex >= 0 Then
    Begin

      if TagsData.Lyrics <> '' Then
      ppHeaderInfo3.ModifyAttribute(0,nIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength)
      Else
      ppHeaderInfo3.DeleteAttribute(0,nIndex);

    End
    Else if nlength <> 0 Then
    ppHeaderInfo3.AddAttribute(0,AttribName,pwIndex,WMT_TYPE_STRING,0,PByte(pValue),nLength);

    ppEditor.Flush;

  Finally

  ppHeaderInfo3 := Nil;

  ppEditor.Close;
  ppEditor := Nil;

    if DllHandle <> 0 Then
    Begin
    FreeLibrary(DllHandle);
    _WMCreateEditor := Nil;
    End;

  End;

End;


  Exports
  ShowTags, SaveTags;

begin


end.

DanaPaul

  • Posts: 335
Re:Editing Wma Tags
« Reply #46 on: 27 Jan '04 - 17:15 »
Much Gracias...

Back to work ;)

Dana

MrTDelphi

  • Posts: 111
Re:Editing Wma Tags
« Reply #47 on: 30 Jan '04 - 10:53 »
Hi Philip

I just want to share about field,
how if add some field at (wma, ogg, mp3).pas my at wav... ;) like
Cue,  Intro,  BPM, , Startsilence, Endsilence, starttime, Endtime, custome1, custome2...ect
i thinks at a "DJ" radio/mix/studio it can using for more info....

what about this do you ..interested... ;)


regards.

Luq

Chris

  • Posts: 1810
Re:Editing Wma Tags
« Reply #48 on: 30 Jan '04 - 12:30 »
Cue,  Intro,  BPM, , Startsilence, Endsilence, starttime, Endtime, custome1, custome2...ect


mmm  possible is all
but I don`t think that that is an good Idea

Example......you put this Fields in the Mp3Tagv2
whats happend  if the User Remove the Tag ??
then all your adjustment is away
or whats happend if the File is an WavFile ???

---- I`m self Developing a Big DJ  Application----

I think a Better way is  to use a better Listbox  with Columns and a procedure / function to access every Column seperatly
(Best for me  LMDListbox)

Greets chris
« Last Edit: 30 Jan '04 - 14:05 by Chris »

DanaPaul

  • Posts: 335
Re:Editing Wma Tags
« Reply #49 on: 30 Jan '04 - 13:46 »
but I don`t think that that is an good Idea

I think both ideas (implementations) have merit.  Therefore I think a better way is to leave the decision to the end user.

Example, an option to "share" this information via meta tags/comments and/or an option to save this information in a database.

IMHO, either implementation would work well if this implementation also considered read only media storage for these audio files (CDA, NET) and designed its implementation around relative values rather than arbitrary custom settings, eh? ;)
« Last Edit: 30 Jan '04 - 13:50 by DanaPaul »