meta_flac.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package ffmpeg
  2. import (
  3. "context"
  4. "go.uber.org/zap"
  5. "mime"
  6. "strings"
  7. "github.com/go-flac/flacpicture"
  8. "github.com/go-flac/flacvorbis"
  9. "github.com/go-flac/go-flac"
  10. "golang.org/x/exp/slices"
  11. )
  12. func updateMetaFlac(_ context.Context, outPath string, m *UpdateMetadataParams, logger *zap.Logger) error {
  13. f, err := flac.ParseFile(m.Audio)
  14. if err != nil {
  15. return err
  16. }
  17. // generate comment block
  18. comment := flacvorbis.MetaDataBlockVorbisComment{Vendor: "unlock-music.dev"}
  19. // add metadata
  20. title := m.Meta.GetTitle()
  21. if title != "" {
  22. _ = comment.Add(flacvorbis.FIELD_TITLE, title)
  23. }
  24. album := m.Meta.GetAlbum()
  25. if album != "" {
  26. _ = comment.Add(flacvorbis.FIELD_ALBUM, album)
  27. }
  28. artists := m.Meta.GetArtists()
  29. for _, artist := range artists {
  30. _ = comment.Add(flacvorbis.FIELD_ARTIST, artist)
  31. }
  32. existCommentIdx := slices.IndexFunc(f.Meta, func(b *flac.MetaDataBlock) bool {
  33. return b.Type == flac.VorbisComment
  34. })
  35. if existCommentIdx >= 0 { // copy existing comment fields
  36. exist, err := flacvorbis.ParseFromMetaDataBlock(*f.Meta[existCommentIdx])
  37. if err != nil {
  38. for _, s := range exist.Comments {
  39. if strings.HasPrefix(s, flacvorbis.FIELD_TITLE+"=") && title != "" ||
  40. strings.HasPrefix(s, flacvorbis.FIELD_ALBUM+"=") && album != "" ||
  41. strings.HasPrefix(s, flacvorbis.FIELD_ARTIST+"=") && len(artists) != 0 {
  42. continue
  43. }
  44. comment.Comments = append(comment.Comments, s)
  45. }
  46. }
  47. }
  48. // add / replace flac comment
  49. cmtBlock := comment.Marshal()
  50. if existCommentIdx < 0 {
  51. f.Meta = append(f.Meta, &cmtBlock)
  52. } else {
  53. f.Meta[existCommentIdx] = &cmtBlock
  54. }
  55. if m.AlbumArt != nil {
  56. coverMime := mime.TypeByExtension(m.AlbumArtExt)
  57. logger.Debug("cover image mime detect", zap.String("mime", coverMime))
  58. cover, err := flacpicture.NewFromImageData(
  59. flacpicture.PictureTypeFrontCover,
  60. "Front cover",
  61. m.AlbumArt,
  62. coverMime,
  63. )
  64. if err != nil {
  65. logger.Warn("failed to create flac cover", zap.Error(err))
  66. } else {
  67. coverBlock := cover.Marshal()
  68. f.Meta = append(f.Meta, &coverBlock)
  69. // add / replace flac cover
  70. coverIdx := slices.IndexFunc(f.Meta, func(b *flac.MetaDataBlock) bool {
  71. return b.Type == flac.Picture
  72. })
  73. if coverIdx < 0 {
  74. f.Meta = append(f.Meta, &coverBlock)
  75. } else {
  76. f.Meta[coverIdx] = &coverBlock
  77. }
  78. }
  79. }
  80. return f.Save(outPath)
  81. }