News : The level of daily SPAM has reached insane proportions, all registrations are now manual. I ask you to send me an e-mail (john (at) murga (dot) org), to confirm that you want me to create an account for you.


Post Reply  Post Thread 
Pages (2): « First [1] 2 Next > Last »
access to media files on a LAN server
Author Message
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #1
access to media files on a LAN server

I recently spent a decent amount of time researching ways to stream media over a LAN server, and after wading through many sites talking mostly about Flash and other heavy options I eventually learned that some of the media players we all have installed already support streaming directly from a regular http/ftp link. For a few days I was playing around with mplayer and VLC, and it always came down to having to either copy and paste URLs or use a playlist that automatically starts playing.

So i decided to make a script that would bypass the need for a browser just to get a link and just run your chosen media player when you found what you wanted.

Note that this might not be suitable in any situation other than what I use it for, which is a local network, and it hasn't been tested for problems that might arise as a result of the server or any of the desired files being unavailable. Also note that it was written specifically to access one file at a time (i.e. a movie), not a playlist, and it DOES NOT SUPPORT SUBDIRECTORIES beyond what is listed in url[#] at this time. Subdirectories might actually break it, though so far they just seem to create a blank browser.

Requires a file host.."/lua_menu" which contains commands that add data to two tables, label and url. The format is:
label[1]="this is a label for dir 1"; url[1]="/this/is/the/dir/where/label1/files/live"
The URL must be a directory containing regular media files only (at this point), and if the host variable doesn't end with a slash, url must begin with a slash (url begins where host leaves off).

As always, bug reports and suggestions are welcome. I know I do sloppy work with tables, so if something better is suggested (while not making lua_menu more complicated to edit) I'd like that.

On a side note, it appears that Windows opens a cmd window when os.execute() is run. Is this because I used Progra~1 instead of trying harder to use the real path, or does that always happen with os.execute()?

Yet another note: the "srt" exception was added because I have some movies with srt subtitles...they work when I play the movies locally, but they serve no purpose when accessed through the network....one of these days I'm going to find out about serving subtitle files.

Code:
-- USER CONFIGURATION

--player="C:\\Progra~1\\SMPlayer\\smplayer.exe" -- Windows
player="mplayer" -- Linux
host="http://myhost/videos"

-- END USER CONFIGURATION

label={}; url={}
-- retrieve the menu from server
menufile,c,h=socket.http.request(host.."/lua_menu")
assert(loadstring(menufile))()

function get_menu()
box:clear()
for i,v in pairs(label) do
  box:add(v)
end
menu_up=1
end

function get_files()
box:clear()
body,code,header=socket.http.request(dir)
for l in string.gmatch(body,"<a href=\"(.-)\"") do
  if not string.find(l,"\.srt$") and not string.find(l,"\/") then
  box:add(l)
  end
end
menu_up=0
end

function play()
if box:value() > 0 and menu_up==0 then
  win:hide()
  Fl:check()
  os.execute(player.." "..dir.."/"..box:text(box:value()))
--  os.exit()
  win:show()
end
end

function menu_choice()
if box:value() > 0  and menu_up==1 then
dir=host..url[box:value()]
get_files()
end
end

ww,wh,bh=420,400,25
bw=ww/3
win=fltk:Fl_Window(ww,wh,"Movies")
box=fltk:Fl_Hold_Browser(0,0,ww,wh-bh); box:callback(menu_choice)
go=fltk:Fl_Button(0,wh-bh,bw,bh,"play"); go:callback(play)
fresh=fltk:Fl_Button(bw,wh-bh,bw,bh,"menu"); fresh:callback(get_menu)
no=fltk:Fl_Button(bw*2,wh-bh,bw,bh,"quit"); no:callback(function() os.exit() end)

--table.sort(menu)
get_menu()

--win:resizable(box)
win:show()
Fl:run()

01-10-2010 01:33 PM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #2
RE: access to media files on a LAN server

Also have to fix the keyboard control, but that's usually done after the clicky interface is fairly stable.

01-10-2010 02:55 PM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #3
RE: access to media files on a LAN server

Did some fixin'
Keyboard control should be halfway decent now.
The menu file is flexible, but i don't know if that is actually helpful.
Access is granted via double-click rather than having to click to select and then click a button to play.

EDIT: fixed crash if menu_file is not getted.
Still want to look into supporting subdirectories, but it feels complicated at the moment.

Code:
#!/usr/bin/env murgaLua

-- access media files on a file server & stream in a player
-- mikshaw 2010

--> USER CONFIGURATION <--

--player="C:\\Progra~1\\SMPlayer\\smplayer.exe" -- Windows
player="mplayer" -- Linux
host="http://localhost/videos"
menu_file=host.."/lua_menu"

--> END USER CONFIGURATION <--

label={}; url={}
-- retrieve the menu from server
menufile,c,h=socket.http.request(menu_file)
if c~=200 then
fltk.fl_alert("could not find "..menu_file)
os.exit() end
assert(loadstring(menufile))()

function get_menu()
box:clear()
for i,v in pairs(label) do
  box:add(v)
end
fresh:deactivate()
go:label("Show files")
box:value(1)
end

function get_files()
box:clear()
body,code,header=socket.http.request(dir)
for l in string.gmatch(body,"<a href=\"(.-)\"") do
  if not string.find(l,"\.srt$") and not string.find(l,"\/") then
  box:add(l)
  end
end
fresh:activate()
go:label("Play")
box:value(1)
end

function play(self)
if box:value() > 0 then
  if self:label()=="Play" then
    win:hide()
    Fl:check()
    os.execute(player.." "..dir.."/"..box:text(box:value()))
--    os.exit()
    win:show()
  else
    dir=host..url[box:value()]
    get_files()
  end
end
end

function dubbleclik()
if Fl:event() == fltk.FL_RELEASE and Fl:event_clicks() > 0 then
go:do_callback()
end
end

ww,wh,bh=420,400,25
bw=ww/3
win=fltk:Fl_Window(ww,wh,"Movies")
box=fltk:Fl_Hold_Browser(0,0,ww,wh-bh); box:callback(dubbleclik)
go=fltk:Fl_Return_Button(0,wh-bh,bw,bh,"Play"); go:callback(play)
fresh=fltk:Fl_Button(bw,wh-bh,bw,bh,"&Menu"); fresh:callback(get_menu)
no=fltk:Fl_Button(bw*2,wh-bh,bw,bh,"&Quit"); no:callback(function() os.exit() end)

--table.sort(menu)
get_menu()

--win:resizable(box)
win:show()
Fl:run()

This post was last modified: 01-13-2010 02:14 PM by mikshaw.

01-12-2010 03:01 PM
Find all posts by this user Quote this message in a reply
JohnMurga
Administrator
*******


Posts: 381
Group: Administrators
Joined: Apr 2007
Status: Offline
Reputation: 2
Post: #4
RE: access to media files on a LAN server

Sorry, just saw this now, I've been away.

I'll test tonight.

Regarding SRT files ... I don't think there is a way to serve them over the network.

The only solution I found is to do realtime transcoding, which is a bit like using a bulldozer to kill an ant.

Not sure about OS.execute(), but sys.spawn() doesn't open a CMD window.

Cheers
John de Murga

01-14-2010 08:01 PM
Visit this user's website Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #5
RE: access to media files on a LAN server

re: sys.spawn
Looks like it will work fine, but I don't really understand it.
At this point, what I see is
sys.spawn(command,{command_arguments?},something,something,something) =o)

I'm curious how one learns to use a software that has no website or documentation =o\

Anyway, this seems to be working for my current project:
sys.spawn(player, {dir.."/"..box:text(box:value())})
I still don't know when it's appropriate to use assert(), although the example used it.

But now I have to figure out how to keep the murgaLua window hidden while the player runs, since it apparently backgrounds the process by default. Maybe that's where one of the "something" parameters comes in?
I would use iconize() rather than hide(), but my window manager does not support minimizing.
Then again, over 99% of the world's desktop computer users do not have this issue, so maybe I should just go with iconize() and only use hide() for my personal copy.

01-15-2010 05:13 AM
Find all posts by this user Quote this message in a reply
JohnMurga
Administrator
*******


Posts: 381
Group: Administrators
Joined: Apr 2007
Status: Offline
Reputation: 2
Post: #6
RE: access to media files on a LAN server

mikshaw Wrote:
I'm curious how one learns to use a software that has no website or documentation =o\

Natural reaction, I am sorry.

Thats why I don't want to release a full murgaLua release until I get chance to have half decent documentation that goes with it.

I'll look at my docs snapshot as I think I did that function already.

Cheers
JohnM

01-16-2010 09:04 AM
Visit this user's website Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #7
RE: access to media files on a LAN server

That's a reasonable reason to not release a public release.
However, even though you don't have thorough documentation right now you do have this website, complete with a forum where people can get support from other users when they have questions. When I clicked the luasys "project home page" link at LuaForge, there was an index.php file listed as part of a directory listing...pretty much useless when the server apparently doesn't recognize index.php as a default index page, especially considering that I looked into the php page and saw nothing that had anything to do with luasys.

01-16-2010 01:48 PM
Find all posts by this user Quote this message in a reply
JohnMurga
Administrator
*******


Posts: 381
Group: Administrators
Joined: Apr 2007
Status: Offline
Reputation: 2
Post: #8
RE: access to media files on a LAN server

That another thing, I have to upgrade the forum so that people can register themselves ...
(Obviously with a good anti spam system).

Anyway ... The parameters for sys.spawn are :

Code:
filename (string),
arguments (table: {number => string}),
pid_udata (of new process),
in (fd_udata), out (fd_udata), err (fd_udata),
is_console (boolean)


For what you are doing sys.run might work too :-)

Cheers
JohnM

01-17-2010 12:42 PM
Visit this user's website Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #9
RE: access to media files on a LAN server

Ok, thanks, I'll try that. I noticed that using sys.spawn as I previously posted was causing murgaLua to crash after a series of 1) running the spawn command, 2) stopping the command, and then 3) sending an event to the murgaLua window. For now I've gone back to os.execute()

I did a bit of a rewrite to the original script today, although it's a little buggy. I dumped the menu file in favor of a couple of main menu items set within the script. I had made the menu file originally just because my videos directory already had an index.html file in its root for the lan website, but that file was a bit of a pain to parse in Lua. Now since this script is a more convenient way to play the files than by using a web browser, I got rid of the index.html file so all directories behave the same...just have to grab the "<a href=" strings.

The bugs come from not-fully-worked-out subdirectory support. At this point it looks like it's mostly working, with the browser hopefully keeping track of which item in the previous directory was selected...but I haven't tested it enough to know how reliable it is.

Code:
#!/usr/bin/env murgaLua

-- access media files on a file server & stream in a player
-- mikshaw 2010

--player="C:\\Progra~1\\SMPlayer\\smplayer.exe" -- Windows
player="mplayer" -- Linux
host="http://localhost"


ext= { "mp3", "ogg", "flac", "avi", "mp4", "mov", "divx", "flv",
"mkv", "asf", "mpg", "mpeg", "wmv", "wav" }

function get_menu()
box:clear()
box:add("videos/")
box:add("mp3/")
level=0
box:value(1)
end

function get_files()
box:clear()
body,code,header=socket.http.request(dir)
for l in string.gmatch(body,"<a href=\"(.-)\"") do
  if string.find(l,"\/$") then box:add(l) end
  for k,v in pairs(ext) do
    if string.find(string.lower(l),"%."..v) then
      box:add(l)
    end
  end
end
fresh:activate()
if not pos[level] then pos[level]=1 end
box:value(pos[level])
--print(pos[level],dir)
end

function play()
win:hide()
Fl:check()
--sys.spawn(player,{dir.."/"..box:text(box:value())}) --crashes
os.execute(player.." "..dir.."/"..box:text(box:value()))
win:show()
end

function go_back()
--pos[level]=box:value()
dir=string.gsub(dir,"/[^/]-/$","")
level=level-1
if host==dir then get_menu()
else
get_files()
end
end

function go_forward()
--pos[level]=box:value()
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


ww,wh,bh=420,400,25
bw=ww/3
win=fltk:Fl_Window(ww,wh,"Movies")
box=fltk:Fl_Hold_Browser(0,0,ww,wh-bh); box:callback(dubbleclik)
pack=fltk.Fl_Pack(0,wh-bh,wh,bh)
pack:type(1)
go=fltk:Fl_Return_Button(0,0,bw,bh,"Open"); go:callback(navigate)
fresh=fltk:Fl_Button(0,0,bw,bh,"&Menu"); fresh:callback(get_menu)
no=fltk:Fl_Button(0,0,bw,bh,"&Quit"); no:callback(function() os.exit() end)
fltk:Fl_End()

pos={}
pos[0]=1
dir=host
get_menu()

--win:resizable(box)
win:show()
Fl:run()

This post was last modified: 01-18-2010 03:46 PM by mikshaw.

01-18-2010 03:32 PM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 522
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #10
RE: access to media files on a LAN server

I think I fixed the navigation glitches.
Also now displays file size, although it is dependent upon having a server directory listing that puts the filesize in a <td class="s"> tag, since I couldn't think of another way to parse it. For now I'm just hoping it's not specific to lighttpd, but I may need to find a better way to do it.
EDIT: It appears that Apache doesn't use tables for directory listings, so I'm definitely going to need a new solution for file sizes. Seems to have been easier than I thought:
filesize=string.gsub(l,".*>([%d%.]-[KMG])<.*","%1")
I wouldn't be surprised if this is still not universal, but it will at least work for more than just lighttpd servers.

I moved the buttons off the visible interface, since there is already keyboard and double-click behavior to handle the same tasks as clicking the buttons.

EDIT2: fixed the ext loop to search for the extension at the end of the string, and to break if it matches.

EDIT3: It seems that having the main menu being dictated by the script is silly, when the server can easily just set up a "media" directory. Please bear with me...I'm not an expert with web servers, and things are likely to change a lot from week to week =o)
It's now set up so that there is a plain directory structure starting with "host", and what the server wants to do from that point is the server's problem.

Code:
#!/usr/bin/env murgaLua

-- access media files on a file server & stream in a player
-- mikshaw 2010

--player="C:\\Progra~1\\SMPlayer\\smplayer.exe" -- Windows
player="mplayer" -- Linux
host="http://localhost/media"


ext= { "mp3", "ogg", "flac", "avi", "mp4", "mov", "divx", "flv",
"mkv", "asf", "mpg", "mpeg", "wmv", "wav" }

function get_menu()
--box:clear()
--box:add("video/")
--box:add("audio/")
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()
body,code,header=socket.http.request(dir)
for l in string.gmatch(body,"<a href=.-\n") do
filename=string.gsub(l,"<a href=\"(.-)\".*","%1")
--filesize=string.gsub(l,".*<td class=\"s\">(.-)</td>.*","%1")
filesize=string.gsub(l,".*>([%d%.]-[KMG])<.*","%1")
  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)
      break
    end
  end
end
fresh:activate()
if not pos[level] then pos[level]=1 end
box:value(pos[level])
end

function play()
win:hide()
Fl:check()
--sys.spawn(player,{dir.."/"..box:text(box:value())}) --crashes
os.execute(player.." "..dir.."/"..string.gsub(box:text(box:value()),"\t.*",""))
win:show()
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


ww,wh,bh=550,400,25
bw=ww/3
win=fltk:Fl_Double_Window(ww,wh,"Movies")
box=fltk:Fl_Hold_Browser(0,0,ww,wh); box:callback(dubbleclik)
box:column_widths({ww-100,100,0})
pack=fltk.Fl_Pack(0,wh,wh,bh)
pack:type(1)
go=fltk:Fl_Return_Button(0,0,bw,bh,"Open"); go:callback(navigate)
fresh=fltk:Fl_Button(0,0,bw,bh,"&Menu"); fresh:callback(get_menu)
no=fltk:Fl_Button(0,0,bw,bh,"&Quit"); no:callback(function() os.exit() end)
fltk:Fl_End()

pos={}
pos[0]=1
get_menu()

win:resizable(box)
win:show()
Fl:run()

This post was last modified: 01-19-2010 02:25 PM by mikshaw.

01-19-2010 04:25 AM
Find all posts by this user Quote this message in a reply
Pages (2): « First [1] 2 Next > Last »
Post Reply  Post Thread 

View a Printable Version
Send this Thread to a Friend
Subscribe to this Thread | Add Thread to Favorites

Forum Jump: