Uma biblioteca Node.js moderna e completa para criação e gerenciamento de playlists de arquivos de mídia locais com interface CLI robusta.
- 🎯 Geração automática de playlists a partir de diretórios locais
- 📁 Suporte a múltiplos formatos de áudio e vídeo (.mp3, .wav, .mp4, .mkv, etc.)
- 🎨 Capas personalizadas para playlists
- 📊 Extração de metadados (título, artista, duração, etc.)
- 💾 Exportação em múltiplos formatos (JSON, M3U, M3U8)
- 🔄 Reordenação de itens da playlist
- 🛡️ Type-safe com TypeScript
- 🖥️ Interface de linha de comando (CLI)
- ⚡ Performance otimizada com busca recursiva
npm install upload-playlista
npm install -g upload-playlista
import { createPlaylistManager, scanDirectory } from 'upload-playlista';
// Criar gerenciador de playlists
const manager = await createPlaylistManager();
// Criar uma nova playlist
const playlist = await manager.createPlaylist({
name: 'Minha Playlist',
description: 'Minhas músicas favoritas'
});
// Adicionar arquivos
await manager.addToPlaylist('Minha Playlist', '/caminho/para/musica.mp3');
// Definir capa
await manager.setPlaylistCover('Minha Playlist', '/caminho/para/capa.jpg');
// Exportar playlist
await manager.exportPlaylist('Minha Playlist', 'json', './playlist.json');
# Criar playlist
playlista create "Minha Playlist" -d "Minhas músicas favoritas"
# Adicionar arquivo
playlista add "Minha Playlist" "/caminho/para/musica.mp3"
# Listar playlists
playlista list
# Importar de diretório
playlista import "Rock Clássico" "/Music/Rock" -d "Coleção de rock clássico"
# Exportar playlist
playlista export "Minha Playlist" m3u "./playlist.m3u"
import { PlaylistManager } from 'upload-playlista';
const manager = new PlaylistManager({
storageDirectory: '/caminho/para/storage', // Diretório onde salvar playlists
autoSave: true, // Salvar automaticamente
compressionEnabled: false // Compressão de arquivos
});
await manager.initialize();
// Criar playlist
const playlist = await manager.createPlaylist({
name: 'Nome da Playlist',
description: 'Descrição opcional',
coverImage: '/caminho/para/capa.jpg' // opcional
});
// Adicionar arquivo
await manager.addToPlaylist('Nome da Playlist', '/caminho/arquivo.mp3');
// Remover arquivo
await manager.removeFromPlaylist('Nome da Playlist', '/caminho/arquivo.mp3');
// Reordenar itens
await manager.reorderPlaylist('Nome da Playlist', 0, 2); // mover item do índice 0 para 2
// Definir capa
await manager.setPlaylistCover('Nome da Playlist', '/caminho/capa.jpg');
// Obter playlist
const playlist = manager.getPlaylist('Nome da Playlist');
// Listar todas
const names = manager.listPlaylists();
const playlists = manager.getAllPlaylists();
// Excluir playlist
await manager.deletePlaylist('Nome da Playlist');
// Exportar
await manager.exportPlaylist('Nome da Playlist', 'json', './output.json');
await manager.exportPlaylist('Nome da Playlist', 'm3u', './output.m3u');
// Importar de diretório
const playlist = await manager.importFromDirectory(
'Nova Playlist',
'/caminho/diretorio',
'Descrição opcional'
);
// 🆕 NOVOS MÉTODOS: Obter tracks como arrays
const allTracks = manager.getPlaylistTracks('Nome da Playlist');
const audioTracks = manager.getPlaylistAudioTracks('Nome da Playlist');
const videoTracks = manager.getPlaylistVideoTracks('Nome da Playlist');
const simplifiedTracks = manager.getPlaylistTracksSimplified('Nome da Playlist');
import { FileScanner } from 'upload-playlista';
// Escanear diretório
const mediaFiles = await FileScanner.scanDirectory('/caminho/diretorio', {
recursive: true, // Busca recursiva
includeHidden: false, // Incluir arquivos ocultos
maxDepth: 10, // Profundidade máxima
includeFormats: ['.mp3', '.mp4'] // Formatos específicos
});
// Extrair metadados de arquivo único
const metadata = await FileScanner.extractMetadata('/arquivo.mp3');
// Verificar se formato é suportado
const isSupported = FileScanner.isSupportedFormat('.mp3');
// Obter formatos suportados
const formats = FileScanner.getSupportedFormats();
import {
createPlaylist,
addToPlaylist,
removeFromPlaylist,
deletePlaylist,
listPlaylists,
getPlaylist,
setPlaylistCover,
scanDirectory,
// 🆕 Novas funções para obter tracks
getPlaylistTracks,
getPlaylistAudioTracks,
getPlaylistVideoTracks,
getPlaylistTracksSimplified
} from 'upload-playlista';
// Todas as funções aceitam um parâmetro opcional storageDirectory
const playlist = await createPlaylist('Nome', 'Descrição', '/capa.jpg', '/storage');
// 🆕 Obter tracks diretamente
const tracks = await getPlaylistTracks('Minha Playlist');
const audioOnly = await getPlaylistAudioTracks('Minha Playlist');
const simplified = await getPlaylistTracksSimplified('Minha Playlist');
// Exemplo de uso dos tracks
tracks.forEach((track, index) => {
console.log(`${index + 1}. ${track.title || track.fileName}`);
console.log(` Artista: ${track.artist || 'Desconhecido'}`);
console.log(` Duração: ${Math.floor((track.duration || 0) / 60)}min`);
});
- .mp3, .wav, .flac, .aac, .ogg, .m4a, .wma
- .mp4, .mkv, .avi, .mov, .wmv, .flv, .webm
- .jpg, .jpeg, .png, .bmp, .gif, .webp
interface Playlist {
id: string;
name: string;
description?: string;
coverImage?: string;
items: PlaylistItem[];
createdAt: Date;
updatedAt: Date;
totalDuration: number;
totalFiles: number;
}
interface PlaylistItem {
id: string;
metadata: MediaMetadata;
order: number;
}
interface MediaMetadata {
fileName: string;
filePath: string;
fileSize: number;
duration?: number;
title?: string;
artist?: string;
album?: string;
year?: number;
genre?: string;
format: string;
bitrate?: number;
sampleRate?: number;
dateAdded: Date;
}
// 🆕 NOVO: Interface simplificada para tracks
interface TrackInfo {
title: string; // Título ou nome do arquivo
artist: string; // Artista ou "Artista Desconhecido"
album: string; // Álbum ou "Álbum Desconhecido"
filePath: string; // Caminho completo
duration: number; // Duração em segundos (0 se N/A)
format: string; // Extensão (.mp3, .wav, etc.)
}
# Criar playlist
playlista create <nome> [opções]
-d, --description <desc> Descrição da playlist
-c, --cover <path> Caminho para imagem de capa
-s, --storage <path> Diretório de armazenamento
# Adicionar arquivo
playlista add <playlist> <arquivo> [opções]
# Remover arquivo
playlista remove <playlist> <arquivo> [opções]
# Listar playlists
playlista list [opções]
-v, --verbose Exibir informações detalhadas
# Exibir playlist
playlista show <playlist> [opções]
# Excluir playlist
playlista delete <playlist> [opções]
-y, --yes Confirmar automaticamente
# Definir capa
playlista cover <playlist> <imagem> [opções]
# Exportar playlist
playlista export <playlist> <formato> <arquivo> [opções]
# Escanear diretório
playlista scan <diretório> [opções]
-r, --recursive Busca recursiva
-h, --hidden Incluir arquivos ocultos
-d, --depth <número> Profundidade máxima
-f, --formats <lista> Formatos específicos
# Importar de diretório
playlista import <nome> <diretório> [opções]
-d, --description <desc> Descrição da playlist
-r, --recursive Busca recursiva
# Instalar dependências
npm install
# Compilar TypeScript
npm run build
# Executar em modo desenvolvimento
npm run dev
# Executar testes
npm test
# Lint
npm run lint
# CLI em desenvolvimento
npm run cli -- create "Test Playlist"
import { createPlaylistManager } from 'upload-playlista';
async function exemplo() {
// Criar gerenciador
const manager = await createPlaylistManager('./minhas-playlists');
// Criar playlist
const playlist = await manager.createPlaylist({
name: 'Músicas para Trabalhar',
description: 'Playlist para concentração'
});
// Escanear diretório e adicionar arquivos
const playlist2 = await manager.importFromDirectory(
'Biblioteca Musical',
'/Users/usuario/Music'
);
// Definir capa
await manager.setPlaylistCover(
'Músicas para Trabalhar',
'/Users/usuario/Pictures/work-cover.jpg'
);
// Reordenar itens
await manager.reorderPlaylist('Biblioteca Musical', 0, 5);
// Exportar em diferentes formatos
await manager.exportPlaylist('Biblioteca Musical', 'json', './biblioteca.json');
await manager.exportPlaylist('Biblioteca Musical', 'm3u8', './biblioteca.m3u8');
// Listar todas as playlists
const playlists = manager.getAllPlaylists();
console.log(`Total de playlists: ${playlists.length}`);
playlists.forEach(p => {
console.log(`- ${p.name}: ${p.totalFiles} arquivos, ${Math.floor(p.totalDuration/60)} minutos`);
});
}
exemplo().catch(console.error);
const options = {
recursive: true, // Busca recursiva nos subdiretórios
includeHidden: false, // Incluir arquivos/pastas ocultos
maxDepth: 10, // Profundidade máxima da busca
includeFormats: ['.mp3', '.wav'] // Filtrar apenas formatos específicos
};
const files = await FileScanner.scanDirectory('/music', options);
const manager = new PlaylistManager({
storageDirectory: './playlists', // Onde salvar as playlists
autoSave: true, // Salvar automaticamente após mudanças
compressionEnabled: false // Comprimir arquivos JSON (futuro)
});
- [ ] Suporte a streaming de URLs
- [ ] Sincronização com serviços de música
- [ ] Interface web
- [ ] Plugins customizados
- [ ] Cache de metadados
- [ ] Suporte a bibliotecas remotas
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/nova-feature
) - Commit suas mudanças (
git commit -am 'Adiciona nova feature'
) - Push para a branch (
git push origin feature/nova-feature
) - Abra um Pull Request
MIT License - veja o arquivo LICENSE para detalhes.
- 📧 Email: suporte@exemplo.com
- 🐛 Issues: GitHub Issues
- 📖 Documentação: Wiki
Feito com ❤️ em TypeScript