vlibras-player-nextjs
v2.5.1
Published
VLibras Player para Next.js - Biblioteca moderna para tradução de texto em Libras com callbacks de estado
Maintainers
Readme
vlibras-player-nextjs
Biblioteca moderna do VLibras Player para Next.js e React com TypeScript
🎯 Sobre
O vlibras-player-nextjs é uma biblioteca moderna e otimizada do VLibras Player, especialmente desenvolvida para aplicações Next.js e React. Esta biblioteca permite integrar facilmente a tradução automática de texto para Libras (Língua Brasileira de Sinais) em suas aplicações web.
✨ Principais Características
- 🚀 Compatível com Next.js 13+ (App Router e Pages Router)
- 🔷 TypeScript nativo com tipagem completa
- ⚛️ Hooks React modernos com conexão automática ao DOM
- 🎨 Componentes estilizados prontos para uso
- 📱 Design responsivo e acessível
- 🌙 Suporte a tema escuro
- 🔧 API moderna e fácil de usar
- 📦 Tree-shaking otimizado
- 🧪 Totalmente testado
- 🔄 Conexão automática ao container DOM (v2.1.0+)
- 🔧 Sem duplicação de containers Unity (v2.1.1+)
- 🎯 Callbacks de estado para monitoramento preciso (v2.2.0+)
- 🔄 Gerenciamento Unity corrigido com aguardo real de prontidão (v2.3.0+)
🆕 Novidades v2.5.0 - Hook com Melhores Práticas React! ⚛️
A versão v2.5.0 traz o hook redesenhado seguindo as melhores práticas do React:
🏗️ Arquitetura Moderna com useReducer
- ✅ Estado Centralizado: Gerenciamento com
useReducerpara maior previsibilidade - ✅ Memoização Inteligente: Callbacks e objetos memoizados para performance otimizada
- ✅ Estados Derivados:
canTranslate,canPause,canResume,canStop,canRestart - ✅ Tratamento de Erros Robusto: Distinção entre erros fatais e avisos
- ✅ Debouncing: Prevenção de traduções muito rápidas consecutivas
🎯 Interface Organizadas em Grupos
const player = useVLibrasPlayer({ containerRef, autoInit: true });
// Controles agrupados
player.controls.play();
player.controls.pause();
// Configurações agrupadas
player.settings.setSpeed(1.5);
player.settings.setRegion('BR');
// Utilitários agrupados
player.utils.clearWarnings();
player.utils.retry();🚀 Funcionalidades Avançadas
- � Retry Automático: Tentativas de reconexão configuráveis
- ⏱️ Debouncing: Controle de frequência de traduções
- 🛑 AbortController: Cancelamento de operações assíncronas
- 🧹 Cleanup Automático: Gerenciamento de memória e timers
- � Estados Derivados: Estados computados para UX melhor
🔗 Compatibilidade Mantida
- ✅ API Legacy: Métodos antigos mantidos para compatibilidade
- ✅ Migração Gradual: Adote novas práticas progressivamente
- ✅ TypeScript Melhorado: Tipagem mais precisa e documentação inline
⚠️ Principais Melhorias v2.4.1:
- Hook incompleto sem novas funcionalidades → ✅ Hook oficial 100% atualizado
- Faltavam controles inteligentes → ✅ Controles automáticos baseados no estado
- Sem logging de eventos → ✅ Sistema completo de event logging
- Callbacks não integrados no hook → ✅ Integração total com callbacks
- Erros de tipagem TypeScript → ✅ Tipos corrigidos e interface atualizada
🆕 v2.3.0 - Correções Críticas de Estado
A versão v2.3.0 corrige problemas críticos de gerenciamento de estado Unity:
- ✅ UnityStateManager: Nova classe para controle preciso do estado Unity WebGL
- ✅ Aguardo de Prontidão: Métodos aguardam automaticamente Unity estar pronto
- ✅ Callbacks Funcionais: Sistema de callbacks totalmente corrigido
- ✅ Detecção de Animação: Aguarda conclusão real das animações
- ✅ Estados Confiáveis:
isReadyreflete o estado real do Unity - ✅ Debugging: Informações detalhadas para desenvolvimento
⚠️ Problemas Corrigidos na v2.3.0:
isReady: trueantes do Unity estar pronto → ✅ Corrigido- Callbacks
onLoadnão funcionando → ✅ Corrigido - Tradução não aguardando animação → ✅ Corrigido
- Estados inconsistentes → ✅ Corrigido
🆕 v2.2.0 - Callbacks de Estado (Base)
A versão v2.2.0 introduz callbacks de estado que permitem monitorar eventos reais do VLibras Player:
const { translate, isTranslating, isPlaying } = useVLibrasPlayer({
// ✅ Callbacks de tradução
onTranslationStart: () => console.log('🎬 Tradução iniciada'),
onTranslationEnd: () => console.log('✅ Tradução finalizada'),
onTranslationError: (error) => console.log('❌ Erro:', error),
// ✅ Callbacks de reprodução
onPlay: () => console.log('▶️ Reprodução iniciada'),
onPause: () => console.log('⏸️ Pausado'),
onStop: () => console.log('⏹️ Parado'),
// ✅ Callbacks do player
onPlayerReady: () => console.log('🚀 Player pronto'),
onPlayerError: (error) => console.log('💥 Erro no player:', error),
});
// ✅ Estados precisos baseados em eventos reais
console.log('Traduzindo:', isTranslating); // true/false preciso
console.log('Reproduzindo:', isPlaying); // true/false precisoBenefícios dos Callbacks:
- 🎯 Estado preciso - Conhecimento real do que está acontecendo
- 🖥️ UI responsiva - Interfaces que refletem o estado real
- 📊 Analytics - Logging preciso de eventos
- 🔄 Sem timers - Eventos nativos do Unity WebGL
- ✅ Retrocompatível - API anterior continua funcionando
📚 Documentação completa: docs/CALLBACKS_DOCUMENTATION.md
📦 Instalação
npm install vlibras-player-nextjs
# ou
yarn add vlibras-player-nextjs
# ou
pnpm add vlibras-player-nextjs� Debugging e Estado Unity (v2.3.0)
Para verificar o estado real do Unity e debugar problemas:
'use client';
import { useVLibrasPlayer, UnityStateManager } from 'vlibras-player-nextjs';
export default function DebugComponent() {
const { player, isReady, connect } = useVLibrasPlayer({
onLoad: () => console.log('✅ Unity realmente pronto!'),
});
const showDebugInfo = () => {
const debugInfo = UnityStateManager.getDebugInfo();
console.log('🔍 Debug Unity:', debugInfo);
// Verificação manual do estado
console.log('🔍 Unity Ready:', UnityStateManager.isUnityReady());
console.log('🔍 Animation Playing:', UnityStateManager.isAnimationPlaying());
};
return (
<div>
<button onClick={showDebugInfo}>Ver Debug Info</button>
<div id="vlibras-player-container"></div>
<div>Estado: {isReady ? '✅ Pronto' : '⏳ Carregando'}</div>
</div>
);
}�🚀 Uso Básico
Hook React Moderno (v2.5.0+) ⚛️
'use client';
import { useRef } from 'react';
import { useVLibrasPlayer } from 'vlibras-player-nextjs';
export default function ModernVLibrasComponent() {
const containerRef = useRef<HTMLDivElement>(null);
// 🚀 Hook com melhores práticas React
const player = useVLibrasPlayer({
containerRef,
autoInit: true,
retryOnError: true,
maxRetries: 3,
debounceMs: 300,
// Callbacks organizados
onPlayerReady: () => console.log('🚀 Player pronto!'),
onStateChange: (state) => console.log('📊 Estado:', state.status),
onTranslationStart: () => console.log('🎬 Tradução iniciada'),
onTranslationEnd: () => console.log('✅ Tradução finalizada'),
onPlayerError: (error, isFatal) => {
console.log(isFatal ? '💥 Erro fatal:' : '⚠️ Aviso:', error);
}
});
const handleTranslate = async () => {
if (!player.canTranslate) return;
try {
await player.translate("Olá mundo moderno!");
} catch (error) {
console.error('Erro na tradução:', error);
}
};
return (
<div>
<div ref={containerRef} className="vlibras-container" />
{/* Controles inteligentes baseados em estado derivado */}
<button
onClick={handleTranslate}
disabled={!player.canTranslate}
>
{player.isBusy ? 'Processando...' : 'Traduzir'}
</button>
<button
onClick={player.controls.pause}
disabled={!player.canPause}
>
Pausar
</button>
<button
onClick={player.controls.resume}
disabled={!player.canResume}
>
Retomar
</button>
<button
onClick={player.controls.stop}
disabled={!player.canStop}
>
Parar
</button>
{/* Configurações */}
<button onClick={() => player.settings.setSpeed(1.5)}>
Velocidade 1.5x
</button>
{/* Utilitários */}
{player.hasWarnings && (
<button onClick={player.utils.clearWarnings}>
Limpar Avisos ({player.errors.warnings.length})
</button>
)}
{/* Estado visual */}
<div>
<p>Status: {player.status}</p>
<p>Pronto: {player.isReady ? '✅' : '⏳'}</p>
<p>Traduzindo: {player.isTranslating ? '🎬' : '⏸️'}</p>
<p>Reproduzindo: {player.isPlaying ? '▶️' : '⏹️'}</p>
{player.errors.fatal && (
<p style={{ color: 'red' }}>Erro: {player.errors.fatal}</p>
)}
</div>
</div>
);
}API de Compatibilidade (v2.4.x e anteriores)
'use client';
import { useRef } from 'react';
import { useVLibrasPlayer } from 'vlibras-player-nextjs';
export default function LegacyComponent() {
const containerRef = useRef<HTMLDivElement>(null);
const { translate, isReady, isLoading, error } = useVLibrasPlayer({
autoInit: true,
containerRef, // 🔥 CONEXÃO AUTOMÁTICA!
targetPath: '/vlibras/target',
region: 'BR',
onLoad: () => console.log('Player carregado!'),
onError: (error) => console.error('Erro:', error)
});
const handleTranslate = async () => {
if (!isReady) return;
try {
await translate("Olá mundo!");
} catch (error) {
console.error('Erro na tradução:', error);
}
};
return (
<div>
<div ref={containerRef} className="vlibras-container" />
<button
onClick={handleTranslate}
disabled={!isReady || isLoading}
>
{isLoading ? 'Traduzindo...' : 'Traduzir'}
</button>
{error && <p style={{ color: 'red' }}>Erro: {error}</p>}
</div>
);
}
}Classe VLibras Player (Uso Direto)
'use client';
import { VLibrasPlayer } from 'vlibras-player-nextjs';
import { useRef, useEffect, useState } from 'react';
export default function DirectUsage() {
const containerRef = useRef<HTMLDivElement>(null);
const [player, setPlayer] = useState<VLibrasPlayer | null>(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (containerRef.current) {
const playerInstance = new VLibrasPlayer({
targetPath: '/vlibras/target',
region: 'BR'
});
playerInstance.load(containerRef.current);
setPlayer(playerInstance);
}
}, []);
const handleTranslate = async () => {
if (!player) return;
setIsLoading(true);
try {
await player.translate("Olá mundo!");
} catch (error) {
console.error('Erro na tradução:', error);
} finally {
setIsLoading(false);
}
};
return (
<div>
<div ref={containerRef} className="vlibras-container" />
<button onClick={handleTranslate} disabled={!player || isLoading}>
{isLoading ? 'Traduzindo...' : 'Traduzir'}
</button>
</div>
);
} player.load(containerRef.current);
}}, [player]);
🆕 Novidades da v2.1.1
🔧 Bug Crítico de Duplicação Resolvido
A v2.1.1 resolve um bug crítico que causava duplicação de containers Unity WebGL:
❌ Problema (v2.1.0 e anteriores)
- 🔴 Múltiplos containers: Criava containers duplicados a cada re-render
- 🔴 Vazamentos de memória: Containers órfãos não eram limpos
- 🔴 Performance degradada: Múltiplas instâncias Unity simultâneas
- 🔴 IDs aleatórios: Timestamps únicos impediam reutilização
✅ Solução (v2.1.1)
- 🟢 Container único: Reutiliza container existente quando possível
- 🟢 Cleanup automático: Remove containers órfãos antes de criar novos
- 🟢 IDs estáveis: Baseados na região em vez de timestamps
- 🟢 Verificação de estado: Só carrega Unity se necessário
🚀 Melhorias Implementadas
- Verificação de Container Existente: Player reutiliza containers quando possível
- Cleanup Automático: Remove containers órfãos para evitar duplicação
- IDs Estáveis: Containers têm IDs previsíveis para melhor reutilização
- Dispose Melhorado: Limpeza completa de estado e recursos
- Hook Otimizado: Dependências otimizadas para evitar re-execuções
🔄 Novidades da v2.1.0
✅ Hook useVLibrasPlayer Corrigido
O principal problema da v2.0.0 foi resolvido! Agora o hook conecta automaticamente ao container DOM:
❌ Antes (v2.0.0 - Quebrado)
const { player, translate } = useVLibrasPlayer({ autoInit: true });
// ❌ Necessário fazer conexão manual
useEffect(() => {
if (containerRef.current && player) {
player.load(containerRef.current); // ❌ Não funcionava
}
}, [player]);✅ Agora (v2.1.0+ - Funciona!)
const { translate, isReady } = useVLibrasPlayer({
autoInit: true,
containerRef // ✅ Conexão automática!
});
// ✅ Pronto para usar, sem configuração adicional!🚀 Funcionalidades v2.1.0
- Conexão Automática: Use
containerRefpara conexão automática - Callbacks de Eventos:
onLoad,onTranslateStart,onTranslateEnd,onError - Estado
isReady: Saiba quando o player está pronto para uso - Método
connect(): Conexão manual quando necessário - Tratamento de Erros Melhorado: Erros mais informativos if (playerRef.current) { await playerRef.current.translate('Olá mundo!'); } };
return ( Traduzir ); } <button onClick={() => play()}>Play <button onClick={() => pause()}>Pause
<div className="status">
Status: {player.status} | Carregado: {player.loaded ? 'Sim' : 'Não'}
</div>
</div>); }
## 🔧 API Completa
### Hook useVLibrasPlayer (v2.1.0+)
```typescript
interface UseVLibrasPlayerOptions {
// Configurações do Player
autoInit?: boolean; // Inicializa automaticamente
containerRef?: RefObject<HTMLElement>; // Ref para conexão automática
targetPath?: string; // Caminho dos arquivos Unity
translatorUrl?: string; // URL do serviço de tradução
region?: 'BR' | 'PT'; // Região do dicionário
enableStats?: boolean; // Habilitar estatísticas
// Callbacks
onLoad?: () => void; // Player carregado
onTranslateStart?: (text: string) => void; // Tradução iniciada
onTranslateEnd?: (gloss: string) => void; // Tradução finalizada
onError?: (error: string) => void; // Erro ocorrido
}
// Uso do Hook
const {
// Estado
player, // Estado atual do player
isLoading, // Se está carregando/traduzindo
error, // Erro atual (se houver)
isReady, // Se está pronto para uso (v2.1.0+)
// Métodos de Controle
translate, // Traduzir texto
play, // Reproduzir animação
pause, // Pausar animação
stop, // Parar animação
repeat, // Repetir última animação
setSpeed, // Definir velocidade
toggleSubtitle, // Alternar legendas
changeAvatar, // Trocar avatar
setRegion, // Definir região
// Conexão Manual (v2.1.0+)
connect, // Conectar a container específico
} = useVLibrasPlayer(options);Classe VLibrasPlayer
interface VLibrasPlayerOptions {
translatorUrl?: string;
targetPath?: string;
region?: 'BR' | 'PT';
enableStats?: boolean;
onLoad?: () => void;
}
// Uso da Classe
const player = new VLibrasPlayer(options);
player.load(containerElement);
await player.translate(text);// Métodos de controle translate, // Traduzir texto play, // Reproduzir pause, // Pausar stop, // Parar repeat, // Repetir
// Configurações
🎨 Exemplos Avançados
Exemplo com Callbacks e Estados
'use client';
import { useRef, useState } from 'react';
import { useVLibrasPlayer } from 'vlibras-player-nextjs';
export default function AdvancedExample() {
const containerRef = useRef<HTMLDivElement>(null);
const [status, setStatus] = useState('Aguardando...');
const [translatedText, setTranslatedText] = useState('');
const {
translate,
play,
pause,
stop,
setSpeed,
isReady,
isLoading,
error,
player
} = useVLibrasPlayer({
autoInit: true,
containerRef,
region: 'BR',
targetPath: '/vlibras/target',
onLoad: () => setStatus('Player carregado!'),
onTranslateStart: (text) => {
setStatus(`Traduzindo: ${text}`);
setTranslatedText(text);
},
onTranslateEnd: (gloss) => setStatus(`Glosa: ${gloss}`),
onError: (error) => setStatus(`Erro: ${error}`)
});
const handleTranslate = async () => {
const text = prompt('Digite o texto para traduzir:');
if (text && text.trim()) {
try {
await translate(text);
} catch (err) {
console.error('Erro na tradução:', err);
}
}
};
return (
<div className="vlibras-demo">
<div ref={containerRef} className="vlibras-container" />
<div className="controls">
<button onClick={handleTranslate} disabled={!isReady}>
📝 Traduzir Texto
</button>
<button onClick={() => play()} disabled={!isReady}>
▶️ Play
</button>
<button onClick={pause} disabled={!isReady}>
⏸️ Pause
</button>
<button onClick={stop} disabled={!isReady}>
⏹️ Stop
</button>
<button onClick={() => setSpeed(1.5)} disabled={!isReady}>
⚡ Velocidade 1.5x
</button>
</div>
<div className="status">
<p><strong>Status:</strong> {status}</p>
<p><strong>Player Status:</strong> {player.status}</p>
<p><strong>Carregado:</strong> {player.loaded ? 'Sim' : 'Não'}</p>
<p><strong>Pronto:</strong> {isReady ? 'Sim' : 'Não'}</p>
<p><strong>Carregando:</strong> {isLoading ? 'Sim' : 'Não'}</p>
{translatedText && <p><strong>Último texto:</strong> {translatedText}</p>}
{error && <p style={{ color: 'red' }}><strong>Erro:</strong> {error}</p>}
</div>
</div>
);
}Conexão Manual Avançada
'use client';
import { useRef, useEffect, useState } from 'react';
import { useVLibrasPlayer } from 'vlibras-player-nextjs';
export default function ManualConnectionExample() {
const [selectedContainer, setSelectedContainer] = useState<string>('container1');
const container1Ref = useRef<HTMLDivElement>(null);
const container2Ref = useRef<HTMLDivElement>(null);
const { connect, translate, isReady } = useVLibrasPlayer({
autoInit: true,
// Sem containerRef para conexão manual
});
const handleContainerChange = (containerId: string) => {
setSelectedContainer(containerId);
const container = containerId === 'container1'
? container1Ref.current
: container2Ref.current;
if (container) {
connect(container);
}
};
return (
<div>
<div className="container-selection">
<button onClick={() => handleContainerChange('container1')}>
Conectar ao Container 1
</button>
<button onClick={() => handleContainerChange('container2')}>
Conectar ao Container 2
</button>
</div>
<div className="containers">
<div
ref={container1Ref}
className={`vlibras-container ${selectedContainer === 'container1' ? 'active' : ''}`}
style={{ border: selectedContainer === 'container1' ? '2px solid blue' : '1px solid gray' }}
/>
<div
ref={container2Ref}
className={`vlibras-container ${selectedContainer === 'container2' ? 'active' : ''}`}
style={{ border: selectedContainer === 'container2' ? '2px solid blue' : '1px solid gray' }}
/>
</div>
<button onClick={() => translate("Olá!")} disabled={!isReady}>
Traduzir no Container Ativo
</button>
</div>
);
}⚙️ Configuração
Next.js (next.config.js)
/** @type {import('next').NextConfig} */
const nextConfig = {
// Configurações para WebGL/Unity
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
};
return config;
},
// Headers para WebGL
async headers() {
return [
{
source: '/vlibras/target/:path*',
headers: [
{
key: 'Cross-Origin-Embedder-Policy',
value: 'require-corp',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
],
},
];
},
};
module.exports = nextConfig;Estrutura de Arquivos
public/
vlibras/
target/
playerweb.data.unityweb
playerweb.json
playerweb.wasm.code.unityweb
playerweb.wasm.framework.unityweb
UnityLoader.jsOs arquivos Unity são incluídos automaticamente na biblioteca, mas você pode substituí-los colocando os arquivos na pasta public/vlibras/target/.
🔄 Migração
De v2.1.0 para v2.1.1
A v2.1.1 é 100% retrocompatível e resolve automaticamente o problema de duplicação:
✅ Sem Mudanças Necessárias
// Seu código existente continua funcionando perfeitamente
const { translate, isReady } = useVLibrasPlayer({
autoInit: true,
containerRef
});
// ✅ Agora SEM duplicação de containers automático!🚀 Benefícios Automáticos da v2.1.1:
- Performance melhorada: Sem containers duplicados
- Menos uso de memória: Cleanup automático de recursos
- Estabilidade: Comportamento consistente em re-renders
- React StrictMode: Funciona perfeitamente com modo estrito
De v2.0.0 para v2.1.1
Migração recomendada em duas etapas:
✅ Código Recomendado (v2.1.1)
const { translate, isReady } = useVLibrasPlayer({
autoInit: true,
containerRef // Conexão automática + sem duplicação
});
// ✅ API moderna sem problemas de performance❌ Código Antigo (ainda funciona, mas não recomendado)
const { player, translate } = useVLibrasPlayer({ autoInit: true });
useEffect(() => {
if (containerRef.current && player) {
// Conexão manual ainda funciona, mas é desnecessária
player.load?.(containerRef.current);
}
}, [player]);Do VLibras Original
Se você está migrando do VLibras original, a integração é simples:
Antes (VLibras Original)
<div vw class="enabled">
<div vw-access-button class="active"></div>
<div vw-plugin-wrapper>
<div class="vw-plugin-top-wrapper"></div>
</div>
</div>
<script src="https://vlibras.gov.br/app/vlibras-plugin.js"></script>
<script>
new window.VLibras.Widget('https://vlibras.gov.br/app');
</script>Depois (vlibras-player-nextjs)
import { useVLibrasPlayer } from 'vlibras-player-nextjs';
const { translate } = useVLibrasPlayer({
autoInit: true,
containerRef
});Arquivos Unity (public/vlibras/target/)
Coloque os arquivos Unity WebGL no diretório público:
public/
└── vlibras/
└── target/
├── UnityLoader.js
├── playerweb.json
├── playerweb.data.unityweb
├── playerweb.wasm.code.unityweb
└── playerweb.wasm.framework.unityweb❓ FAQ
Hook vs Classe: Qual usar?
Hook (Recomendado): Use para integração simples em componentes React
const { translate, isReady } = useVLibrasPlayer({ autoInit: true, containerRef });Classe: Use para controle avançado ou integração com frameworks não-React
const player = new VLibrasPlayer(options);
player.load(container);Como corrigir "Player não inicializado"?
v2.1.0+: Use containerRef para conexão automática
const containerRef = useRef<HTMLDivElement>(null);
const { translate } = useVLibrasPlayer({ autoInit: true, containerRef });Arquivos Unity não carregam?
- Verifique se os arquivos estão em
public/vlibras/target/ - Configure os headers CORS no
next.config.js - Use
targetPath: '/vlibras/target'nas opções
Como personalizar o avatar?
const { changeAvatar } = useVLibrasPlayer({ autoInit: true, containerRef });
// Trocar para avatar feminino
changeAvatar('anya');
// Trocar para avatar masculino
changeAvatar('icaro');Funciona com SSR/SSG?
Sim! Use 'use client' no componente que usa o VLibras:
'use client';
import { useVLibrasPlayer } from 'vlibras-player-nextjs';🎯 Compatibilidade
- ✅ Next.js 13+ (App Router e Pages Router)
- ✅ React 18+
- ✅ TypeScript 5+
- ✅ Node.js 16+
- ✅ Navegadores modernos (Chrome 80+, Firefox 74+, Safari 13+)
- ✅ SSR/SSG com Next.js
- ✅ Webpack 5+
- ✅ Vite 4+
📊 Performance
- 📦 Tamanho do bundle: ~14MB (inclui arquivos Unity WebGL)
- ⚡ Carregamento inicial: ~2-3s (dependendo da conexão)
- 🔄 Tradução: ~500ms-1s por frase
- 💾 Uso de memória: ~50-100MB durante reprodução
🛠️ Desenvolvimento
# Clonar repositório
git clone https://github.com/Luca-Sousa/vlibras-player-web-nextjs.git
# Instalar dependências
npm install
# Desenvolvimento
npm run dev
# Build
npm run build
# Testes
npm run test
# Verificação de tipos
npm run type-check📄 Licença
Este projeto está licenciado sob a LGPL v3.0 - veja o arquivo LICENSE para detalhes.
O VLibras é uma tecnologia desenvolvida pelo Governo Federal do Brasil.
🤝 Contribuição
Contribuições são bem-vindas! Por favor, leia nosso guia de contribuição antes de submeter um PR.
Como contribuir:
- 🍴 Fork o projeto
- 🌟 Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - 💾 Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - 📤 Push para a branch (
git push origin feature/AmazingFeature) - 🔀 Abra um Pull Request
📞 Suporte
- 📋 Issues: GitHub Issues
- 📧 Email: contato
- 📱 NPM: vlibras-player-nextjs
🙏 Agradecimentos
- VLibras - Tecnologia original
- Unity Technologies - WebGL Runtime
- Next.js Team - Framework
- React Team - Biblioteca
vlibras-player-nextjs v2.1.1 - Acessibilidade em Libras para React e Next.js 🤟
<div className="flex gap-2">
<button
onClick={handleTranslate}
disabled={isTranslating || !text.trim()}
className="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50"
>
{isTranslating ? 'Traduzindo...' : 'Traduzir'}
</button>
<button
onClick={() => playerRef.current?.play()}
className="bg-green-500 text-white px-4 py-2 rounded"
>
Play
</button>
<button
onClick={() => playerRef.current?.pause()}
className="bg-yellow-500 text-white px-4 py-2 rounded"
>
Pause
</button>
<button
onClick={() => playerRef.current?.stop()}
className="bg-red-500 text-white px-4 py-2 rounded"
>
Stop
</button>
</div>
</div>
</div>); }
## 🤝 Contribuindo
Contribuições são bem-vindas! Por favor, leia nosso [guia de contribuição](CONTRIBUTING.md) para mais detalhes.
## 📄 Licença
Este projeto está licenciado sob a [LGPL-3.0](LICENSE) - veja o arquivo LICENSE para detalhes.
## 👥 Créditos
- **Equipe VLibras Original:** Criadores da tecnologia base
- **Comunidade Next.js:** Inspiração e melhores práticas
- **Contribuidores:** Todos que ajudaram a modernizar esta biblioteca
---
<div align="center">
<p>Feito com ❤️ para democratizar o acesso à Libras na web</p>
</div>