2010-02-18 61 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窗口?

問候

沙希德