All Projects → mrkkrp → htaglib

mrkkrp / htaglib

Licence: other
Haskell bindings for TagLib, an audio meta-data library

Programming Languages

haskell
3896 projects

Projects that are alternatives of or similar to htaglib

Widgetkit
Compose native apps without a code using JSON and load them as NSBundle into another app dynamicly from local or remote locations.
Stars: ✭ 191 (+855%)
Mutual labels:  bindings
niki
Media Player, DLNA, Music, Video and Streaming
Stars: ✭ 14 (-30%)
Mutual labels:  taglib
hoedown
rust bindings for hoedown
Stars: ✭ 16 (-20%)
Mutual labels:  bindings
Freetype Py
Python binding for the freetype library
Stars: ✭ 209 (+945%)
Mutual labels:  bindings
Python Mpv
Python interface to the awesome mpv media player
Stars: ✭ 245 (+1125%)
Mutual labels:  bindings
packtag
A JSP Taglib for delivering minified, combined and gzip-compressed resources (JavaScript and CSS).
Stars: ✭ 22 (+10%)
Mutual labels:  taglib
Go Python3
Go bindings to the CPython-3 API
Stars: ✭ 185 (+825%)
Mutual labels:  bindings
DotNetJS
Consume C# in JavaScript with comfort: single-file UMD library, auto-generated 2-way bindings and type definitions
Stars: ✭ 551 (+2655%)
Mutual labels:  bindings
node-taglib2
A rewrite of the now unmaintained node-taglib
Stars: ✭ 40 (+100%)
Mutual labels:  taglib
mapbox-ios-binding
Xamarin binding library for Mapbox iOS SDK
Stars: ✭ 15 (-25%)
Mutual labels:  bindings
Nimgl
NimGL is a Nim library that offers bindings for popular libraries used in computer graphics
Stars: ✭ 218 (+990%)
Mutual labels:  bindings
Fltk Rs
Rust bindings for the FLTK GUI library.
Stars: ✭ 241 (+1105%)
Mutual labels:  bindings
RubyGateway
Embed Ruby in Swift: load Gems, run scripts, call APIs seamlessly in both directions.
Stars: ✭ 108 (+440%)
Mutual labels:  bindings
Intercept
A C/C++ Binding Library for SQF and RV Engine Access Abstraction Layer
Stars: ✭ 191 (+855%)
Mutual labels:  bindings
swift-tree-sitter
Swift bindings for the tree-sitter parsing library
Stars: ✭ 29 (+45%)
Mutual labels:  bindings
Libvlc Go
Go bindings for libVLC and high-level media player interface
Stars: ✭ 188 (+840%)
Mutual labels:  bindings
marko-i18next
Components to use i18next in Marko templates.
Stars: ✭ 13 (-35%)
Mutual labels:  taglib
gfort2py
Library to allow calling fortran code from python
Stars: ✭ 60 (+200%)
Mutual labels:  bindings
loam
Javascript wrapper for GDAL in the browser
Stars: ✭ 174 (+770%)
Mutual labels:  bindings
samp-rs
SA:MP SDK written in Rust
Stars: ✭ 36 (+80%)
Mutual labels:  bindings

HTagLib

License BSD3 Hackage Stackage Nightly Stackage LTS CI

This is Haskell bindings to TagLib, a library for reading and editing meta-data of several popular audio formats.

It works with the following formats:

  • MP3
  • FLAC
  • MPC
  • Speex
  • WavPack TrueAudio
  • WAV
  • AIFF
  • MP4
  • ASF

This happens in an abstract, uniform way, so you don't need to handle any low-level details. As a consequence, it's currently not possible to work with format-specific functionality.

Alternatives

There is at least two other Haskell bindings to TagLib:

Both are low level, without any type safety or higher-level abstractions.

A note for FLAC users

If you want to work with FLAC, there is a complete Haskell binding to libFLAC—the reference FLAC implementation. It allows us to work with all FLAC metadata (read and write) and also provides a Haskell API to the stream encoder and the stream decoder. Please prefer that package if you don't need to work with other audio formats.

Quick start

First, since this is bindings to C-interface of the library, you'll need to install the library itself. If you're on a Unix-like system, chances are you'll have it in the official repositories of your distro.

Reading meta data

Now to the hacking. It's recommended that you define a record representing meta-data of audio track in your program, like this:

module Main (main) where

import Data.Monoid
import Sound.HTagLib
import System.Environment (getArgs)

data AudioTrack = AudioTrack
  { atTitle :: Title,
    atArtist :: Artist,
    atAlbum :: Album,
    atComment :: Comment,
    atGenre :: Genre,
    atYear :: Maybe Year,
    atTrack :: Maybe TrackNumber
  }
  deriving (Show)

We use unique types for every component of meta data, so it's more difficult to use a track title instead of a track artist, for example. String meta data types have smart constructors, but Title, Artist, Album, Comment, and Genre all are instances of IsString, so it is enough to turn on the OverloadedStrings language extension to use normal string literals to create values of these types.

Year and TrackNumber may be not set or missing, in this case you get Nothing. This is possible with string-based fields too, but in that case you just get empty strings. Year and TrackNumber have smart constructors that make sure that the values are positive (i.e. zero is not allowed).

OK, it's time to read some info. There is TagGetter type which is an applicative functor. You first construct TagGetter which will retrieve entire AudioTrack for you using the applicative style:

audioTrackGetter :: TagGetter AudioTrack
audioTrackGetter =
  AudioTrack
    <$> titleGetter
    <*> artistGetter
    <*> albumGetter
    <*> commentGetter
    <*> genreGetter
    <*> yearGetter
    <*> trackNumberGetter

Perfect, now use getTags to read the entire record:

main :: IO ()
main = do
  path <- head <$> getArgs
  track <- getTags path audioTrackGetter
  print track

For example (alignment is added):

$ ./example "/home/mark/music/David Bowie/1977, Low/01 Speed of Life.flac"
AudioTrack
  { atTitle = Title "Speed of Life",
    atArtist = Artist "David Bowie",
    atAlbum = Album "Low",
    atComment = Comment "",
    atGenre = Genre "",
    atYear = Just (Year 1977),
    atTrack = Just (TrackNumber 1)
  }

Success! It's also possible to extract audio properties like sample rate, etc. but it's not shown here for simplicity, consult Haddocks for more information.

N.B. If you need to extract the duration, TagLib only returns the number of seconds as an integer. This means that if you want to calculate the total duration of an album, you'll get a slightly incorrect result. The right solution is to extract the duration as floating-point number, for that we recommend the bindings to libsndfilehsndfile (or the above-mentioned flac package for Haskell if you work with FLAC).

Writing meta data

TagSetter is an instance of Monoid. This means that we can set title and artist of audio track like this:

main :: IO ()
main = do
  (path : title : artist : _) <- getArgs
  setTags path Nothing $
    titleSetter (mkTitle title)
      <> artistSetter (mkArtist artist)
  track <- getTags path audioTrackGetter
  print track

This code loads a file and changes the “title” and “artist” meta data fields.

Contribution

Issues, bugs, and questions may be reported in the GitHub issue tracker for this project.

Pull requests are also welcome.

License

Copyright © 2015–present Mark Karpov

Distributed under BSD 3 clause license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].