-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathid3parser.exs
41 lines (31 loc) · 1.17 KB
/
id3parser.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# A refactor of Benjamin Tan's ID3v1 parsing code at http://benjamintan.io/blog/2014/06/10/elixir-bit-syntax-and-id3/
defmodule ID3Parser do
@id3_tag_size 128
def parse(file_name, io_input \\ &File.read/1, io_output \\ &IO.puts/1) do
case io_input.(file_name) do
{:ok, binary} ->
{title, artist, album, year, comment} = parse_binary(binary)
io_output.(title)
io_output.(artist)
io_output.(album)
io_output.(year)
io_output.(comment)
_ ->
io_output.("Couldn't open #{file_name}")
end
end
def parse_binary(binary) when byte_size(binary) > @id3_tag_size do
mp3_byte_size = (byte_size(binary) - @id3_tag_size)
<< _ :: binary-size(mp3_byte_size), id3_tag :: binary >> = binary
<< "TAG",
title :: binary-size(30),
artist :: binary-size(30),
album :: binary-size(30),
year :: binary-size(4),
comment :: binary-size(30),
_rest :: binary >> = id3_tag
{title, artist, album, year, comment}
end
end
# Now you can easily test both the "parse" and "parse_binary" functions in isolation,
# and the latter is additionally functionally pure.