API VLCj: Criando Players de Áudio/Vídeo em Java

Veja neste artigo como trabalhar com a API VLCj, para criar seus próprios players de áudio/vídeo para Windows/Linux em Java baseados no VLC.

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.

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:

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
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:

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:

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:

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.

Artigos relacionados