6

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 support 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.

4

3 回答 3

5

您可以将 VLC 作为子进程运行,并通过进程输出流向其提供命令。您需要在每个命令之后刷新流并休眠一会儿。下面的代码并不能做所有事情——但它确实允许我在 Java 的控制下在 VLC 中播放不同的文件。

     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);

注意 - 您将需要另一个线程来读取 VLC 的输出,因此它不会阻塞:

     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();
于 2011-09-12T18:50:39.897 回答
0

在另一个论坛上找到了解决方案: http: //forums.sun.com/thread.jspa?threadID=5145675

显然,在 Linux 或 Mac 下运行时,您必须将“--rc-fake-tty”参数传递给 VLC。

于 2010-02-19T17:21:27.207 回答
0

由于 vlc 在 rc 模式下打开一个新的 DOS 窗口,因此在 writer.flush() 期间代码抱怨管道已关闭。这也被验证为 inputThread 打印“VLC OUTPUT:nullEnd of data from VLC”。有没有办法避免它,链接到新打开的 vlc rc 窗口?

问候

沙希德

于 2014-08-13T09:12:00.183 回答