#!/usr/bin/env murgaLua -- access media files on a http server & stream in a player -- mikshaw 2010 local VERSION=5 Fl:get_system_colors() -- check for configuration file myos=murgaLua.getHostOsName() if myos=="windows" then cfg=os.getenv("USERPROFILE").."\\media.lua.cfg" else cfg=os.getenv("HOME").."/.media.lua.cfg" end local get_cfg=loadfile(cfg) if get_cfg then get_cfg() end -- apply configuration variables if myos=="windows" then player=player or "C:\\Progra~1\\SMPlayer\\smplayer.exe" pls_flag=pls_flag or "" else player=player or "mplayer" pls_flag=pls_flag or "-playlist" end subtitle_flag=subtitle_flag or "-sub" host=host or "192.168.1.99" mediadir=mediadir or "/media" -- check is server is available testy=socket.protect(function() local c = socket.connect(host, 80) if not c then fltk.fl_alert("server not found!"); os.exit() else c:close() end end) testy() host="http://"..host..mediadir -- check if the media dir is available local b,c=socket.http.request(host) if c~=200 then fltk.fl_alert("media not available"); os.exit() end pls={} ext= { "mp3", "ogg", "ogv", "flac", "avi", "mp4", "mov", "divx", "flv", "mkv", "m4v", "asf", "mpg", "mpeg", "wmv", "wav" } -- os.tmpname() seems to be unreliable, particularly in Vista if myos=="windows" then plstmp=os.getenv("USERPROFILE").."\\media.lua.pls" subtmp=os.getenv("USERPROFILE").."\\media.lua.sub" else plstmp=os.getenv("HOME").."/media.lua.pls" subtmp=os.getenv("HOME").."/media.lua.sub" end function update_me() local remote_file=host.."/media.lua" local body,code,header=socket.http.request(remote_file) if code~=200 then fltk.fl_alert("I couldn't check for updates for some reason.\nNo biggie.") return end local current_version=tonumber(string.match(body,"VERSION=([%d]*)")) if current_version > VERSION then local ask=fltk.fl_choice("There is a newer version available.\nDo you want to update?","no","yes",NULL) if ask==1 then local outpoot=io.open(arg[0],"w") if outpoot then outpoot:write(body) outpoot:close() fltk.fl_message("Update successful.\nPlease restart the program.") else fltk.fl_alert("Sorry, but I couldn't update your script.\n You can try to download it yourself at "..remote_file) end end else fltk.fl_message("You have the latest version.") end end -- "menu" is a misnomer carried over from earlier version...really just resets to root directory function get_menu() level=0 dir=host get_files() box:remove(1) -- get rid of the ../ while pos[1] do table.remove(pos) end box:value(pos[level]) end function get_files() box:clear() pls={} body,code,header=socket.http.request(dir) for l in string.gmatch(body,"([%d%.]-[KMG])<.*","%1") -- server-specific if string.find(filename,"\/$") then box:add(filename) end for k,v in pairs(ext) do if string.find(string.lower(filename),"%."..v.."$") then box:add(filename.."\t"..filesize) table.insert(pls,dir.."/"..filename) break end end end fresh:activate() if not pos[level] then pos[level]=1 end box:value(pos[level]) end function play() realfile=string.gsub(box:text(box:value()),"\t.*","") subfile=string.gsub(realfile,"%.%w-$","%.srt") if string.find(body,subfile,1,1) then socket.http.request{ url=dir.."/"..subfile, sink=ltn12.sink.file(io.open(subtmp,"w")) } subflag=" "..subtitle_flag.." "..subtmp.." " else subflag=" " end win:hide() Fl:check() os.execute(player..subflag..dir.."/"..realfile) os.remove(subtmp) win:show() end function play_list() if not pls[1] then return end local playlist=io.open(plstmp,"w") if playlist then playlist:write("[playlist]\nNumberOfEntries="..table.maxn(pls).."\n") for i,v in pairs(pls) do playlist:write("File"..i.."="..v.."\n") end playlist:close() win:hide() Fl:check() os.execute(player.." "..pls_flag.." "..plstmp) win:show() else fltk.fl_message("Sorry, but I couldn't write a playlist") end end function go_back() dir=string.gsub(dir,"/[^/]-/$","") level=level-1 if host==dir then get_menu() else get_files() end end function go_forward() dir=dir.."/"..box:text(box:value()) level=level+1 get_files() end function dubbleclik() if Fl:event() == fltk.FL_RELEASE and Fl:event_clicks() > 0 then navigate() end end function navigate() if box:value() > 0 then pos[level]=box:value() if box:text(box:value())=="../" then go_back() elseif string.find(box:text(box:value()),"\/$") then go_forward() else play() end end end function quit() os.remove(subtmp) os.remove(plstmp) os.exit() end ww,wh,bw,bh=640,400,160,25 win=fltk:Fl_Double_Window(ww,wh,"Movies") win:callback(quit) box=fltk:Fl_Hold_Browser(0,0,ww,wh-bh); box:callback(dubbleclik) box:column_widths({ww-bw,bw,0}) go=fltk:Fl_Return_Button(0,0,0,0,"Open"); go:callback(navigate) fresh=fltk:Fl_Button(0,wh-bh,bw,bh,"back to &Main"); fresh:callback(get_menu) playall=fltk:Fl_Button(bw,wh-bh,bw,bh,"&Play all"); playall:callback(play_list) update=fltk:Fl_Button(bw*2,wh-bh,bw,bh,"check for &Updates"); update:callback(update_me) exit=fltk:Fl_Button(bw*3,wh-bh,bw,bh,"&Quit"); exit:callback(quit) pos={} pos[0]=1 get_menu() win:resizable(box) win:show() Fl:run()