delete lyric is working in tag editor

This commit is contained in:
tramhao 2021-03-05 12:55:12 +08:00
parent 391f33a956
commit 727f2d5a7a
5 changed files with 210 additions and 93 deletions

View File

@ -166,7 +166,7 @@ func cleanLRC(s string) (cleanLyric string) {
return cleanLyric return cleanLyric
} }
// AsLRC renders the sub in .srt format // AsLRC renders the sub in .lrc format
func (lyric Lyric) AsLRC() (res string) { func (lyric Lyric) AsLRC() (res string) {
if lyric.Offset != 0 { if lyric.Offset != 0 {
@ -181,7 +181,7 @@ func (lyric Lyric) AsLRC() (res string) {
return return
} }
// AsLRC renders the caption as srt // AsLRC renders the caption as lrc
func (cap Caption) AsLRC() string { func (cap Caption) AsLRC() string {
// res := fmt.Sprintf("%d", cap.Caption.Seq) + eol + // res := fmt.Sprintf("%d", cap.Caption.Seq) + eol +
// TimeLRC(cap.Caption.Start) + " --> " + TimeLRC(cap.Caption.End) + eol // TimeLRC(cap.Caption.Start) + " --> " + TimeLRC(cap.Caption.End) + eol

View File

@ -228,7 +228,7 @@ func (p *PlayingBar) switchLyrics() {
func (p *PlayingBar) delayLyric(lyricDelay int) (err error) { func (p *PlayingBar) delayLyric(lyricDelay int) (err error) {
p.subtitle.Offset += (time.Duration)(lyricDelay) * time.Millisecond p.subtitle.Offset += (time.Duration)(lyricDelay) * time.Millisecond
err = embedLyric(gomu.player.GetCurrentSong().Path(), p.subtitle.AsLRC(), p.langLyricCurrentPlaying) err = embedLyric(gomu.player.GetCurrentSong().Path(), p.subtitle.AsLRC(), p.langLyricCurrentPlaying, false)
if err != nil { if err != nil {
return tracerr.Wrap(err) return tracerr.Wrap(err)
} }

View File

@ -629,7 +629,7 @@ func ytdl(url string, selPlaylist *tview.TreeNode) error {
} }
lyricContent := string(byteContent) lyricContent := string(byteContent)
err = embedLyric(audioPath, lyricContent, langExt) err = embedLyric(audioPath, lyricContent, langExt, false)
if err != nil { if err != nil {
return tracerr.Wrap(err) return tracerr.Wrap(err)
} }

278
popup.go
View File

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"regexp" "regexp"
"sort"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -841,7 +842,7 @@ func ytSearchPopup() {
func tagPopup(node *AudioFile) (err error) { func tagPopup(node *AudioFile) (err error) {
popupLyricMap := make(map[string]*lyric.Lyric) popupLyricMap := make(map[string]string)
popupID := "tag-input-popup" popupID := "tag-input-popup"
var tag *id3v2.Tag var tag *id3v2.Tag
@ -861,115 +862,209 @@ func tagPopup(node *AudioFile) (err error) {
if !ok { if !ok {
die(errors.New("USLT error")) die(errors.New("USLT error"))
} }
res, err := lyric.NewFromLRC(uslf.Lyrics) res := uslf.Lyrics
if err != nil { popupLyricMap[uslf.ContentDescriptor] = res
return tracerr.Wrap(err)
}
popupLyricMap[uslf.ContentDescriptor] = &res
} }
var options []string var options []string
for option := range popupLyricMap { for option := range popupLyricMap {
options = append(options, option) options = append(options, option)
} }
sort.Strings(options)
// var lyricText string = "abcdefg" var (
// _, optionSelected := lyricDropdown.GetCurrentOption() artistInputField *tview.InputField = tview.NewInputField()
// // for _, v := range popupLyricMap[optionSelected].Captions.Text { titleInputField *tview.InputField = tview.NewInputField()
// lyricText += v albumInputField *tview.InputField = tview.NewInputField()
// } getTagButton *tview.Button = tview.NewButton("Get Tag")
lyricTextView := tview.NewTextView() saveTagButton *tview.Button = tview.NewButton("Save Tag")
lyricDropDown *tview.DropDown = tview.NewDropDown()
lyricTextView.SetBackgroundColor(gomu.colors.background). deleteLyricButton *tview.Button = tview.NewButton("Delete Lyric")
getLyric1Button *tview.Button = tview.NewButton("Get Lyric 1")
getLyric2Button *tview.Button = tview.NewButton("Get Lyric 2")
getLyric3Button *tview.Button = tview.NewButton("Get Lyric 3")
lyricTextView *tview.TextView
leftGrid *tview.Grid = tview.NewGrid()
rightFlex *tview.Flex = tview.NewFlex()
)
artistInputField.SetLabel("Artist: ").
SetFieldWidth(20).
SetText(tag.Artist()).
SetFieldBackgroundColor(gomu.colors.popup).
SetBackgroundColor(gomu.colors.background)
titleInputField.SetLabel("Title: ").
SetFieldWidth(20).
SetText(tag.Title()).
SetFieldBackgroundColor(gomu.colors.popup).
SetBackgroundColor(gomu.colors.background)
albumInputField.SetLabel("Album: ").
SetFieldWidth(20).
SetText(tag.Album()).
SetFieldBackgroundColor(gomu.colors.popup).
SetBackgroundColor(gomu.colors.background)
getTagButton.SetBorder(true).
SetBackgroundColor(gomu.colors.background).
SetTitleColor(gomu.colors.accent)
saveTagButton.SetSelectedFunc(func() {
tag, err = id3v2.Open(node.path, id3v2.Options{Parse: true})
if err != nil {
errorPopup(err)
}
defer tag.Close()
tag.SetArtist(artistInputField.GetText())
tag.SetTitle(titleInputField.GetText())
tag.SetAlbum(albumInputField.GetText())
err := tag.Save()
if err != nil {
errorPopup(err)
} else {
defaultTimedPopup(" Success ", "Tag update successfully")
}
}).
SetBorder(true). SetBorder(true).
SetTitle("lyric") SetBackgroundColor(gomu.colors.background).
widgets := make(map[string]tview.Primitive) SetTitleColor(gomu.colors.foreground)
// widgets["widgetA"] = tview.NewXXX()
// widgets["widgetA"].(XXX).Foo()
_ = widgets
getTagButton := tview.NewButton("Get Tag") deleteLyricButton.SetSelectedFunc(func() {
_, langExt := lyricDropDown.GetCurrentOption()
if len(options) > 0 {
err := embedLyric(node.path, "", langExt, true)
if err != nil {
errorPopup(err)
}
// Reset dropdown options
var newOptions []string
for _, v := range options {
if v == langExt {
continue
}
newOptions = append(newOptions, v)
}
lyricDropDown.SetOptions(newOptions, nil).
SetCurrentOption(0)
// Reset lyricpreview
if len(newOptions) > 0 {
_, langExt = lyricDropDown.GetCurrentOption()
lyricTextView.SetText(popupLyricMap[langExt]).
SetTitle(" " + langExt + " lyric preview ")
} else {
langExt = ""
lyricTextView.SetText("No lyric embeded.").
SetTitle(" " + langExt + " lyric preview ")
}
infoPopup(langExt + " lyric deleted successfully.")
} else {
infoPopup("No lyric embeded.")
}
}).
SetBorder(true).
SetBackgroundColor(gomu.colors.background).
SetTitleColor(gomu.colors.accent)
form := tview.NewForm(). getLyric1Button.SetBorder(true).
AddInputField("Artist: ", tag.Artist(), 20, nil, nil). SetBackgroundColor(gomu.colors.background).
AddInputField("Title: ", tag.Title(), 20, nil, nil). SetTitleColor(gomu.colors.accent)
AddInputField("Album: ", tag.Album(), 20, nil, nil). getLyric2Button.SetBorder(true).
AddFormItem(getTagButton) SetBackgroundColor(gomu.colors.background).
// AddButton("Get Tag", nil) SetTitleColor(gomu.colors.accent)
getLyric3Button.SetBorder(true).
SetBackgroundColor(gomu.colors.background).
SetTitleColor(gomu.colors.accent)
lyricDropDown.SetOptions(options, nil).
SetCurrentOption(0).
SetFieldBackgroundColor(gomu.colors.background).
SetFieldTextColor(gomu.colors.accent).
SetPrefixTextColor(gomu.colors.accent).
SetSelectedFunc(func(text string, _ int) {
lyricTextView.SetText(popupLyricMap[text]).
SetTitle(" " + text + " lyric preview ")
}).
SetLabel("Embeded Lyrics: ")
lyricDropDown.SetBackgroundColor(gomu.colors.popup)
form.SetFieldBackgroundColor(gomu.colors.popup). var lyricText string
_, langExt := lyricDropDown.GetCurrentOption()
lyricText = popupLyricMap[langExt]
if lyricText == "" {
lyricText = "No lyric embeded."
langExt = ""
}
lyricTextView = tview.NewTextView()
lyricTextView.
SetDynamicColors(true).
SetRegions(true).
SetScrollable(true).
SetTitle(" " + langExt + " lyric preview ").
SetBorder(true)
lyricTextView.SetText(lyricText).
SetScrollable(true).
SetWordWrap(true).
SetWrap(true).
SetBackgroundColor(gomu.colors.popup). SetBackgroundColor(gomu.colors.popup).
SetBorder(true)
leftGrid.SetRows(3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3).
SetColumns(30).
AddItem(artistInputField, 0, 0, 1, 3, 1, 10, true).
AddItem(titleInputField, 1, 0, 1, 3, 1, 10, true).
AddItem(albumInputField, 2, 0, 1, 3, 1, 10, true).
AddItem(getTagButton, 3, 0, 1, 3, 1, 10, true).
AddItem(saveTagButton, 4, 0, 1, 3, 1, 10, true).
AddItem(lyricDropDown, 6, 0, 1, 3, 1, 10, true).
AddItem(deleteLyricButton, 7, 0, 1, 3, 1, 10, true).
AddItem(getLyric1Button, 8, 0, 1, 3, 1, 10, true).
AddItem(getLyric2Button, 9, 0, 1, 3, 1, 10, true).
AddItem(getLyric3Button, 10, 0, 1, 3, 1, 10, true)
leftGrid.SetBorder(true).
SetTitle(node.name). SetTitle(node.name).
SetBorder(true). SetBorderPadding(1, 1, 2, 2)
SetBorderPadding(1, 0, 2, 2)
form2 := tview.NewForm().
AddDropDown("Lyrics Available: ", options, 0, nil).
AddButton("Delete Lyric", nil).
AddButton("Get Lyric2", nil).
AddButton("Get Lyric3", nil)
form2.SetFieldBackgroundColor(gomu.colors.popup). rightFlex.SetDirection(tview.FlexColumn).
SetBackgroundColor(gomu.colors.popup). AddItem(lyricTextView, 0, 1, true)
SetTitle("Lyric").
SetBorder(true).
SetBorderPadding(1, 0, 2, 2)
lyricFlex := tview.NewFlex().SetDirection(tview.FlexColumn). lyricFlex := tview.NewFlex().SetDirection(tview.FlexColumn).
AddItem(form, 40, 0, true). AddItem(leftGrid, 0, 2, true).
AddItem(tview.NewFlex().SetDirection(tview.FlexRow). AddItem(rightFlex, 0, 3, true)
AddItem(form2, 10, 0, true).
AddItem(lyricTextView, 0, 2, true), 0, 2, true)
// AddItem(artistInput, 0, 3, true).
// AddItem(lyricTextView, 0, 3, true), 0, 3, true)
lyricFlex. lyricFlex.
SetTitle(node.name).
SetBorderPadding(1, 1, 2, 2).
SetBackgroundColor(gomu.colors.popup) SetBackgroundColor(gomu.colors.popup)
// gettagbutton := form.getformitembylabel("get tag") inputs := []tview.Primitive{
artistInputField,
// gettagbutton.setinputcapture(func(e *tcell.eventkey) *tcell.eventkey { titleInputField,
// switch e.key() { albumInputField,
// case tcell.keytab: getTagButton,
// gomu.app.setfocus(form2) saveTagButton,
// } lyricDropDown,
deleteLyricButton,
// return e getLyric1Button,
// }) getLyric2Button,
getLyric3Button,
lyricTextView,
}
gomu.pages. gomu.pages.
AddPage(popupID, center(lyricFlex, 120, 40), true, true) AddPage(popupID, center(lyricFlex, 90, 40), true, true)
gomu.popups.push(lyricFlex) gomu.popups.push(lyricFlex)
form.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey { lyricFlex.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
switch e.Key() { switch e.Key() {
case tcell.KeyEnter: case tcell.KeyEnter:
tag, err = id3v2.Open(node.path, id3v2.Options{Parse: true}) if deleteLyricButton.HasFocus() {
if err != nil { return e
errorPopup(err) } else if saveTagButton.HasFocus() {
}
tagArtist := form.GetFormItemByLabel("Artist").(*tview.InputField).GetText()
tagTitle := form.GetFormItemByLabel("Title").(*tview.InputField).GetText()
tag.SetArtist(tagArtist)
tag.SetTitle(tagTitle)
tag.SetAlbum(form.GetFormItemByLabel("Album").(*tview.InputField).GetText())
err := tag.Save()
if err != nil {
errorPopup(err)
gomu.pages.RemovePage(popupID)
gomu.popups.pop()
return e return e
} }
defaultTimedPopup(" Success ", "Tag update successfully")
gomu.pages.RemovePage(popupID)
gomu.popups.pop()
case tcell.KeyEsc: case tcell.KeyEsc:
gomu.pages.RemovePage(popupID) gomu.pages.RemovePage(popupID)
gomu.popups.pop() gomu.popups.pop()
case tcell.KeyTAB: case tcell.KeyTab:
// if form.GetFormItemByLabel("Get Tag").HasFocus() { cycleFocus(gomu.app, inputs, false)
// lyricform.SetFocus(0) case tcell.KeyBacktab:
// } cycleFocus(gomu.app, inputs, true)
} }
return e return e
@ -1005,7 +1100,7 @@ func lyricPopup(audioFile *AudioFile) error {
} }
langExt := "en" langExt := "en"
err = embedLyric(audioFile.path, lyric, langExt) err = embedLyric(audioFile.path, lyric, langExt, false)
if err != nil { if err != nil {
errorPopup(err) errorPopup(err)
gomu.app.Draw() gomu.app.Draw()
@ -1048,7 +1143,7 @@ func lyricPopupCN(audioFile *AudioFile, serviceProvider string) error {
} }
langExt := "zh-CN" langExt := "zh-CN"
err = embedLyric(audioFile.path, lyric, langExt) err = embedLyric(audioFile.path, lyric, langExt, false)
if err != nil { if err != nil {
errorPopup(err) errorPopup(err)
gomu.app.Draw() gomu.app.Draw()
@ -1062,3 +1157,24 @@ func lyricPopupCN(audioFile *AudioFile, serviceProvider string) error {
return nil return nil
} }
func cycleFocus(app *tview.Application, elements []tview.Primitive, reverse bool) {
for i, el := range elements {
if !el.HasFocus() {
continue
}
if reverse {
i = i - 1
if i < 0 {
i = len(elements) - 1
}
} else {
i = i + 1
i = i % len(elements)
}
app.SetFocus(elements[i])
return
}
}

View File

@ -242,7 +242,7 @@ func shell(input string) (string, error) {
return stdout.String(), nil return stdout.String(), nil
} }
func embedLyric(songPath string, lyricContent string, usltContentDescriptor string) (err error) { func embedLyric(songPath string, lyricContent string, usltContentDescriptor string, isDelete bool) (err error) {
var tag *id3v2.Tag var tag *id3v2.Tag
tag, err = id3v2.Open(songPath, id3v2.Options{Parse: true}) tag, err = id3v2.Open(songPath, id3v2.Options{Parse: true})
if err != nil { if err != nil {
@ -262,13 +262,14 @@ func embedLyric(songPath string, lyricContent string, usltContentDescriptor stri
} }
tag.AddUnsynchronisedLyricsFrame(uslf) tag.AddUnsynchronisedLyricsFrame(uslf)
} }
tag.AddUnsynchronisedLyricsFrame(id3v2.UnsynchronisedLyricsFrame{ if !isDelete {
Encoding: id3v2.EncodingUTF8, tag.AddUnsynchronisedLyricsFrame(id3v2.UnsynchronisedLyricsFrame{
Language: "eng", Encoding: id3v2.EncodingUTF8,
ContentDescriptor: usltContentDescriptor, Language: "eng",
Lyrics: lyricContent, ContentDescriptor: usltContentDescriptor,
}) Lyrics: lyricContent,
})
}
err = tag.Save() err = tag.Save()
if err != nil { if err != nil {
return tracerr.Wrap(err) return tracerr.Wrap(err)