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:
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.
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:
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());
}
}
version: {}1.1.11 The Luggage
compiler: {}gcc version 4.4.4 (GCC)
changeset: {}1.1.11-0-ge4974ac
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();
}
}
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\\");
}
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");
}
}
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;
}
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());
uk.co.caprica.vlcj.player.embedded.windows.WindowsEmbeddedMediaPlayer
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.