Запустите VLC на Java и подключитесь к нему через интерфейс rc

Я уже видел этот поток, но у меня все еще есть проблема: запуск vlc player в java Похоже, что привязки Java для VLC больше не находятся в стадии активной разработки и в любом случае не поддерживают все возможности командной строки.

Учитывая следующий код, я не могу запустить VLC из приложения Java в Mac OS 10.5.8 (Java 1.6), а затем подключиться к нему через интерфейс rc через Терминал или другое приложение Java.

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

} }

Вот приложение Java, использующее пакет Apache Commons Net, которое я пытаюсь подключить к вышеуказанному приложению, работающему на том же компьютере:

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

Может кто-нибудь помочь мне здесь? Я в растерянности. Большое спасибо.


person onedanshow    schedule 18.02.2010    source источник


Ответы (3)


Вы можете запускать VLC как подпроцесс и передавать ему команды через поток вывода процесса. Вам нужно сбросить поток и немного поспать после каждой команды. Следующий код не делает всего, но позволяет мне воспроизводить разные файлы в VLC под управлением 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);

Примечание. Вам понадобится другой поток для чтения вывода из 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();
person Shalom Crown    schedule 12.09.2011
comment
Всем, кто хочет реализовать это, обратите внимание на \n в конце каждой команды. Также имейте в виду, что закрытие выходного потока приведет к отключению экземпляра VLC. Это были две вещи, которые меня зацепили. - person Brent Robinson; 26.01.2014

Решение найдено на другом форуме: http://forums.sun.com/thread.jspa?threadID=5145675

Вы должны передать аргумент «--rc-fake-tty» в VLC при работе под Linux или Mac, по-видимому.

person onedanshow    schedule 19.02.2010

Поскольку vlc открывает новое окно DOS в режиме rc, во время write.flush() код жалуется, что канал был закрыт. это также было проверено, поскольку inputThread печатает «VLC OUTPUT: nullEnd of data from VLC». Есть ли способ избежать этого, чтобы ссылаться на недавно открытое окно vlc rc?

С Уважением

Шахид

person user3604938    schedule 13.08.2014