-module(media). -export([init/0,insert/3, ask/2, all/0, play/3]). -define(TESTPATTERN, "../ac/*.mp3"). % Since we are not willing to calculate and deliver all the id3 tags everytime they are requested, % we try to get something persistent with mnesia. % Concerning the parsing of id3tags we use the library id3v2 by Brendon Hogger. For detailed information take a % look at the header of the library. % What is an entry in our database made of? By the way the filepath includes the filename. -record(track, {artist, title, votes, locked, filepath }). % With which application do we play mp3s? player(path) -> {ok, ["/usr/bin/env", "mplayer", "-quiet", path]}. % Before this module becomes usable, we must initialize it with the following steps: % 1. Initialize the mnesiadatabase and create the table within it. % 2. Parse the mp3s in the working directory and add them to the database % 3. Get into a loop so the database can be actually queried and files can be played. init() -> mnesia:create_schema([node()]), mnesia:start(), mnesia:create_table(track, [{attributes, record_info(fields, track)}]), read_files(filelib:wildcard(?TESTPATTERN),0,0), io:format("Initialisation of mnesia successful.\n"). read_files([FN|Rest],Total,Fail) -> case id3v2:read_file(FN) of {ok, Props} -> % insert entry into mnesia DB Artist = proplists:get_value(tpe1, Props), Title = proplists:get_value(tit2, Props), insert(bitstring_to_list(Artist), bitstring_to_list(Title), FN), read_files(Rest, Total+1, Fail); not_found -> read_files(Rest, Total+1, Fail+1) end; read_files([],Total,Fail) -> io:format("Total: ~w, Failed: ~w~n", [Total, Fail]). % Basic insertion of entrys into the database. Some entries are left out because they are 0 or false. insert(Artist, Title, Filepath) -> F = fun() -> mnesia:write(#track{artist = Artist, title = Title, votes = 0, locked = false, filepath = Filepath}) end, mnesia:transaction(F). % We want to query in order to simplify the next calls. ask(Artist, Title) -> F = fun() -> mnesia:match_object({track, Artist, Title, '_', '_', '_'}) end, {atomic, Results} = mnesia:transaction(F), Results. % Just in case the client is interested in everything we got. all() -> F = fun() -> mnesia:match_object({track, '_','_','_','_','_'}) end, {atomic, Results} = mnesia:transaction(F), Results. % We want to play mp3s from our database. play(Artist, Title, Callback) -> [Head|_] = ask(Artist, Title), {_, _, _, _, _, Fp} = Head, Port = erlang:open_port({spawn_executable, "/usr/bin/mplayer"}, [{args, [Fp]}]). % We want to execute commands locally