从ID3中解析Mp3元数据
TODO:: 判断MP3文件是否包含TAG
标签
MP3和ID3
ID3是一种在MP3中使用的描述MP3音频文件的元数据结构, 如下图所示:
ID3v1 字段结构
读取Mp3文件
1 | defmodule Mp3 do def get(filename) do case File.read(filename) do {:ok, binary} -> binary _ -> IO.puts "Can't not open #{filename}" end end end |
提取ID3v1 标记
ID3标记是MP3文件的最后128字节, 因此我们可以计算出ID3 Tag的起始偏移量
1 | mp3_byte_size = (byte_size(binary) - 128) |
然后通过Bit Syntax类匹配出我们需要的ID3 Tag部分的Bit字符串.
1 | << _ :: binary-size(mp3_byte_size), id3_tag :: binary >> = binary |
完整代码
1 | defmodule Mp3 do def parse(filename) do case File.read(filename) do {:ok, binary} -> IO.puts byte_size(binary) # 获取Mp3音频数据的大小,用于计算ID3的起始偏移量 mp3_byte_size = (byte_size(binary) - 128) * 8 # 把我们需要的部分解析出来 << _ :: size(mp3_byte_size), id3_tag :: binary >> = binary case id3_tag do <<"TAG",tags::binary>> -> # 从id3_tag中匹配出标题,艺术家名称,专辑名称,发行年份, 评论, 等 << tag :: binary-size(3), title :: binary-size(30), artist :: binary-size(30), album :: binary-size(30), year :: binary-size(4), comment :: binary-size(30), genre :: binary-size(1) >> = id3_tag # 输出 IO.puts tags IO.puts "TAG: #{tag}" IO.puts "标题名: #{title}" IO.puts "艺术家: #{artist}" IO.puts "专辑名: #{album}" IO.puts "年份: #{year}" IO.puts "评论: #{comment}" IO.puts "流派: #{genre}" _ -> :NO_TAG_INFORMATION end _ -> IO.puts "Can't not open #{filename}" end end end |
参考资料
- 本文原文
http://benjamintanweihao.github.io/blog/2014/06/10/elixir-bit-syntax-and-id3/ - ID3v1 结构说明
http://id3.org/ID3v1 - Erlang 比特语法和ID3
http://www.citizen428.net/blog/2010/09/04/erlang-bit-syntax-and-id3 - Erlang 比特语法
http://www.erlang.org/doc/programming_examples/bit_syntax.html - Erlang Programming - Francesco Cesarini and Simon Thompson 电子版PDF, 206页