All checks were successful
continuous-integration/drone/push Build is passing
90 lines
2.5 KiB
Go
90 lines
2.5 KiB
Go
package tagger
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"strconv"
|
||
|
||
"gitea.mrixs.me/Mrixs/yamusic-bot/internal/model"
|
||
"github.com/bogem/id3v2"
|
||
)
|
||
|
||
// ID3Tagger реализует интерфейс interfaces.Tagger для работы с ID3-тегами.
|
||
type ID3Tagger struct{}
|
||
|
||
// NewID3Tagger создает новый экземпляр теггера.
|
||
func NewID3Tagger() *ID3Tagger {
|
||
return &ID3Tagger{}
|
||
}
|
||
|
||
// ReadMetadata читает основные метаданные (название, исполнитель) из аудиофайла.
|
||
func (t *ID3Tagger) ReadMetadata(filePath string) (string, string, error) {
|
||
tag, err := id3v2.Open(filePath, id3v2.Options{Parse: true})
|
||
if err != nil {
|
||
return "", "", fmt.Errorf("failed to open mp3 file for reading tags: %w", err)
|
||
}
|
||
defer tag.Close()
|
||
|
||
title := tag.Title()
|
||
artist := tag.Artist()
|
||
|
||
if title == "" || artist == "" {
|
||
return "", "", fmt.Errorf("title or artist tag is empty")
|
||
}
|
||
|
||
return title, artist, nil
|
||
}
|
||
|
||
// WriteTags записывает метаданные и обложку в указанный аудиофайл.
|
||
func (t *ID3Tagger) WriteTags(filePath string, coverPath string, info *model.TrackInfo) error {
|
||
tag, err := id3v2.Open(filePath, id3v2.Options{Parse: true})
|
||
if err != nil {
|
||
return fmt.Errorf("failed to open mp3 file for tagging: %w", err)
|
||
}
|
||
defer tag.Close()
|
||
|
||
tag.SetTitle(info.Title)
|
||
tag.SetArtist(info.Artist)
|
||
tag.SetAlbum(info.Album)
|
||
tag.SetYear(strconv.Itoa(info.Year))
|
||
tag.SetGenre(info.Genre)
|
||
|
||
// Добавляем исполнителя альбома (TPE2)
|
||
if info.AlbumArtist != "" {
|
||
tag.AddTextFrame(tag.CommonID("Band/Orchestra/Accompaniment"), id3v2.EncodingUTF8, info.AlbumArtist)
|
||
}
|
||
|
||
// Добавляем номер трека (TRCK)
|
||
if info.TrackPosition > 0 {
|
||
tag.AddTextFrame(tag.CommonID("Track number/Position in set"), id3v2.EncodingUTF8, strconv.Itoa(info.TrackPosition))
|
||
}
|
||
|
||
// Добавляем номер диска (TPOS)
|
||
if info.DiscNumber > 0 {
|
||
tag.AddTextFrame(tag.CommonID("Part of a set"), id3v2.EncodingUTF8, strconv.Itoa(info.DiscNumber))
|
||
}
|
||
|
||
// Встраиваем обложку
|
||
if coverPath != "" {
|
||
artwork, err := os.ReadFile(coverPath)
|
||
if err != nil {
|
||
return fmt.Errorf("failed to read cover file: %w", err)
|
||
}
|
||
|
||
pic := id3v2.PictureFrame{
|
||
Encoding: id3v2.EncodingUTF8,
|
||
MimeType: "image/jpeg",
|
||
PictureType: id3v2.PTFrontCover,
|
||
Description: "Front Cover",
|
||
Picture: artwork,
|
||
}
|
||
tag.AddAttachedPicture(pic)
|
||
}
|
||
|
||
if err = tag.Save(); err != nil {
|
||
return fmt.Errorf("failed to save id3 tags: %w", err)
|
||
}
|
||
|
||
return nil
|
||
}
|