Uma biblioteca multiplataforma Kotlin para manipulação de áudio e vídeo, disponível para Android e iOS.
Frigg é uma figura da mitologia nórdica, sendo a principal deusa, esposa de Odin e deusa do amor, casamento, maternidade e lar. Assim como Frigg cuida e protege o lar, esta biblioteca foi criada para fornecer ferramentas confiáveis e cuidadosas para a manipulação de mídia em suas aplicações multiplataforma.
Frigg é uma biblioteca Kotlin Multiplatform que oferece utilitários para manipulação de áudio e vídeo. Desenvolvida com foco em performance, confiabilidade e facilidade de uso, Frigg permite que você trabalhe com mídia de forma consistente em diferentes plataformas.
- ✅ Android (minSdk 24)
- ✅ iOS (arm64, x64, simulator)
- Kotlin Multiplatform: Código compartilhado entre plataformas
- LAME: Biblioteca nativa para codificação MP3
- Expect/Actual: Implementações específicas por plataforma
- Result API: Uso do padrão
Result<String>do Kotlin para tratamento de erros
- 🎵 Conversão WAV para MP3
- Suporte a bitrate configurável (padrão: 128 kbps)
- Validação robusta de arquivos de entrada
- Sistema de exceções tipadas para tratamento de erros
- Validação de formato PCM 16-bit
- Verificação de permissões e espaço em disco
- API moderna usando
Result<String>do Kotlin
- 🎬 Funcionalidades de manipulação de vídeo
- 🎚️ Mais formatos de áudio
- 🔧 Ferramentas adicionais de processamento
Adicione o repositório Maven Central no seu build.gradle.kts:
repositories {
mavenCentral()
}Adicione a dependência:
dependencies {
implementation("io.github.cardosofgui:frigg:1.1.0")
}repositories {
mavenCentral()
}
dependencies {
implementation 'io.github.cardosofgui:frigg:1.1.0'
}No Android, você precisa inicializar a biblioteca no Application ou Activity:
import android.app.Application
import com.br.frigg.FriggConverter
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
FriggConverter.initialize(this)
}
}import com.br.frigg.FriggConverter
suspend fun convertAudio() {
val converter = FriggConverter()
val wavPath = "/path/to/audio.wav"
val result = converter.convertWavToMp3(wavPath, bitrate = 128)
result.onSuccess { mp3Path ->
println("Conversão bem-sucedida! MP3 salvo em: $mp3Path")
}.onFailure { exception ->
println("Erro na conversão: ${exception.message}")
exception.printStackTrace()
}
}import com.br.frigg.FriggConverter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
fun convertAudioFile(wavPath: String) {
val converter = FriggConverter()
CoroutineScope(Dispatchers.IO).launch {
val result = converter.convertWavToMp3(
wavPath = wavPath,
bitrate = 192 // Qualidade maior
)
result.onSuccess { mp3Path ->
// Arquivo MP3 criado com sucesso
// Faça algo com o arquivo MP3
}.onFailure { exception ->
// Trate o erro
when (exception) {
is com.br.frigg.FileNotFoundException -> {
// Arquivo não encontrado
}
is com.br.frigg.InvalidFileException -> {
// Arquivo inválido ou corrompido
}
is com.br.frigg.StorageException -> {
// Espaço insuficiente em disco
}
else -> {
// Outros erros
}
}
}
}
}import com.br.frigg.FriggConverter
suspend fun convertWithFallback(wavPath: String): String {
val converter = FriggConverter()
return converter.convertWavToMp3(wavPath)
.getOrElse { exception ->
// Tratamento de erro personalizado
throw exception
}
}import com.br.frigg.FriggConverter
suspend fun convertWithFold(wavPath: String): String {
val converter = FriggConverter()
return converter.convertWavToMp3(wavPath).fold(
onSuccess = { mp3Path -> mp3Path },
onFailure = { exception ->
throw exception
}
)
}Frigg utiliza um sistema completo de exceções tipadas que permite tratamento específico de diferentes tipos de erros:
FriggException (classe base)
├── StorageException
├── WritePermissionException
├── InvalidFileException
├── FileNotFoundException
├── ReadPermissionException
├── DirectoryCreationException
├── NativeLibraryException
├── ConversionException
├── EmptyFileException
└── UnknownFriggExceptionimport com.br.frigg.*
import com.br.frigg.FriggConverter
suspend fun convertWithDetailedErrorHandling(wavPath: String) {
val converter = FriggConverter()
converter.convertWavToMp3(wavPath).onFailure { exception ->
when (exception) {
is FileNotFoundException -> {
println("Arquivo não encontrado: ${exception.filePath}")
}
is ReadPermissionException -> {
println("Sem permissão para ler: ${exception.filePath}")
}
is InvalidFileException -> {
println("Arquivo inválido: ${exception.filePath}")
println("Motivo: ${exception.reason}")
}
is StorageException -> {
println("Espaço insuficiente")
println("Disponível: ${exception.availableSpace} bytes")
println("Necessário: ${exception.requiredSpace} bytes")
}
is WritePermissionException -> {
println("Sem permissão para escrever em: ${exception.path}")
}
is DirectoryCreationException -> {
println("Erro ao criar diretório: ${exception.directoryPath}")
}
is NativeLibraryException -> {
println("Erro ao carregar biblioteca nativa: ${exception.libraryName}")
}
is ConversionException -> {
println("Erro na conversão")
println("WAV: ${exception.wavPath}")
println("MP3: ${exception.mp3Path}")
}
is EmptyFileException -> {
println("Arquivo MP3 vazio: ${exception.filePath}")
}
is UnknownFriggException -> {
println("Erro desconhecido: ${exception.message}")
exception.cause?.printStackTrace()
}
else -> {
println("Erro inesperado: ${exception.message}")
}
}
}
}Classe principal para conversão de áudio.
Converte um arquivo WAV para MP3.
Parâmetros:
wavPath: Caminho completo para o arquivo WAV de entradabitrate: Taxa de bits do MP3 de saída (padrão: 128 kbps)
Retorno:
Result.success(mp3Path: String): Conversão bem-sucedida, retorna o caminho do arquivo MP3 criadoResult.failure(exception: FriggException): Erro na conversão, contém uma exceção tipada
Requisitos do arquivo WAV:
- Formato: PCM 16-bit
- Extensão:
.wav - Arquivo válido e legível
Android:
- Método estático
initialize(context: Context)deve ser chamado antes do uso
Classe base para todas as exceções do módulo Frigg.
open class FriggException(
message: String,
cause: Throwable? = null
) : Exception(message, cause)Lançada quando não há espaço suficiente em disco.
open class StorageException(
message: String,
val availableSpace: Long,
val requiredSpace: Long,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando não há permissão para escrever no diretório de destino.
open class WritePermissionException(
message: String,
val path: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando o arquivo WAV é inválido, corrompido ou em formato não suportado.
open class InvalidFileException(
message: String,
val filePath: String,
val reason: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando o arquivo WAV não foi encontrado.
open class FileNotFoundException(
message: String,
val filePath: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando não há permissão para ler o arquivo WAV.
open class ReadPermissionException(
message: String,
val filePath: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando não é possível criar o diretório de saída.
open class DirectoryCreationException(
message: String,
val directoryPath: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando há erro ao carregar a biblioteca nativa.
open class NativeLibraryException(
message: String,
val libraryName: String? = null,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando a conversão nativa falha.
open class ConversionException(
message: String,
val wavPath: String,
val mp3Path: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada quando o arquivo MP3 foi criado mas está vazio ou não foi criado.
open class EmptyFileException(
message: String,
val filePath: String,
cause: Throwable? = null
) : FriggException(message, cause)Lançada para erros não mapeados.
open class UnknownFriggException(
message: String,
override val cause: Throwable
) : FriggException(message, cause)- minSdk: 24 (Android 7.0)
- compileSdk: 36
- Kotlin: 2.2.20+
- iOS 13.0+
- Suporta dispositivos físicos (arm64) e simuladores (x64, arm64)
- Versão mínima: 2.2.20
Frigg utiliza a arquitetura expect/actual do Kotlin Multiplatform:
frigg/
├── src/
│ ├── commonMain/ # Código compartilhado
│ │ └── kotlin/
│ │ └── com/br/frigg/
│ │ ├── FriggConverter.kt # expect class
│ │ └── FriggException.kt # Sistema de exceções
│ ├── androidMain/ # Implementação Android
│ │ └── kotlin/
│ │ └── com/br/frigg/
│ │ └── FriggConverter.android.kt # actual class
│ └── iosMain/ # Implementação iOS
│ └── kotlin/
│ └── com/br/frigg/
│ └── FriggConverter.ios.kt # actual class
Este projeto está licenciado sob a Licença GPL-2.0 - veja o arquivo LICENSE para detalhes.
Contribuições são bem-vindas! Sinta-se à vontade para:
- Abrir uma issue para reportar bugs ou sugerir funcionalidades
- Fazer um fork do repositório
- Criar uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Fazer commit das suas mudanças (
git commit -m 'Add some AmazingFeature') - Fazer push para a branch (
git push origin feature/AmazingFeature) - Abrir um Pull Request
Guilherme Cardoso
- GitHub: @CardosofGui
- Projeto: https://github.com/CardosofGui/frigg
Feito com ❤️ usando Kotlin Multiplatform