Murga-Projects Forums

Full Version: Controling mpg321 with murgaLua.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I would like to build a graphical interface for mpg321 using the remote function.

Code:
mpg321 -R abc

The problem I'm having is to send the comands directly to mpg321. I can monitor the output of mpg321 by starting it with the comand...

Code:
mpg321 -R abc > /tmp/music

and then in murgaLua...

Code:
file="/tmp/music";
out=assert(io.open(file, "r"));
ww = 400;
wh = 60;
window = fltk:Fl_Window(ww, wh, "Monitor mpg321") ;
outputWindow = fltk:Fl_Multiline_Output(60, 5, 335, 50);
outputWindow:textsize(20);
function read()
while(true) do
Fl:check();
result=out:read("*line");
Fl:check();
if result ~= nil then
outputWindow:value(result);
end;
end;
end;
ButtonPlay = fltk:Fl_Button(5, 5, 50, 50, "Watch");
ButtonPlay:labelsize(15);
ButtonPlay:align(fltk.FL_ALIGN_WRAP);
ButtonPlay:callback(read);
window:show();
Fl:run();

This is very basic for now, but I would like to be able to send comands to mpg321 and possibly find a better way of reading them.
Thanks,
Dan

You can probably ignore what I posted originally. I misunderstood your question.
It seems that mpg321 has to have some sort of symbiotic relationship with its interface? The documentation mentions remote commands, but doesn't say how to send them.

After looking at mpg321 -R abc, it appears to create some strange interactive shell of some sort. That seems an odd way to remotely control an application through a gui. If you consider xmms, for example, the program runs remotely by sending commandline options with the xmms command. Maybe you'll need to change the default output of murgaLua in order to speak with the mpg321 interface, but that's just a wild guess. This sounds like an interesting project.

Original post:

Use os.execute("mpg321 -R") or io.popen("mpg321 -R")
The latter provides a way to directly grab the output of the command, bypassing the need to read and write a temp file.

I don't know a way to monitor continuous program output while keeping control of the interface. I assume it would require a coroutine, but I know nothing about that. It might work using the new murgaLua timer, though.
Hmm... I have never really liked the look of xmms (even with skins). I also found it lacking in some features (such as searching), but Xmms along with QueryXMMS may be just the thing I'm looking for. I could use QueryXmms to controll Xmms and get feed back from it. Then use murgaLua to create the GUI and features that I want. Now to just find a way of getting Xmms to play without a window (hidden).
Thanks for the feed back,
Dan
I've never cared for xmms either, and use either mpg321 or mplayer for most of my audio playing. When I said "consider xmms" I meant only "consider the fact that xmms does remote differently", and not that you should consider replacing mpg321
Okay, I have been gone all week and just had time to play with this again today. Here is what I have come up with so far. It doesn't apear to put much of a strain on my 800Mhz CPU. It requires XMMS, QueryXMMS, and murgaLua 0.5.5. I think I'll start working on the playlist features next. Right now I'm going to try and use SQLite based playlists and not use the XMMS playlist features at all. We'll see how that goes, but I would really like to use the table feature that John is working on for murgaLua 0.6.

Code:
timer = murgaLua.createFltkTimer()
os.execute("qxmms --start");

function quit_callback(w)
if fltk.fl_choice("Do yu want to quit XMMS?", "No", "Yes", nil) >= 1 then
window:hide()
os.execute("TEST=`pidof xmms`; kill $TEST")
os.exit()
else
window:hide()
os.exit()
end
end

function setState()
currentSongCMD =  io.popen("qxmms -t");
currentSong = currentSongCMD:read("*a");
currentSongCMD:close();
fullCurrentSong = currentSong;
titleCount = string.len(currentSong)
if titleCount>30
then
currentSong = string.match(currentSong, "..............................") .. "..."
end
outputWindow:label(currentSong)
outputWindow:tooltip(fullCurrentSong);
currentVolumeCMD = io.popen("qxmms -v");
currentVolume = currentVolumeCMD:read("*line");
currentVolumeCMD:close();
currentVolume = currentVolume/100
volume:value(currentVolume, "", "", "");

songLengthCMD = io.popen("qxmms -l");
songLength = songLengthCMD:read("*line");
songLengthCMD:close();
songPlayHead:label(songLength);

songTimePlayedCMD = io.popen("qxmms -n");
songTimePlayed = songTimePlayedCMD:read("*line");
songTimePlayedCMD:close();
timePlayedBox:label(songTimePlayed)

songLengthSecondsCMD = io.popen("qxmms -Sl");
songLengthSeconds = songLengthSecondsCMD:read("*line");
songLengthSecondsCMD:close();

songTimePlayedSecondsCMD = io.popen("qxmms -Sn");
songTimePlayedSeconds = songTimePlayedSecondsCMD:read("*line");
songTimePlayedSecondsCMD:close();

songPlayHead:value(songTimePlayedSeconds/songLengthSeconds, "", "", "");

currentStateCMD =  io.popen("qxmms -r");
currentState = currentStateCMD:read("*line");
currentStateCMD:close();

if currentState == "Playing"
then
buttonPause:show();
buttonPause:activate();
buttonPlay:hide();
buttonPlay:deactivate();
else
buttonPlay:show();
buttonPlay:activate();
buttonPause:hide();
buttonPause:deactivate();
end
window:redraw();
timer:doWait(.25)
end

timer:callback(setState)

function rewind()
os.execute("qxmms prev");
play()
end

function play()
os.execute("qxmms play");
currentState = "Playing"
currentSongCMD = io.popen("qxmms -t")
currentSong = currentSongCMD:read("*line")
currentSongCMD:close()
fullCurrentSong = currentSong;
titleCount = string.len(currentSong)
if titleCount>30
then
currentSong = string.match(currentSong, "..............................") .. "..."
end
outputWindow:label(currentSong)
outputWindow:tooltip(fullCurrentSong);
buttonPause:show();
buttonPause:activate();
buttonPlay:hide();
buttonPlay:deactivate();
songLengthCMD = io.popen("qxmms -l");
songLength = songLengthCMD:read("*line");
songLengthCMD:close();
songPlayHead:label(songLength);
window:redraw();
end

function pause()
os.execute("qxmms pause");
buttonPlay:show();
buttonPlay:activate();
buttonPause:hide();
buttonPause:deactivate();
currentState = "Pause"
end

function fastforward()
os.execute("qxmms next");
play()
end

function setVolume()
newVolume = volume:value()*100
os.execute("qxmms volume " .. newVolume);
end

function skip()
if songPlayHead:value()<.001
then
songPlayHead:value(.001)
end
newPlayTime = (songPlayHead:value()*songLengthSeconds)/60;
newPlayMinute, newPlaySecond = string.match(newPlayTime, "(%d+)%.(%d+)")
newPlaySecond = "." .. newPlaySecond;
newPlaySecond = math.floor(newPlaySecond*60);
newPlayTime = newPlayMinute .. ":" .. newPlaySecond
os.execute("qxmms seek " .. newPlayTime);
end

ww = 400;
wh = 60;
window = fltk:Fl_Double_Window(ww, wh, "Tux Tunes");
window:callback(quit_callback)

outputWindow = fltk:Fl_Box(110, 5, ww-115, 50);
outputWindow:box(fltk.FL_DOWN_BOX);
outputWindow:align(fltk.FL_ALIGN_CENTER+fltk.FL_ALIGN_TOP+fltk.FL_ALIGN_INSIDE);
outputWindow:color(fltk.FL_WHITE);

buttonRewind = fltk:Fl_Button(5, 5, 30, 30);
buttonRewind:label("@<<");
buttonRewind:align(fltk.FL_ALIGN_WRAP);
buttonRewind:color(52);
buttonRewind:tooltip("Play Previous Song");
buttonRewind:callback(rewind);

buttonPlay = fltk:Fl_Button(40, 5, 30, 30);
buttonPlay:label("@|>");
buttonPlay:align(fltk.FL_ALIGN_WRAP);
buttonPlay:color(52);
buttonPlay:tooltip("Play");
buttonPlay:callback(play);
buttonPlay:hide();
buttonPlay:deactivate();

buttonPause = fltk:Fl_Button(40, 5, 30, 30);
buttonPause:label("@||");
buttonPause:align(fltk.FL_ALIGN_WRAP);
buttonPause:color(52);
buttonPause:tooltip("Pause");
buttonPause:callback(pause);
buttonPause:hide();
buttonPause:deactivate();

buttonFastForward = fltk:Fl_Button(75, 5, 30, 30);
buttonFastForward:label("@>>");
buttonFastForward:align(fltk.FL_ALIGN_WRAP);
buttonFastForward:color(52);
buttonFastForward:tooltip("Play Next Song");
buttonFastForward:callback(fastforward);

volume = fltk:Fl_Slider(5, 45, 100, 10);
volume:type(fltk.FL_HORIZONTAL);
volume:color(52);
volume:tooltip("Volume");
volume:callback(setVolume)

songPlayHead = fltk:Fl_Slider(160, 40, outputWindow:w()-100, 10);
songPlayHead:type(fltk.FL_HOR_FILL_SLIDER);
songPlayHead:align(fltk.FL_ALIGN_LEFT);
songPlayHead:tooltip("Slide to skip forward or reverse");
songPlayHead:callback(skip)

timeTotalBox = fltk:Fl_Box(outputWindow:x()+5, 40, 40, 10);
timeTotalBox:box(fltk.FL_NO_BOX);
timeTotalBox:tooltip("Total Song Time");

timePlayedBox = fltk:Fl_Box(songPlayHead:x()+songPlayHead:w()+5, 40, 35, 10);
timePlayedBox:box(fltk.FL_NO_BOX);
timePlayedBox:align(fltk.FL_ALIGN_WRAP);
timePlayedBox:tooltip("TimePlayed");

setState()

Fl:scheme("gtk+")
window:show();
Fl:run();

Reference URL's