Slide 1

Slide 1 text

Open Source HTTP API for Media Encoding Snickers GoLab 2017. Florence, Italy

Slide 2

Slide 2 text

/flavioribeiro /flavioribeiro flavioribeiro.com senior engineer @ the new york times

Slide 3

Slide 3 text

context

Slide 4

Slide 4 text

context motivation

Slide 5

Slide 5 text

context motivation how it works?

Slide 6

Slide 6 text

context motivation how it works? future

Slide 7

Slide 7 text

context

Slide 8

Slide 8 text

context media factory client acquistion API media factory API transcoding API distribution API CDN Storage database http://nyt.ms/mediafactory

Slide 9

Slide 9 text

transcoding api transcoding API http://github.com/nytimes/video-transcoding-api

Slide 10

Slide 10 text

{      "providers":  ["elastictranscoder",  "elementalconductor",  "encodingcom",  "zencoder"],
    "preset":  {
        "name":  "sample_preset",
        "description":  "This  is  an  example  preset",
        "container":  "mp4",
        "rateControl":  "VBR",
        "video":  {                  "profile":  "Main",  "profileLevel":  "3.1",
                "height":  "720",  "width":  "1080",
                "codec":  "h264",  "bitrate":  "1000000",
                "gopSize":  "90",  "gopMode":  "fixed",
                "interlaceMode":  "progressive"
        },
        "audio":  {
                "codec":  "aac",
                "bitrate":  "64000"
        }
 } transcoding api - presets

Slide 11

Slide 11 text

transcoding api - jobs {      "provider":  "elastictranscoder",
    "source":  “ftp://nytimes:isg00d@ftp.nytimes.com/folder/my_video_source.mov”,      “destination”:  “ftp://nytimes:isg00d@ftp.nytimes.com/outputs”,
    "outputs":  [
        {"preset":  "720p_mp4",  "fileName":  "my_video_720p.mp4"},
        {"preset":  "1080p_mp4",  "fileName":  "my_video_1080p.mp4"},
        {"preset":  "256p_hls",  "fileName":  "hls/my_video_480p.m3u8"},
        {"preset":  "480p_hls",  "fileName":  "hls/my_video_480p.m3u8"},
        {"preset":  "720p_hls",  "fileName":  "hls/my_video_720p.m3u8"},
        {"preset":  "1080p_hls",  "fileName":  "hls/my_video_1080p.m3u8"},
        {"preset":  "2160p_hls",  "fileName":  "hls/my_video_2160p.m3u8"}
    ],      "streamingParams":  {
        "segmentDuration":  5,
        "protocol":  "hls"
    }
 }  

Slide 12

Slide 12 text

• old system worked well for ~10 years, not anymore • new system is a set of microservices in Go • fast encoding, scalability, reliability • transcoding API is a wrapper for encoding services • presets, encoding jobs context recap

Slide 13

Slide 13 text

motivation

Slide 14

Slide 14 text

motivation • team fluent in Go — except me

Slide 15

Slide 15 text

motivation • team fluent in Go — except me • I wanted to test different approaches

Slide 16

Slide 16 text

motivation • team fluent in Go — except me • I wanted to test different approaches • What if I create another encoding service in Go?

Slide 17

Slide 17 text

• open source alternative to encoding providers • deploy & run everywhere • add features any time • compatible with transcoding api jobs and presets What if I create another encoding service in Go?

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

how it works?

Slide 20

Slide 20 text

RESTful API how it works?

Slide 21

Slide 21 text

var  Routes  =  map[Route]RouterArguments{      //Job  routes      CreateJob:          RouterArguments{Path:  "/jobs",  Method:  http.MethodPost},      ListJobs:            RouterArguments{Path:  "/jobs",  Method:  http.MethodGet},      GetJobDetails:  RouterArguments{Path:  "/jobs/{jobID}",  Method:  http.MethodGet},      StartJob:            RouterArguments{Path:  "/jobs/{jobID}/start",  Method:  http.MethodPost},      //Preset  routes      CreatePreset:          RouterArguments{Path:  "/presets",  Method:  http.MethodPost},      UpdatePreset:          RouterArguments{Path:  "/presets",  Method:  http.MethodPut},      ListPresets:            RouterArguments{Path:  "/presets",  Method:  http.MethodGet},      GetPresetDetails:  RouterArguments{Path:  "/presets/{presetName}",  Method:  http.MethodGet},      DeletePreset:          RouterArguments{Path:  "/presets/{presetName}",  Method:  http.MethodDelete},   } how it works? server/routes.go

Slide 22

Slide 22 text

RESTful API database how it works?

Slide 23

Slide 23 text

RESTful API database pipeline downloaders uploaders encoding engines how it works?

Slide 24

Slide 24 text

func  StartJob(cfg  gonfig.Gonfig,  dbInstance  db.Storage,  job  types.Job)  {      newJob,  err  :=  SetupJob(job.ID,  dbInstance,  cfg)      job  =  *newJob      if  err  !=  nil  {          updateJobWithError(dbInstance,  job,  err.Error())          return    }      downloadFunc  :=  downloaders.GetDownloadFunc(job.Source)      if  err  :=  downloadFunc(log,  cfg,  dbInstance,  job.ID);  err  !=  nil  {          updateJobWithError(dbInstance,  job,  err.Error())          return    }      encodeFunc  :=  encoders.GetEncodeFunc(job)      if  err  :=  encodeFunc(logger,  dbInstance,  job.ID);  err  !=  nil  {          updateJobWithError(dbInstance,  job,  err.Error())          return      }      uploadFunc  :=  uploaders.GetUploadFunc(job.Destination)      if  err  :=  uploadFunc(logger,  dbInstance,  job.ID);  err  !=  nil  {          updateJobWithError(dbInstance,  job,  err.Error())          return      }      CleanSwap(dbInstance,  job.ID);  err  !=  nil      job.Status  =  types.JobFinished      dbInstance.UpdateJob(job.ID,  job)   }   how it works? pipeline/pipeline.go

Slide 25

Slide 25 text

RESTful API database pipeline downloaders uploaders encoding engines ffmpeg binding how it works?

Slide 26

Slide 26 text

how it works? • encoding engines • Cgo wrapper for FFmpeg functions • https://github.com/3d0c/gmf

Slide 27

Slide 27 text

how it works? package  segmenter   /*   #include     #include  "libavformat/avformat.h"   #include     #include  "c/segmenter.h"   #include  "c/util.h"   #cgo  LDFLAGS:  -­‐L${SRCDIR}/../build  -­‐lsegmenter  -­‐lavcodec  -­‐lavformat  -­‐lavutil   */   import  "C"   import  (     "fmt"     "os"     "unsafe"     "github.com/3d0c/gmf"   )  

Slide 28

Slide 28 text

DEMO!

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

future

Slide 31

Slide 31 text

future transcoding API

Slide 32

Slide 32 text

future • multibitrate HLS • go client (WIP) • add another encoding engine using GStreamer

Slide 33

Slide 33 text

We’re hiring nyti.ms/technology @NYTDevs | developers.nytimes.com

Slide 34

Slide 34 text

Stay updated open.blogs.nytimes.com @NYTDevs | developers.nytimes.com

Slide 35

Slide 35 text

Connect with us on Slack! http://video-dev.org @NYTDevs | developers.nytimes.com

Slide 36

Slide 36 text

thank you! { , } /flavioribeiro