Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 17, 2023 06:03 pm GMT

GO - Funo Lambda para converter audio a partir do S3(AWS) - ffmpeg

Atuei em um projeto pessoal, onde necessitei fazer a converso de um arquivo wav(audio de qualidade maxima, sem compresso) para mp3.

Neste post, vou demonstrar o passo a passo, como fazer de forma "assncrona", a partir de um upload para um bucket no S3(servio de armazenamento de arquivos) da AWS.

No desenho abaixo, segue um contexto do que ser feito e explicado neste post:

Image description

Criando Buckets

Em seu console da AWS, v at o service S3, crie 2 novos buckets. O primeiro bucket, ser o destino do upload do arquivo de udio "bruto", no format .wav. O segundo, ser para o arquivo comprimido e convertido para .mp3. No meu caso, usei estes nomes:

Image description

Criando Lambda

Sim, vamos j proceder na criao da funo lambda que ser responsvel por converter os arquivos de audio bruto, para formado de audio compactado. Para isso, em seu AWS Console, na busca procuro por Lambda. Clique em Create Function

Vamos utilizar a linguagem GO, conforme a tela abaixo:

Image description

Permisses de acesso Lambda - S3

Ser necessrio a criao de uma Police, e atrel-la a Role criada na criao da lambda.

Para isso acessaremos o console do IAM, sem seguida vamos ao menu Polices > Add Police. Mudaremos o modo para JSON, e vamos inserir o cdigo a seguir:

{    "Version": "2012-10-17",    "Statement": [        {            "Sid": "VisualEditor0",            "Effect": "Allow",            "Action": [                "logs:CreateLogStream",                "logs:CreateLogGroup",                "logs:PutLogEvents"            ],            "Resource": "*"        },        {            "Sid": "VisualEditor1",            "Effect": "Allow",            "Action": "s3:GetObject",            "Resource": "arn:aws:s3:::mgm-wav-files/*"        },        {            "Sid": "VisualEditor2",            "Effect": "Allow",            "Action": "s3:PutObject",            "Resource": "arn:aws:s3:::mgm-mp3-files/*"        }    ]}

A poltica acima d permisso de leitura no bucket de arquivos wav e escrita no bucket para arquivos mp3, convertidos. Vamos salvar essa Police.

No console do IAM, vamos ao menu Roles, vamos selecionar a Role criada para a lambda. Em seguida, vamos em Add Permissions > atacch policies. Na buscar, buscar pelo nome da poltica criada e salvar.

Run time Lambda. O que isso?

As funes lambda, na linguagem Go(entre outras), rodam em um contexto de ambiente Linux, no caso da distribuio AWS Linux. Nesse contexto, precisamos "carregar" uma lib, que ser a responsvel por fazer a converso de udio.

Essa lib o FFMPEG. Que trata de vrios formatos de mdias, audio, video.

Para isso, utilizaremos uma feature das funes lambda na AWS, chamada Layer, traduzindo: camada

Com uma layer, conseguimos rodar algumas libs em tempo de execuo de uma ou mais funes lambda. Como?

Criando Layer FFMPEG

Vamos baixar os binrios desta lib em nossa mquina local, e transferir apenas o necessrio para um arquivo ZIP, que ser inserido em um Lambda Layer.

Para isso, vou utilizar o exemplo abaixo, de ambiente Linux/MacOS:

wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xzwget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz.md5md5sum -c ffmpeg-release-amd64-static.tar.xz.md5tar xvf ffmpeg-release-amd64-static.tar.xz

Aps o download e descompactar o arquivo, vamos criar uma nova basta, para copiar o conteudo do binario do ffmpeg, e zipar o contedo:

mkdir -p ffmpeg/bincp ffmpeg-4.3.1-amd64-static/ffmpeg ffmpeg/bin/cd ffmpegzip -r ../ffmpeg.zip .

Agora, vamos criar uma nova Layer em nosso ambiente de Lambdas na AWS, anexando o arquivo zip criado no passo acima como no exemplo a seguir:

Image description

Anexando Layer FFMPEG a nossa funo Lambda

Vamos voltar ao menu Functions dentro de Lambda em nosso Console. Na aba code vamos descer a tela, e ir at a sesso Layers e clicar em Add Layer. Vamos preencher e selecionar o formulrio, como na imagem abaixo

Image description

E (FINALMENT) vamos ao nosso cdigo!

Para a linguagem Go, no temos um editor online em funes lambda na AWS. Por isso, vamos gerar nosso cdigo localmente, build-lo e subir um zip do mesmo via console.

Incio de tudo

package mainfunc main() {}

Em nosso ambiente local de desenvolvimento em Go, vamos criar uma nova pasta. Nesta pasta, iniciaremos o projeto com o famoso comando "go mod" para criar nosso arquivo de controle de mdulos go do Projeto.

Aps, iremos criar o arquivo main.go com o seguinte contedo:

package mainimport "github.com/aws/aws-lambda-go/lambda"func handler()  {}func main() {    lambda.Start(handler)}

Acima, importamos a biblioteca oficial lambda, para utilizao em Go. Criamos uma funo chamada handler onde vamos inserir nossa futura estrutura de converso de udio, e abaixo a funo main, apenas executa a funo handler em ambiente de execuo do Lambda.

Agora vamos carregar a biblioteca oficial do s3, para conectar no bucket que ir iniciar a funo(essa informao importante, pois o start traz informaes do bucket para a lambda). Em seguida, vamos criar um diretrio temporrio, dentro do ambiente de execuo da lambda, para fazer download do arquivo, onde possa ser manipulado. Em seguida realizar o download, utilizando um log para verificar:

package mainimport (    "context"    "fmt"    "github.com/aws/aws-lambda-go/events"    "github.com/aws/aws-lambda-go/lambda"    "github.com/aws/aws-sdk-go/aws"    "github.com/aws/aws-sdk-go/aws/session"    "github.com/aws/aws-sdk-go/service/s3"    "github.com/aws/aws-sdk-go/service/s3/s3manager"    "log"    "os")func handler(_ context.Context, s3Event events.S3Event) {    record := s3Event.Records[0]    key := record.S3.Object.Key    sess, _ := session.NewSession(&aws.Config{Region: &record.AWSRegion})    downloader := s3manager.NewDownloader(sess)    file, err := os.Create(fmt.Sprintf("/tmp/%s", key))    if err != nil {        panic(err)    }    defer file.Close()    _, err = downloader.Download(file,        &s3.GetObjectInput{            Bucket: &record.S3.Bucket.Name,            Key:    &key,        })    if err != nil {        panic(err)    }    log.Printf("Downloaded %s", file.Name())}func main() {    lambda.Start(handler)}

Nossa funo handler, recebe 2 parmetros vindos de Context e events, libs da AWS que trazem informaes a respeito do bucket que inicia a lambda.
Neste ponto, interessante que faamos o primeiro upload do cdigo buildado, para realizar um teste "manual". Primeiro vamos criar o build dessa aplicao com o comando:

go build -o main

Em seguida, vamos empacotar o arquivo em um arquivo zip, para realizar o upload:

zip main.zip main

Agora vamos ao console, realizar o upload:

Image description

Criando Trigger

Antes de testarmos o cdigo, precisamos criar a trigger ou gatilho, que dar inicio a lambda que criamos.

Dentro da nossa funo, no console AWS vamos clicar em Add Trigger.

Vamos preencher o formulrio, conforme as 3 imagens abaixo:

Image description

Neste ponto, vamos selecionar o bucket dos arquivos brutos:
Image description

Em seguida selecionar todos os tipos de entrada de arquivos
Image description

Por final, vamos deixar um filtro para somente iniciar a lambda, para arquivos .wav
Image description

Primeiro teste

Agora, vamos ao nosso bucket, fazer um upload de arquivo .wav, e verificar o status no CloudWatch, e posteriormente verificar se o arquivo mp3 foi criado no outro bucket.

Image description

Acima vemos os 2 buckets utilizados em nosso projeto. Vamos acessar o mgm-wav-files para realizar o upload. Aps o upload, vamos acessar o CloudWatch, ir ao meno Logs > Logs Groups. L haver um grupo de log, com nome de nossa Lambda. Em nosso casso est assim:

Image description

Entrando em nosso log, vamos procurar se h a mensagem "Downloaded NOMEDOARQUIVO", como a seguir:

Image description

Neste caso, tudo certo, vamos continuar!

Convertando arquivo .wav com FFMPEG

Vamos utilizar a funciona a lib nativa Go OS, para utilizar a funo exec.Command, que nos possibilita rodar comandos em nvel de bash. E a partir dele, usar o ffmpeg para convertar o arquivo .wav para .mp3, gravando-o no diretrio temporrio criado anteriormente:

outputFile := strings.Replace(file.Name(), filepath.Ext(file.Name()), ".mp3", 1)    cmd := exec.Command("ffmpeg", "-i", file.Name(), outputFile)    out, err := cmd.CombinedOutput()    if err != nil {        log.Fatalf("cmd.Run() failed with %s
", err) } log.Printf("Execution output:
%s
", string(out)) output, err := os.Open(outputFile) if err != nil { panic(err) }

Gravando arquivo convertido em outro bucket

Agora, vamos acessar o arquivo criado, e fazer o upload para o bucket criado, apenas para receber os arquivos convertidos. O cdigo exemplo, existe na documentao da AWS:

//put mp3 file in converted bucket    destinationBucket := "mgm-mp3-files"    _, err = s3.New(sess).PutObject(&s3.PutObjectInput{        Bucket: &destinationBucket,        Key:    aws.String(filepath.Base(outputFile)),        Body:   output,    })    log.Printf("Copied %s to %s", outputFile, record.S3.Bucket.Name)

Cdigo Final

package mainimport (    "context"    "fmt"    "github.com/aws/aws-lambda-go/events"    "github.com/aws/aws-lambda-go/lambda"    "github.com/aws/aws-sdk-go/aws"    "github.com/aws/aws-sdk-go/aws/session"    "github.com/aws/aws-sdk-go/service/s3"    "github.com/aws/aws-sdk-go/service/s3/s3manager"    "log"    "os"    "os/exec"    "path/filepath"    "strings")func handler(_ context.Context, s3Event events.S3Event) {    record := s3Event.Records[0]    key := record.S3.Object.Key    sess, _ := session.NewSession(&aws.Config{Region: &record.AWSRegion})    //Download file to a temporary folder    downloader := s3manager.NewDownloader(sess)    file, err := os.Create(fmt.Sprintf("/tmp/%s", key))    if err != nil {        panic(err)    }    defer file.Close()    _, err = downloader.Download(file,        &s3.GetObjectInput{            Bucket: &record.S3.Bucket.Name,            Key:    &key,        })    if err != nil {        panic(err)    }    log.Printf("Downloaded %s", file.Name())    //transform wav file to a compress mp3 file    outputFile := strings.Replace(file.Name(), filepath.Ext(file.Name()), ".mp3", 1)    cmd := exec.Command("ffmpeg", "-i", file.Name(), outputFile)    out, err := cmd.CombinedOutput()    if err != nil {        log.Fatalf("cmd.Run() failed with %s
", err) } log.Printf("Execution output:
%s
", string(out)) output, err := os.Open(outputFile) if err != nil { panic(err) } //put mp3 file in converted bucket destinationBucket := "mgm-mp3-files" _, err = s3.New(sess).PutObject(&s3.PutObjectInput{ Bucket: &destinationBucket, Key: aws.String(filepath.Base(outputFile)), Body: output, }) log.Printf("Copied %s to %s", outputFile, record.S3.Bucket.Name)}func main() { lambda.Start(handler)}

PLUS - Mensagem assncrona de fim da atividade

Por final, vamos fazer com que, ao final da execuo do lambda, em caso de sucesso uma fila SQS seja abastecida com uma mensagem, para que consumidores(aplicativos, web, etc..) possam ser avisados do final do processo e disponibilizao do arquivo mp3 convertido.

Vamos agora ao console AWS, procurar por SQS. O servio simples de fila da prpria Amazon. Vamos criar um tpico, chamado mp3-ready

Image description

Agora, voltando a nossa funo lambda, vamos acessar o menu Add Destination.

Image description

Nosso formulrio deve ser preenchido destga maneira, escolhendo a fila SQS criada(A mensagem de falta de permisso para uso do SQS pelo lambda, ser solucionada no prximo passo)

Image description

Agora com nosso destino de lambda criado, precisamos dar permisso no IAM para nossa role de execuo da lambda, criar mensagem no tpico criado no SQS

Image description

Permisso lambda > SQS

No console do IAM, clicar no menu ROLES. Procurar pela role criada para a lambda. Dentro dessa role, vamos no menu Add Permissions > Atacch polices. Na busca, procurar por SQS, e escolher AmazonSQSFullAccess(sabemos que no o ideal rs.) e clicar em Add Permissions.


Original Link: https://dev.to/markgerald/go-lambda-para-converter-audio-a-partir-do-s3aws-ffmpeg-10jp

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To