Launch VLC in Java and connect to it via rc interface
I've already seen this thread, but I'm still having an issue: starting vlc player in java It appears the Java bindings for VLC are no longer under active development and do not supp开发者_StackOverflow中文版ort everything possible on the command line anyway.
Given the following code, I can't launch VLC from a Java application on Mac OS 10.5.8 (Java 1.6) and then connect to it via the rc interface through the Terminal or another Java application.
public class Main {
public static void main(String[] args) {
String s = null;
try {
//Process p = Runtime.getRuntime().exec("/Applications/VLC.app/Contents/MacOS/VLC -I telnet --telnet-host=localhost:4442 -I rc --rc-host=localhost:4444");
//Process p = Runtime.getRuntime().exec("/Applications/VLC.app/Contents/MacOS/VLC -I rc --rc-host=localhost:4444");
//ProcessBuilder pb = new ProcessBuilder("/Applications/VLC.app/Contents/MacOS/VLC","-I rc","--rc-host=localhost:4444");
ProcessBuilder pb = new ProcessBuilder("/Applications/VLC.app/Contents/MacOS/VLC","-IRC","--rc-host=localhost:4444");
Process p = pb.start();
StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), false);
StreamGobbler inputGobbler = new StreamGobbler(p.getInputStream(), false);
errorGobbler.start();
inputGobbler.start();
System.out.println("Waiting: \n"+p.waitFor());
System.out.println("All done here");
//p.destroy();
//System.exit(0);
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (Exception ie) {
ie.printStackTrace();
}
}
}
class StreamGobbler extends Thread {
InputStream is;
boolean discard;
StreamGobbler(InputStream is, boolean discard) {
this.is = is;
this.discard = discard;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
if(!discard)
System.out.println(line);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
} }
Here is the Java application using the Apache Commons Net package that I'm trying to connect to the above app running on the same machine:
public class TelnetTest {
public static void main(String args[]) {
TelnetClient tl = new TelnetClient();
try {
tl.connect("localhost", 4444);
if(tl.isConnected()) {
System.out.println("Connected successfully!");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(tl.getOutputStream()));
bw.write("quit");
bw.flush();
} else {
System.err.println("Problem with connection");
}
} catch(Exception e) {
System.err.println("Telnet connection threw an exception: "+e.getMessage());
}
}
}
The latter app works fine if I start VLC using the commands from the first app in the Terminal. Likewise, I can't connect to the first app from the Terminal using "telnet localhost 4444" in the Terminal.
The only difference I can find is in the output from VLC. When running in the terminal:
[0x2786e8] main interface error: no interface module matched "globalhotkeys,none"
[0x2786e8] main interface error: no suitable interface module
[0x201b28] main libvlc error: interface "globalhotkeys,none" initialization failed
Remote control interface initialized. Type `help' for help.
When executing via the top Java application:
[0x4009178] main interface error: no interface module matched "globalhotkeys,none"
[0x4009178] main interface error: no suitable interface module
[0x2017a8] main libvlc error: interface "globalhotkeys,none" initialization failed
[0x4009178] main interface error: no suitable interface module
[0x2017a8] main libvlc error: interface "default" initialization failed
Can anyone help me out here? I'm at a loss. Thank you very much.
You can run VLC as a subprocess and feed it commands through the process output stream. You need to flush the stream and sleep for a little while after each command. The following code doesn't do everything - but it does allow me to play different files in VLC under control of Java.
String vlcParameters = String.format(
"-I rc --rc-fake-tty --video-on-top --disable-screensaver --no-video-title-show " +
"--no-mouse-events --no-keyboard-events --no-fullscreen --no-video-deco " +
"--x11-display \"%s\" --video-x %d --video-y %d --width %d --height %d",
":0.0", // X11 display
top, // X
left, //Y
width, //Width
height //Height
);
ProcessBuilder pb = new ProcessBuilder("vlc", vlcParameters);
pb.redirectErrorStream(true);
vlcProcess = pb.start();
// Later - clear current playlist
writer.write("clear\n".getBytes());
writer.flush();
Thread.sleep(10);
String playListCommand = String.format(
"add file://%s\n",
filePath);
writer.write(playListCommand.getBytes());
writer.flush();
Thread.sleep(milliDuration - 10);
Note - you will need another thread to read the output from VLC so it doesn't block:
Thread inputThread = new Thread(new Runnable()
{
@Override
public void run()
{
InputStream in = vlcProcess.getInputStream();
BufferedReader bufin = new BufferedReader(new InputStreamReader(in));
try
{
while (true)
{
String line = bufin.readLine();
if (line == null)
{
System.out.writeln("End of data from VLC");
}
System.out.writeln("VLC OUTPUT:" + line);
}
}
catch (IOException ex)
{
//...
}
}
},
"VLC stdout reader");
inputThread.start();
Found the solution on another forum: http://forums.sun.com/thread.jspa?threadID=5145675
You have to pass the "--rc-fake-tty" argument to VLC when running under Linux or Mac apparently.
Since vlc opens a new DOS window in rc mode, during writer.flush() the code complains that the pipe was closed. this was also verified as the inputThread prints "VLC OUTPUT:nullEnd of data from VLC". Is there a way to avoid it, to link to the newly opened vlc rc window?
Regards
Shahid
精彩评论