Video Processing with AWS Lambda + Elastic Transcoder in Golang
Tags: aws, go
Published: 2018-03-07 10:11:46

---
title: Video Processing with AWS Lambda + Elastic Transcoder in Golang
published: true
description: 
tags: aws,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

* Golang v1.10
* [aws/aws-lambda-go](https://github.com/aws/aws-lambda-go) v1.1.0
* [aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) v1.13.8


## Premises

* You know [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) and [Elastic Transcoder](https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/introduction.html) roughly
* You've already have a [Elastic Transcoder Pipeline](https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/working-with-pipelines.html)
* You know Golang a little and like it :)


## Flow of the operations

1. Upload a video file in a S3 bucket
1. Lambda is trigger by 1. and create a [Elastic Transcoder Job](https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/working-with-jobs.html)

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

```go
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)
	}
}
```

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.


```go
strPtr := aws.String("somestring")

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


## References

* [elastictranscoder - Amazon Web Services - Go SDK](https://docs.aws.amazon.com/sdk-for-go/api/service/elastictranscoder/)
* [Settings that You Specify When You Create an Elastic Transcoder Job - Amazon Elastic Transcoder](https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/job-settings.html)
* [System Presets - Amazon Elastic Transcoder](https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/system-presets.html)
* [Amazon Elastic Transcoderでサムネイル画像を作成してみた ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/amazon-elastic-transcoder-thumbnail/) (JP)