DEV Community

mmyoji
mmyoji

Posted on

Video Processing with AWS Lambda + Elastic Transcoder in Golang

I'm posting this because I could not find any blog posts with sample code for video processing with AWS Lambda + AWS Elastic Transcoder in Golang.

Dependencies

Premises

Flow of the operations

  1. Upload a video file in a S3 bucket
  2. Lambda is trigger by 1. and create a Elastic Transcoder Job

That's it.

Implementation

Create a Lambda function

  • Runtime: Go 1.x
  • Set an appropriate Role (Elastic Transcoder access is required)
  • Set a handler name as the same with the Go binary after go build
  • Set a trigger as S3 and choose the Pipeline's input bucket name and event type ObjectCreated
  • Set your PIPELINE_ID environment variable

Go code

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "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"
    transcoder "github.com/aws/aws-sdk-go/service/elastictranscoder"
)

var (
    // Generic 720p
    presetID = "1351620000001-000010"
)

func main() {
    lambda.Start(handler)
}

func handler(ctx context.Context, s3Event events.S3Event) {
    for _, record := range s3Event.Records {
        s3 := record.S3
        bucket := s3.Bucket.Name
        objKey := s3.Object.Key
        log.Printf("[%s - %s] Bucket = %s, Key = %s \n", record.EventSource, record.EventTime, bucket, objKey)

        sess := session.Must(
            session.NewSession(
                &aws.Config{
                    // Set supported region
                    Region: aws.String("ap-northeast-1"),
                },
            ),
        )

        svc := transcoder.New(sess)

        resp, err := svc.CreateJob(
            &transcoder.CreateJobInput{
                Input: &transcoder.JobInput{
                    Key: aws.String(objKey),
                },
                Outputs: []*transcoder.CreateJobOutput{
                    &transcoder.CreateJobOutput{
                        PresetId:         aws.String(presetID),
                        Key:              aws.String(objKey),
                        // If the original filename is "test-file.mp4",
                        // this generates "test-file.mp4-00001.png"
                        ThumbnailPattern: aws.String(fmt.Sprintf("%s-{count}", objKey)),
                    },
                },
                PipelineId: aws.String(os.Getenv("PIPELINE_ID")),
            },
        )
        if err != nil {
            log.Printf("Failed: Create Job, %v\n", err)
            return
        }

        log.Printf("Job Response: %v\n", resp.Job)
    }
}
Enter fullscreen mode Exit fullscreen mode

The structs options are at minimum, but you can set CreateJobOutput.ThumbnailPattern as "" if you don't want to generate thumbnails.

ThumbnailPattern must contain {count}.

aws.String(str) is the same with &str, you can use this as a shorthand.

strPtr := aws.String("somestring")

// the same with above, but you need to set a variable first.
str := "somestring"
strPtr := &str
Enter fullscreen mode Exit fullscreen mode

References

Top comments (4)

Collapse
 
ben profile image
Ben Halpern

@maestromac this might come in handy

Collapse
 
maestromac profile image
Mac Siri

Nice! I like how simple and straight forward your post is. Thank you for sharing!

Collapse
 
mmyoji profile image
mmyoji

Thank you! I hope this will help you :)

Collapse
 
umertauheedkhan profile image
umertauheedkhan

i want to add intervals between thumbnails. How can i do that with 'ThumbnailPattern' field ???... Or is there another way to do it ??