2010-02-18 81 views
5

我已经看到这个线程,但我仍然有一个问题:starting vlc player in java它似乎VLC的Java绑定不再处于积极的发展,并不支持一切无论如何,都可以在命令行中使用。在Java中启动VLC,并通过rc接口连接到它

鉴于以下代码,我无法从Mac OS 10.5.8(Java 1.6)上的Java应用程序启动VLC,然后通过终端或其他Java应用程序通过rc接口连接到它。

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

}}

下面是使用我试图连接到同一台计算机上运行上述应用的Apache的共享网络包的Java应用程序:

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

的后者应用程序工作正常,如果我使用终端中的第一个应用程序的命令启动VLC。同样,我无法使用终端中的“telnet localhost 4444”连接到终端的第一个应用程序。

我能找到的唯一区别是VLC的输出。当在终端中运行:

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

当通过顶部的Java应用程序执行:

[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 

谁能帮助我在这里?我很茫然。非常感谢你。

回答

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(); 
+0

为任何人想要实现这一点,注意“\ n”在每个命令的末尾。另请注意,关闭输出流将导致VLC实例关闭。这两件事引起了我的注意。 – 2014-01-26 05:49:23

0

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

问候

沙希德