O VLC é um famoso player de vídeo open-source, que roda em várias plataformas e toca vários tipos de formato de áudio/vídeo.

Para esse artigo, utilizaremos a versão 1.1.11, que pode ser baixada aqui:

Nota: O sistema operacional será o Windows XP – 32 bits.

Nesse site , encontra-se a API VLCj, que permite interagir com o player VLC, acessando quase todas as suas funcionalidades. A versão utilizada será a 1.1.5.1, que pode ser baixada aqui.

Nota: Os códigos fontes desse artigo também funcionam no Windows 64-bits. Porém, é necessário baixar o JDK 32 bits da Oracle (mesmo que seu sistema seja 64 bits), e instalar a versão Win32 do VLC (link acima). Com isso os exemplos funcionarão corretamente.

Executando vídeo no VLC
Figura 2. Executando vídeo no VLC

Configurando dependências

Além da API VLCj, é necessário a biblioteca JNA (Java Native Access), pois o VLCj é dependente dela (faz uso de JNA para acessar as funções nativas do VLC).

Temos, portanto, que configurar esses 3 jars na nossa aplicação:

Dependências
Figura 3. Dependências
Nota: JNA é uma API que permite acessar código nativo a partir do Java. Para maiores informações, clique aqui.

Testando a LibVlc

 
package br.com.devmedia.player;

import uk.co.caprica.vlcj.binding.LibVlc;

public class InformationLib {

    public static void main(String[] args) throws Exception {
        System.out.println("  version: {}" 
        + LibVlc.INSTANCE.libvlc_get_version());
        System.out.println(" compiler: {}" 
        + LibVlc.INSTANCE.libvlc_get_compiler());
        System.out.println("changeset: {}" 
        + LibVlc.INSTANCE.libvlc_get_changeset());
    }
}
Listagem 1. Obtendo informações da LibVlc

   version: {}1.1.11 The Luggage
   compiler: {}gcc version 4.4.4 (GCC) 
   changeset: {}1.1.11-0-ge4974ac
Listagem 2. Saída

A LibVlc é uma interface que representa algumas das funções nativas do VLC (expostas através da libvlc.dll no Windows e libvlc.so no Linux). Essa interface possui um atributo INSTANCE, que é uma implementação concreta da interface LibVlc, permitindo assim acessar todos os métodos definidos nela. O javadoc com a listagem de todos os métodos disponíveis dessa interface, e também do restante da API, pode ser baixado nesse link.

Criando o player de áudio/vídeo


package br.com.devmedia.player;

import com.sun.jna.NativeLibrary;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.util.ArrayList;
import java.util.List;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import uk.co.caprica.vlcj.runtime.windows.WindowsRuntimeUtil;

public class MinimalTestPlayer {

    public MinimalTestPlayer() {
        registerLibrary();
    }

    /**
     *  Executa arquivo de audio/video
     */
    public void play(final String filename) {
        final Canvas videoSurface = new Canvas();
        final Frame frame = buildFrame(videoSurface);
        final List<String> vlcArgs = 
        new ArrayList<String>();

        configureParameters(vlcArgs);

        final EmbeddedMediaPlayer mediaPlayer = 
        createPlayer(vlcArgs, videoSurface);
        mediaPlayer.playMedia(filename);
    }

    /**
     *  Importante: Informa onde está a libvlc, 
     que contem as funções nativas de manipulacao do player
     * 
     *  Windows: libvlc.dll
     *  Linux: libvlc.so
     */
    private void registerLibrary() {
        NativeLibrary.addSearchPath("libvlc", 
        "C:\\Arquivos de programas\\VideoLAN\\VLC\\");

        // Windows 64 bits:
        // NativeLibrary.addSearchPath("libvlc", 
        "c:\\Program Files (x86)\\VideoLAN\\VLC\\");
    }

    /**
     * Cria frame onde será exibido o filme
     */
    private Frame buildFrame(final Canvas videoSurface) {
        final Frame f = new Frame("Test Player");
        f.setSize(800, 600);
        f.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.setLayout(new BorderLayout());
        f.add(videoSurface, BorderLayout.CENTER);
        f.setVisible(true);
        return f;
    }

    /**
     * Configura parametros do VLC
     */
    private void configureParameters(final 
    List<String> vlcArgs) {
        vlcArgs.add("--no-plugins-cache");
        vlcArgs.add("--no-video-title-show");
        vlcArgs.add("--no-snapshot-preview");

        // Importante, se esse parametro nao 
        for configurado no Windows, a aplicacao nao funcionara
        if (RuntimeUtil.isWindows()) {
            vlcArgs.add("--plugin-path=" 
            + WindowsRuntimeUtil.getVlcInstallDir() + "\\plugins");
        }
    }

    /**
     * Constroi o player
     */
    private EmbeddedMediaPlayer createPlayer(final 
    List<String> vlcArgs, final Canvas videoSurface) {
        final MediaPlayerFactory factory = 
        new MediaPlayerFactory(vlcArgs.toArray(new String[vlcArgs.size()]));
        EmbeddedMediaPlayer mediaPlayer = factory.newMediaPlayer(null);
        mediaPlayer.setVideoSurface(videoSurface);
        return mediaPlayer;
    }

    public static void main(String[] args) throws InterruptedException {
        MinimalTestPlayer player = new MinimalTestPlayer();
        // Pode ser MP4, AVI, MOV, MKV, WMA, MPG, MP3, WAV, etc.
        player.play("C:\\videos\\qualquer_video.mp4");

        // Aguarda janela do player ser fechada
        Thread.currentThread().join();
    }
}
Listagem 3. Player de áudio/vídeo
Execução do Test Player
Figura 4. Execução do Test Player

Vamos a explicação dos trechos mais importantes do código:


private void registerLibrary() {
    NativeLibrary.addSearchPath("libvlc", "C:\\Arquivos de programas\\VideoLAN\\VLC\\");

    // Windows 64 bits:
    // NativeLibrary.addSearchPath("libvlc", "c:\\Program Files (x86)\\VideoLAN\\VLC\\");
}
Listagem 4. Registrando DLL (ou Shared Library no Linux)

Através do método addSearchPath da classe NativeLibray (do JNA), indicamos onde se encontra a biblioteca dinâmica nativa que possuem a API de manipulação do VLC.


/**
 * Configura parametros do VLC
 */
private void configureParameters(final List<String> vlcArgs) {
    vlcArgs.add("--no-plugins-cache");
    vlcArgs.add("--no-video-title-show");
    vlcArgs.add("--no-snapshot-preview");

    // Importante, se esse parametro nao for configurado no Windows, a aplicacao nao funcionara
    if (RuntimeUtil.isWindows()) {
        vlcArgs.add("--plugin-path=" + WindowsRuntimeUtil.getVlcInstallDir() + "\\plugins");
    }
}
Listagem 5. Configura os parâmetros do VLC antes da execução

Podemos passar uma série de parâmetros para o VLC, como por exemplo:

  • Tela cheia: --fullscreen
  • Configurar volume: -- volume
  • Desabilitando áudio: --noaudio
  • Definindo o tamanho da tela: --width, --height

Para ver a lista completa de parâmetros, acesse esse site.

Essas configurações também podem ser feitas programaticamente.

Nota: o parâmetro -plugin-path é necessário no Windows, para que o VLC possa ser executado corretamente.


/**
 * Constroi o player
 */
private EmbeddedMediaPlayer createPlayer(final List<String> vlcArgs, final Canvas videoSurface) {
    final MediaPlayerFactory factory = new MediaPlayerFactory(vlcArgs.toArray(new String[vlcArgs.size()]));
    EmbeddedMediaPlayer mediaPlayer = factory.newMediaPlayer(null);
    mediaPlayer.setVideoSurface(videoSurface);
    return mediaPlayer;
}
Listagem 6. Criando o objeto mediaPlayer

A classe MediaPlayer é a classe principal com a qual os desenvolvedores devem lidar para interagir com o VLC. É através dela que acessamos todas as funcionalidades do player VLC, a saber:

  • funções de playlist
  • controles: play, pause, stop, etc
  • captura de frame
  • controles de ajuste de vídeo
  • controles de ajuste de áudio

Apesar de ser a super-classe de tudo que se relaciona a Players na API, para trabalharmos com o Canvas, devemos usar a classe EmbeddedMediaPlayer, que é a super-classe (abstrata) para as implementações concretas do player.

Como o VLCj trabalha com múltiplas plataformas, ela faz uso de padrão Factory (MediaPlayerFactory), para devolver a instância de media player adequada para a plataforma sobre a qual ela roda (LinuxEmbeddedMediaPlayer, MacEmbeddedMediaPlayer ou WindowsEmbeddedMediaPlayer).

Para ver de fato qual instância o MediaPlayerFactory devolve, acrescente a linha abaixo no método createPlayer (antes do return, claro):


System.out.println (mediaPlayer.getClass().getName());
Listagem 7. Vendo o tipo de EmbeddedMediaPlayer

uk.co.caprica.vlcj.player.embedded.windows.WindowsEmbeddedMediaPlayer
Listagem 8. Saída (executando no Windows)

Nesse link, podem ser encontrados vários exemplos de código fonte, demonstrando várias outras funcionalidades, como:

  • Tratamento de eventos do player (MediaPlayerEventAdapter)
  • Configuração de teclas de atalho (AWTEventListener)
  • Interface de controle através de Swing / AWT (botões play / stop / next, etc)
  • Manipulação de playlist´s
  • etc.

Conclusão

Apesar dos exemplos terem sido executados no Windows, o mesmo é válido para o Linux (roda muito bem também). Agora, você pode criar seu próprio player de áudio/vídeo, customizá-lo e até mesmo controlá-lo via internet, celular, etc.

Espero que esse artigo auxilie os desenvolvedores a explorar essa interessante API.