Last active
November 2, 2019 21:20
-
-
Save geberl/da3f54a86811e22bce098a5ca10d8230 to your computer and use it in GitHub Desktop.
Get metadata and stream info from a flac audio file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
"github.com/mewkiz/flac" | |
"github.com/mewkiz/flac/meta" | |
) | |
// go run get_flac_info.go "/home/guenther/Downloads/[2010] Odd Blood/04 - i remember.flac" | |
// go run get_flac_info.go "/home/guenther/Downloads/05 - holiday in cambodia (live).flac" | |
var typeName = map[meta.Type]string{ | |
meta.TypeVorbisComment: "VORBIS_COMMENT", | |
} | |
func main() { | |
flag.Parse() | |
if flag.NArg() < 1 { | |
fmt.Fprintln(os.Stderr, "Exiting, no path(s) supplied") | |
os.Exit(1) | |
} | |
for _, path := range flag.Args() { | |
err := list(path) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
} | |
} | |
func list(path string) error { | |
// Open FLAC stream. | |
stream, err := flac.ParseFile(path) | |
if err != nil { | |
return err | |
} | |
// Get general file info | |
// File owner and file creation date are non-cross-platform (but possible) | |
// https://stackoverflow.com/questions/20875336/how-can-i-get-a-files-ctime-atime-mtime-and-change-them-using-golang | |
fi, err := os.Stat(path) | |
if err != nil { | |
return err | |
} | |
listStreamInfo(stream.Info, fi) | |
fmt.Printf("---\n") | |
listComments(stream.Blocks) | |
return nil | |
} | |
// listComments prints selected metadata tags present in the flac file | |
func listComments(bs []*meta.Block) { | |
vc := getVorbisComment(bs, false) | |
fmt.Printf("album : %s\n", getTag("ALBUM", vc)) | |
fmt.Printf("album artist : %s\n", getTag("ALBUMARTIST", vc)) | |
fmt.Printf("artist : %s\n", getTag("ARTIST", vc)) | |
fmt.Printf("date : %s\n", getTag("DATE", vc)) | |
fmt.Printf("discnumber : %s\n", getTag("DISCNUMBER", vc)) | |
fmt.Printf("disctotal : %s\n", getTag("DISCTOTAL", vc)) | |
fmt.Printf("genre : %s\n", getTag("GENRE", vc)) | |
fmt.Printf("title : %s\n", getTag("TITLE", vc)) | |
fmt.Printf("tracknumber : %s\n", getTag("TRACKNUMBER", vc)) | |
fmt.Printf("totaltracks : %s\n", getTag("TOTALTRACKS", vc)) | |
} | |
// getVorbisComment iterates through all the blocks, and returns the one containing the vorbis comment | |
func getVorbisComment(bs []*meta.Block, print bool) *meta.VorbisComment { | |
for _, block := range bs { | |
switch body := block.Body.(type) { | |
case *meta.VorbisComment: | |
if print { | |
for _, tag := range body.Tags { | |
fmt.Printf(" %s=%s\n", tag[0], tag[1]) | |
} | |
} | |
return body | |
} | |
} | |
return nil | |
} | |
// getTag iterates through all the tags in a vorbis comment, and returns the specified one | |
func getTag(t string, vc *meta.VorbisComment) string { | |
for _, tag := range vc.Tags { | |
if tag[0] == t { | |
return tag[1] | |
} | |
} | |
return "" | |
} | |
// listStreamInfo prints technical info about the flac file | |
func listStreamInfo(si *meta.StreamInfo, fi os.FileInfo) { | |
fileSize := fi.Size() | |
runTime := si.NSamples / uint64(si.SampleRate) | |
bitRate := fileSize / 125 / int64(runTime) | |
fmt.Printf("file size : %d bytes\n", fileSize) | |
fmt.Printf("file name : %s\n", fi.Name()) | |
fmt.Printf("file mode : %s\n", fi.Mode()) | |
fmt.Printf("file mod time : %s\n", fi.ModTime()) | |
fmt.Printf("run time : %d seconds\n", runTime) | |
fmt.Printf("bit rate : %d kbps\n", bitRate) | |
fmt.Printf("min blocksize : %d samples\n", si.BlockSizeMin) | |
fmt.Printf("max blocksize : %d samples\n", si.BlockSizeMax) | |
fmt.Printf("min framesize : %d bytes\n", si.FrameSizeMin) | |
fmt.Printf("max framesize : %d bytes\n", si.FrameSizeMax) | |
fmt.Printf("sample rate : %d Hz\n", si.SampleRate) | |
fmt.Printf("channels : %d\n", si.NChannels) | |
fmt.Printf("bits per sample : %d\n", si.BitsPerSample) | |
fmt.Printf("total samples : %d\n", si.NSamples) | |
fmt.Printf("MD5 : %x\n", si.MD5sum) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment