将 MP3 文件加载到 ListView 中。选择多个项目时,显示 <Multi>,即使显示 <multi>,也需要能够保存到每个文件

问题描述 投票:0回答:1
在这个项目中,我们使用该组件打开 MP3 文件。


3delite.hu =- ID3v2 库

文件加载到 ListView 后,单击每个文件即可在左侧的“编辑”字段中查看其信息,以及顶部的目录路径。

您可以编辑每个文件并通过单击[保存]按钮保存它。

现在,这就是我需要完成的事情。

当您选择在某些字段中具有相同信息的多个项目时(或者)如果您有

<multi>

,我希望能够[保存]对其各个文件所做的任何更改。

我想我需要获取文件的位置,每个文件的[thePath],并以某种方式将其包含在保存中。

已更新

我添加了一个带有两个

按钮备忘录

第一个按钮将加载逗号分隔列表中的所有选定路径。这应该会让循环变得更容易,并希望能够更新所有单独的文件(也许,希望如此)。

第二个按钮只是为了清除备忘录。

这是代码:

加载它.pas

unit LoadIt; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, ComCtrls, StdCtrls, ID3v1Library, ID3v2Library, UITypes, StrUtils; type TForm1 = class(TForm) SidePanel: TPanel; MainPanel: TPanel; ListView1: TListView; OpenDialog1: TOpenDialog; strTitle: TEdit; strArtist: TEdit; Label1: TLabel; Label2: TLabel; strAlbum: TEdit; Label3: TLabel; strTrack: TEdit; Label5: TLabel; TopPanel: TPanel; Button8: TButton; Edit1: TEdit; Label4: TLabel; strPath: TEdit; saveButton: TButton; Memo1: TMemo; SelectedLabel: TLabel; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button8Click(Sender: TObject); procedure ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); procedure saveButtonClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; ID3v1Tag: TID3v1Tag = nil; ID3v2Tag: TID3v2Tag = nil; CurrentAPICIndex: Integer = - 1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Column: TListColumn; begin TopPanel.Align := alTop; SidePanel.Align := alLeft; MainPanel.Align := alClient; ListView1.Align := alClient; ID3v1Tag := TID3v1Tag.Create; ID3v2Tag := TID3v2Tag.Create; Column := ListView1.Columns.Add; Column.Caption := 'Track ID'; Column.Alignment := taLeftJustify; Column.Width := 60; Column := ListView1.Columns.Add; Column.Caption := 'Artist'; Column.Alignment := taLeftJustify; Column.Width := 200; Column := ListView1.Columns.Add; Column.Caption := 'Album'; Column.Alignment := taLeftJustify; Column.Width := 200; Column := ListView1.Columns.Add; Column.Caption := 'Title'; Column.Alignment := taLeftJustify; Column.Width := 200; Column := ListView1.Columns.Add; Column.Caption := 'File ALocation'; Column.Alignment := taLeftJustify; Column.Width := 0; end; procedure AddFileToTree(ListView: TListView; FileName: String); var SR: TSearchRec; ListItem: TListItem; begin // FileSize := 0; if (FindFirst(FileName, faAnyFile, SR) = 0) then begin // FileSize := SR.Size; // FileDate := FileDateToDateTime(SR.Time); ListItem := ListView.Items.Add; // get the MP3 File name // Track Number ListItem.Caption := ID3v2Tag.GetUnicodeText('TRCK'); //0 // get the Artist ListItem.SubItems.Add(ID3v2Tag.GetUnicodeText('TPE1')); // 1 // get the Album ListItem.SubItems.Add(ID3v2Tag.GetUnicodeText('TALB')); // 2 // get the Song title ListItem.SubItems.Add(ID3v2Tag.GetUnicodeText('TIT2')); // 3 // get the path to the MP3 file ListItem.SubItems.Add(FileName); // 4 // First we get the MP3 File name ListItem.SubItems.Add(extractfilename(FileName)); //5 end; end; // This section was coded by: Remy Lebeau // https://stackoverflow.com/a/78172902/2031172 procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); var ls: TListItem; sTrack, sArtist, sSong, sAlbum, sPath: string; procedure CheckForMulti(var selectedStr: string; const value: string); begin if selectedStr = '' then selectedStr := value else if selectedStr <> value then selectedStr := '<multi>'; end; begin ls := ListView1.Selected; while Assigned(ls) do begin CheckForMulti(sTrack, ls.Caption); CheckForMulti(sArtist, ls.SubItems[0]); CheckForMulti(sSong, ls.SubItems[1]); CheckForMulti(sAlbum, ls.SubItems[2]); CheckForMulti(sPath, ls.SubItems[3]); ls := ListView1.GetNextItem(ls, sdAll, [isSelected]); end; strTrack.Text := sTrack; strArtist.Text := sArtist; strTitle.Text := sSong; strAlbum.Text := sAlbum; strPath.Text := sPath; end; procedure TForm1.saveButtonClick(Sender: TObject); var ErrorCode, i: Integer; LanguageID: TLanguageID; FileName : string; ListItem: TListItem; getString : string; LoadIt : integer; begin if ID3v2Tag.MajorVersion = 2 then begin if MessageDlg('The tag in the file is an ID3v2.2 tag, if you click ''Yes'' it will be saved as an ID3v2.3 or ID3v2.4 tag. Do you want to save the tag?', mtConfirmation, [mbYes, mbCancel], 0) <> mrYes then begin Exit; end; end; ID3v2Tag.SetUnicodeText('TPE1', strArtist.Text); ID3v2Tag.SetUnicodeText('TALB', strAlbum.Text); ID3v2Tag.SetUnicodeText('TIT2', strTitle.Text); ID3v2Tag.SetUnicodeText('TRCK', strTrack.Text); ErrorCode := ID3v2Tag.SaveToFile(strPath.text); // ErrorCode := ID3v2Tag.SaveToFile(strPath.Text{$IFDEF DEBUG}, False{$ENDIF}); if ErrorCode <> ID3V2LIBRARY_SUCCESS then begin MessageDlg('Error saving ID3v2 tag, error code: ' + IntToStr(ErrorCode) + #13#10 + ID3v2TagErrorCode2String(ErrorCode), mtError, [mbOk], 0); end; end; procedure TForm1.Button1Click(Sender: TObject); var Item: TListItem; test: System.String; begin memo1.Lines.Clear; Item := ListView1.Selected; while Item <> nil do begin // From Remy Lebeau - https://stackoverflow.com/a/14189378/2031172 Memo1.SelStart := Memo1.GetTextLen; Memo1.SelLength := 0; //memo1.lines.Add(Item.SubItems[3]); // Added in this to created a comma delemited list. // This should make it easier to iterate through. Memo1.SelText := Item.SubItems[3] + ','; Item := ListView1.GetNextItem(Item, sdAll, [isSelected]); end; // Remove the last character (comma) in the string. // Mike Jablonski - https://stackoverflow.com/a/29102436/2031172 test := Memo1.Text; test := Copy(test,1,length(test)-1); Memo1.Text := test; end; procedure TForm1.Button2Click(Sender: TObject); begin Memo1.Clear; end; procedure TForm1.Button8Click(Sender: TObject); var i: integer; LoadIt: integer; begin ListView1.Clear; if OpenDialog1.execute then for i := 0 to OpenDialog1.Files.Count - 1 do if SameText(ExtractFileExt(OpenDialog1.Files[i]), '.mp3') then begin // Bug fix here. Changing from the original TEdit to the OpenDialog.Files[i] fixed song titles in list. LoadIt := ID3v2Tag.LoadFromFile(OpenDialog1.Files[i]); AddFileToTree(ListView1, OpenDialog1.Files[i]); end; end; end.
加载它.dfm

object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 375 ClientWidth = 688 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OnCreate = FormCreate TextHeight = 13 object SidePanel: TPanel Left = -4 Top = 128 Width = 189 Height = 252 TabOrder = 0 object Label1: TLabel Left = 4 Top = 40 Width = 38 Height = 19 Caption = 'Artist' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False end object Label2: TLabel Left = 4 Top = 95 Width = 31 Height = 19 Caption = 'Title' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False end object Label3: TLabel Left = 4 Top = 68 Width = 47 Height = 19 Caption = 'Album' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False end object Label5: TLabel Left = 4 Top = 120 Width = 56 Height = 19 Caption = 'Track #' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False end object strTitle: TEdit Left = 61 Top = 93 Width = 121 Height = 21 TabOrder = 0 Text = 'Song Title' end object strArtist: TEdit Left = 61 Top = 39 Width = 121 Height = 21 TabOrder = 1 Text = 'Artist Name' end object strAlbum: TEdit Left = 61 Top = 66 Width = 121 Height = 21 TabOrder = 2 Text = 'Artist Name' end object strTrack: TEdit Left = 61 Top = 120 Width = 121 Height = 21 TabOrder = 3 Text = 'Artist Name' end object saveButton: TButton Left = 21 Top = 156 Width = 59 Height = 22 Caption = 'Save...' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False TabOrder = 4 OnClick = saveButtonClick end end object MainPanel: TPanel Left = 200 Top = 130 Width = 441 Height = 201 TabOrder = 1 object ListView1: TListView Left = 104 Top = 27 Width = 200 Height = 150 Columns = <> MultiSelect = True RowSelect = True SortType = stText TabOrder = 0 ViewStyle = vsReport OnSelectItem = ListView1SelectItem end end object TopPanel: TPanel Left = 8 Top = 8 Width = 649 Height = 114 TabOrder = 2 object Label4: TLabel Left = 352 Top = 15 Width = 31 Height = 19 Caption = 'Path' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False end object SelectedLabel: TLabel Left = 81 Top = 45 Width = 89 Height = 13 Caption = 'All Selected Paths.' end object Button8: TButton Left = 9 Top = 12 Width = 59 Height = 22 Caption = 'Select...' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False TabOrder = 0 OnClick = Button8Click end object Edit1: TEdit Left = 74 Top = 13 Width = 265 Height = 21 Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] ParentFont = False TabOrder = 1 end object strPath: TEdit Left = 389 Top = 12 Width = 244 Height = 21 TabOrder = 2 Text = 'strPath' end object Memo1: TMemo Left = 74 Top = 64 Width = 505 Height = 41 ScrollBars = ssVertical TabOrder = 3 end object Button1: TButton Left = 192 Top = 40 Width = 91 Height = 25 Caption = 'Get All Selected' TabOrder = 4 OnClick = Button1Click end object Button2: TButton Left = 308 Top = 40 Width = 75 Height = 25 Caption = 'Clear Paths' TabOrder = 5 OnClick = Button2Click end end object OpenDialog1: TOpenDialog Filter = 'MP3|*.mp3' Options = [ofHideReadOnly, ofAllowMultiSelect, ofEnableSizing] Left = 598 Top = 324 end end
项目1.dpr

program Project1; uses Forms, LoadIt in 'LoadIt.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end.
    
delphi pascal
1个回答
0
投票
对于您正在尝试的操作,您可能需要跟踪所做的更改(即查看

TEdit.Modified

 属性),然后循环遍历所选项目,根据需要将这些更改保存到每个单独的文件中。

此外,

AddFileToTree()

 正在泄漏 
TSearchRec
 资源,因为它没有调用 
FindClose()
。但是,由于您实际上并没有使用 
TSearchRec
 来做任何有用的事情,所以您应该只使用 
FileExists()
 来代替。

尝试这样的事情:

unit LoadIt; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, ComCtrls, StdCtrls, ID3v1Library, ID3v2Library, UITypes, StrUtils; type TForm1 = class(TForm) SidePanel: TPanel; MainPanel: TPanel; ListView1: TListView; OpenDialog1: TOpenDialog; strTitle: TEdit; strArtist: TEdit; Label1: TLabel; Label2: TLabel; strAlbum: TEdit; Label3: TLabel; strTrack: TEdit; Label5: TLabel; TopPanel: TPanel; Button8: TButton; Edit1: TEdit; Label4: TLabel; strPath: TEdit; saveButton: TButton; Memo1: TMemo; SelectedLabel: TLabel; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button8Click(Sender: TObject); procedure ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); procedure saveButtonClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; ID3v1Tag: TID3v1Tag = nil; ID3v2Tag: TID3v2Tag = nil; CurrentAPICIndex: Integer = - 1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Column: TListColumn; begin TopPanel.Align := alTop; SidePanel.Align := alLeft; MainPanel.Align := alClient; ListView1.Align := alClient; ID3v1Tag := TID3v1Tag.Create; ID3v2Tag := TID3v2Tag.Create; Column := ListView1.Columns.Add; Column.Caption := 'Track ID'; Column.Alignment := taLeftJustify; Column.Width := 60; Column := ListView1.Columns.Add; Column.Caption := 'Artist'; Column.Alignment := taLeftJustify; Column.Width := 200; Column := ListView1.Columns.Add; Column.Caption := 'Album'; Column.Alignment := taLeftJustify; Column.Width := 200; Column := ListView1.Columns.Add; Column.Caption := 'Title'; Column.Alignment := taLeftJustify; Column.Width := 200; Column := ListView1.Columns.Add; Column.Caption := 'File Allocation'; Column.Alignment := taLeftJustify; Column.Width := 0; end; procedure AddFileToTree(ListView: TListView; FileName: String); var ErrorCode: integer; ListItem: TListItem; begin ErrorCode := ID3v2Tag.LoadFromFile(FileName); if ErrorCode <> ID3V2LIBRARY_SUCCESS then begin MessageDlg('Error loading ID3v2 tag from file: ' + FileName + #13#10 + 'Error code: ' + IntToStr(ErrorCode) + #13#10 + ID3v2TagErrorCode2String(ErrorCode), mtError, [mbOk], 0); Exit; end; ListItem := ListView.Items.Add; // get the MP3 File name // Track Number ListItem.Caption := ID3v2Tag.GetUnicodeText('TRCK'); //0 // get the Artist ListItem.SubItems.Add(ID3v2Tag.GetUnicodeText('TPE1')); // 1 // get the Album ListItem.SubItems.Add(ID3v2Tag.GetUnicodeText('TALB')); // 2 // get the Song title ListItem.SubItems.Add(ID3v2Tag.GetUnicodeText('TIT2')); // 3 // get the path to the MP3 file ListItem.SubItems.Add(FileName);// 4 // First we get the MP3 File name ListItem.SubItems.Add(ExtractFileName(FileName)); //5 end; procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); var ListItem: TListItem; sTrack, sArtist, sSong, sAlbum, sPath: string; procedure CheckForMulti(var selectedStr: string; const value: string); begin if selectedStr = '' then selectedStr := value else if selectedStr <> value then selectedStr := '<multi>'; end; begin ListItem := ListView1.Selected; while ListItem <> nil do begin CheckForMulti(sTrack, ListItem.Caption); CheckForMulti(sArtist, ListItem.SubItems[0]); CheckForMulti(sSong, ListItem.SubItems[1]); CheckForMulti(sAlbum, ListItem.SubItems[2]); CheckForMulti(sPath, ListItem.SubItems[3]); ListItem := ListView1.GetNextItem(ListItem, sdAll, [isSelected]); end; if not strTrack.Modified then begin strTrack.Text := sTrack; strTrack.Modified := False; end; if not strArtist.Modified then begin strArtist.Text := sArtist; strArtist.Modified := False; end; if not strTitle.Modified then begin strTitle.Text := sSong; strTitle.Modified := False; end; if not strAlbum.Modified then begin strAlbum.Text := sAlbum; strAlbum.Modified := False; end; strPath.Text := sPath; end; procedure TForm1.saveButtonClick(Sender: TObject); var FileName : string; ListItem: TListItem; ErrorCode: Integer; begin if (not strTrack.Modified) and (not strArtist.Modified) and (not strTitle.Modified) and (not strAlbum.Modified) then begin MessageDlg('No changes to save', mtInformation, [mbOk], 0); Exit; end; if ID3v2Tag.MajorVersion = 2 then begin if MessageDlg('The tag in the file is an ID3v2.2 tag, if you click ''Yes'' it will be saved as an ID3v2.3 or ID3v2.4 tag. Do you want to save the tag?', mtConfirmation, [mbYes, mbCancel], 0) <> mrYes then begin Exit; end; end; ListItem := ListView1.Selected; while ListItem <> nil do begin if strTrack.Modified then sTrack := strTrack.Text else sTrack := ListItem.Caption; if strArtist.Modified then sArtist := strArtist.Text else sArtist := ListItem.SubItems[0]; if strTitle.Modified then sSong := strTitle.Text else sSong := ListItem.SubItems[1]; if strAlbum.Modified then sAlbum := strAlbum.Text else sAlbum := ListItem.SubItems[2]; ID3v2Tag.SetUnicodeText('TPE1', sArtist); ID3v2Tag.SetUnicodeText('TALB', sAlbum); ID3v2Tag.SetUnicodeText('TIT2', sSong); ID3v2Tag.SetUnicodeText('TRCK', sTrack); FileName := ListItem.SubItems[3]; ErrorCode := ID3v2Tag.SaveToFile(FileName); // ErrorCode := ID3v2Tag.SaveToFile(FileName{$IFDEF DEBUG}, False{$ENDIF}); if ErrorCode <> ID3V2LIBRARY_SUCCESS then begin MessageDlg('Error saving ID3v2 tag, error code: ' + IntToStr(ErrorCode) + #13#10 + ID3v2TagErrorCode2String(ErrorCode), mtError, [mbOk], 0); end; ListItem := ListView1.GetNextItem(ListItem, sdAll, [isSelected]); end; strTrack.Modified := False; strArtist.Modified := False; strTitle.Modified := False; strAlbum.Modified := False; end; procedure TForm1.Button1Click(Sender: TObject); var ListItem: TListItem; test: String; begin test := ''; ListItem := ListView1.Selected; if ListItem <> nil then begin do test := test + ListItem.SubItems[3] + ','; ListItem := ListView1.GetNextItem(ListItem, sdAll, [isSelected]); until ListItem = nil; // Remove the last character (comma) in the string. SetLength(test, Length(test)-1); end; Memo1.Text := test; { alternatively: SL := TStringList.Create; try ListItem := ListView1.Selected; while ListItem <> nil do begin SL.Add(ListItem.SubItems[3]); ListItem := ListView1.GetNextItem(ListItem, sdAll, [isSelected]); end; Memo1.Text := SL.CommaText; finally SL.Free; end; } end; procedure TForm1.Button2Click(Sender: TObject); begin Memo1.Clear; end; procedure TForm1.Button8Click(Sender: TObject); var i: integer; FileName: string; begin ListView1.Clear; if OpenDialog1.Execute then begin for i := 0 to OpenDialog1.Files.Count - 1 do begin FileName := OpenDialog1.Files[i]; if SameText(ExtractFileExt(FileName), '.mp3') then AddFileToTree(ListView1, FileName); end; end; end; end.
    
© www.soinside.com 2019 - 2024. All rights reserved.