(原) Mp3 Tag解析与写入

原创文章,请后转载,并注明出处。

No.1

github.com/dhowden/tag看起来它只是一个解析库,并未有写入功能。

type Metadata interface {
	Format() Format
	FileType() FileType

	Title() string
	Album() string
	Artist() string
	AlbumArtist() string
	Composer() string
	Genre() string
	Year() int

	Track() (int, int) // Number, Total
	Disc() (int, int) // Number, Total

	Picture() *Picture // Artwork
	Lyrics() string
	Comment() string

	Raw() map[string]interface{} // NB: raw tag names are not consistent across formats.
}

附带了一个Tag工具:go install github.com/dhowden/tag/cmd/tag@latest

No.2

github.com/jcs/id3-go 可以读写信息

/*
Title, Artist, Album, Year, Genre, and Comments
标题、艺术家、专辑、年份、流派和评论
*/

package main

import (
    id3 "github.com/jcs/id3-go"
    "fmt"
)

func main(){
	mp3File, _ := id3.Open("到了这个年纪.mp3")
	defer mp3File.Close()
	
	//mp3File.SetTitle("测试")
	//fmt.Println(mp3File.Title())
	mp3File.SetArtist("赵阿光")
	fmt.Println(mp3File.Artist())
}

No.3

github.com/jonasagx/id3tags

package main

import (
	"fmt"
	"github.com/jonasagx/id3tags"
)

func main() {
	var mp3file id3tags.Mp3
	mp3file.Filename = "Ellie Goulding - Burn.mp3"
	mp3file.Path = "/path/to/mp3/"
	mp3file.GetID3Tags()              //read tags from mp3 file
	fmt.Println(mp3file.Title)        //Burn
	mp3file.Artist = "Ellie Goulding" //set Artist
	mp3file.SetID3Tags()              //write tags to mp3file
}

No.4

github.com/szazeski/mp3edit 简单的一个文件,它也是调用了别人。可以简单的修改几个属性,适合于做命令行工具。

mp3edit <options> <filename>
 easy mp3 tag editor and simple audio operations
 version 1.0.3 built 2022-06-25
  -clear
  -copyTagsFrom=otherFile.mp3
  -title="New Title"
  -artist="New Artist"
  -album="New Album"

No.5

github.com/bogem/id3v2 上面的程序就是调用的这个库。

package main

import (
	"fmt"
	"log"

	"github.com/bogem/id3v2/v2"
)

func main() {
	tag, err := id3v2.Open(".//id3v2//testdata//test.mp3", id3v2.Options{Parse: true})
	if err != nil {
		log.Fatal("Error while opening mp3 file: ", err)
	}
	defer tag.Close()

	// Read tags
	fmt.Println(tag.Artist())          // 作者
	fmt.Println(tag.Title())           // 标题
	fmt.Println(tag.Genre())           // 类型/流派
	fmt.Println(tag.Album())           // 唱片集
	fmt.Println(tag.Year())            // 年
	fmt.Println(tag.Version())         // 版本
	fmt.Println(tag.DefaultEncoding()) // 编码
	fmt.Println(tag.Count())

	// Set tags
	//tag.SetArtist("Aphex Twin")
	//tag.SetTitle("Xtal")

	//comment := id3v2.CommentFrame{
	//	Encoding:    id3v2.EncodingUTF8,
	//	Language:    "eng",
	//	Description: "My opinion",
	//	Text:        "I like this song!",
	//}
	//tag.AddCommentFrame(comment)

	// Write tag to file.mp3
	if err = tag.Save(); err != nil {
		log.Fatal("Error while saving a tag: ", err)
	}
}
package main

import (
	"fmt"
	"log"

	"github.com/bogem/id3v2/v2"
)

func main() {
	tag, err := id3v2.Open("file.mp3", id3v2.Options{Parse: true})
	if err != nil {
 		log.Fatal("Error while opening mp3 file: ", err)
 	}
	defer tag.Close()

	// Read tags
	fmt.Println(tag.Artist())
	fmt.Println(tag.Title())

	// Set tags
	tag.SetArtist("Aphex Twin")
	tag.SetTitle("Xtal")

	comment := id3v2.CommentFrame{
		Encoding:    id3v2.EncodingUTF8,
		Language:    "eng",
		Description: "My opinion",
		Text:        "I like this song!",
	}
	tag.AddCommentFrame(comment)

	// Write tag to file.mp3
	if err = tag.Save(); err != nil {
		log.Fatal("Error while saving a tag: ", err)
	}
}

No.6

github.com/frolovo22/tag 解析和编辑 mp3、mp4 和 flac 格式的标签
看起来支持的挺多,但我试了它的演示程序却未达到效果,不知为何。


自己写了一“坨”代码,用于修改音频及改名和格式转换

package main

import (
	"fmt"
	"io/fs"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"runtime"
	"strings"

	"github.com/bogem/id3v2/v2"
)

func main() {
	f := FileForEach(".")
	for _, n := range f {
		//nf := strings.ReplaceAll(n.Name(), "-1080P 高清-AVC.aac", ".mp3")
		//nf = strings.ReplaceAll(nf, "-720P 高清-AVC.aac", ".mp3")
		//nf = strings.ReplaceAll(nf, "-360P 流畅-AVC.aac", ".mp3")
		//nf = strings.ReplaceAll(nf, "每日听书-", "")
		//fmt.Println(n.Name(), " ----> ", nf)
		//Command([]string{"ffmpeg", "-i", n.Name(), "-acodec", "libmp3lame", nf})
		setInfo(n.Name())
		// setInfo(nf)
	}
}

func setInfo(f string) {
	fi := strings.Split(f, "(Av89505210")
	fi = strings.Split(fi[0], ".")
	fmt.Println(fi)
	title := strings.ReplaceAll(fi[0], " ", "")
	fmt.Println(f," ----- ",title)
	return 
	os.Rename(f,title + ".mp3")
	f = title+".mp3"
	tag, err := id3v2.Open(f, id3v2.Options{Parse: true})
	if err != nil {
		log.Fatal("Error while opening mp3 file: ", err)
	}
	defer tag.Close()

	// Read tags
	// fmt.Println(tag.Artist())          // 作者
	// fmt.Println(tag.Title())           // 标题
	// fmt.Println(tag.Genre())           // 类型/流派
	// fmt.Println(tag.Album())           // 唱片集
	// fmt.Println(tag.Year())            // 年
	// fmt.Println(tag.Version())         // 版本
	// fmt.Println(tag.DefaultEncoding()) // 编码
	// fmt.Println(tag.Count())

	// Set tags
	// tag.SetArtist("考夫曼")
	tag.SetTitle(title)
	tag.SetAlbum("有声书-思考,快与慢")
	// tag.SetYear("2010")

	if err = tag.Save(); err != nil {
		log.Fatal("Error while saving a tag: ", err)
	}
}

func FileForEach(fileFullPath string) []fs.FileInfo {
	files, err := ioutil.ReadDir(fileFullPath)
	if err != nil {
		log.Fatal(err)
	}
	var myFile []fs.FileInfo
	for _, file := range files {
		if file.IsDir() {
			continue
		}
		myFile = append(myFile, file)
	}
	return myFile
}

// 执行命令
func Command(params []string) (string, error) {
	var c *exec.Cmd
	switch runtime.GOOS {
	case "darwin":
	case "windows":
		para := append([]string{"/C"}, params[0:]...)
		c = exec.Command("cmd", para...)
	case "linux":
		para := append([]string{"-c"}, params[0:]...)
		c = exec.Command("bash", para...)
	}

	output, err := c.CombinedOutput()
	return string(output), err
}

相关文章