Video Transcoding
at Scale for ABC iview
Daphne Chong
@daphnechong
metro
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
What changes
are we making?
High speed
Medium speed
Low speed
Standard
Encoding
H.264 MP4
Transcoding
Example
Step 1: Prepare watermark
Step 1: Prepare watermark
Step 1: Prepare watermark
Step 2: Input video (GXF)
Step 3: Asymmetrical cropping
Step 4: Scale and set aspect ratio
Step 5: Apply watermark
Step 6: Ready to stream
1500k
other rendition sizes
1000k
650k
500k
220k
audio only
Original file audio track
Previous transcoder audio track
After audio normalisation
That’s a lot of
changes...
Transcoding
Profiles
GXF, ABC1
Profile:
- Renditions (6)
- Crop
- Normalise audio
- Adjust ratio
- Add watermark
- GXF to MP4
GXF, ABC1
GXF, ABC1
MOV, Arts
Profile:
- Renditions (6)
- Adjust ratio
- ProRes MOV to MP4
GXF, ABC1
MOV, Arts
What is this
ā€œMagic Video Softwareā€
you speak of?
./ffmpeg -i utopia.gxf utopia.mp4
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
./ffmpeg -i INPUT -c:v libx264 -filter_complex
"[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma
in], [1:v]scale=54:-1[ovrl],
[main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44
" -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p
-profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a
libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1]
amerge=inputs=2,
dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar
44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart
-threads 0 -y OUTPUT
In reality, it looks like this
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
Cost
Scale
Flexibility
Cost
Scale
Flexibility
thesupercarkids.com
mini-me.com
Cost
Scale
Flexibility
ā€œThe Cloudā€
Cost
Scale
Flexibility
Cost
Scale
Flexibility
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
Source
Queue
Process
Transfer
Notify
8 minutes 27 seconds
Original
length
Time to produce rendition
60 min
7 min
42 min
Lowest
(audio)
Highest
(1500k)
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
Languages:
Node.js
Go
Node.js
Existing team experience
Rapid development for APIs
Untyped. Sadface.
Go
Typed and compiled
Cross-platform
Easy deployment
Learning curve
Infrastructure:
EC2, SQS, S3, SNS,
Dynamo / RDS,
Cloudformation
AWS - EC2
Autoscaling
AWS - SQS
Simple Queuing
System
SQS
First in first out (FIFO)
Single consumer per message
Message has ā€œvisibility timeoutā€
Adjustable visibility timeout
AWS - S3
File Storage
AWS - DynamoDB
AWS - DynamoDB
AWS - DynamoDB
AWS - MySQL on RDS
DynamoDB
NoSQL
Key-value pair storage
Pay for number of records/sec read
DynamoDB
Our use case was not optimal
Manual aggregations
Higher cost than expected
Doesn’t scale automatically
MySQL
Switched to MySQL on RDS
Managed hosting
Aggregations!
Data structure ported as-is
AWS Cloudformation
"ExampleLoadBalancer" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : [ "us-east-1a", "us-east-1b" ],
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "8081",
"Protocol" : "HTTP"
} ]
}
}
Node.js + Go
AWS Infrastructure
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
When should
you scale?
Scaling Considerations
Hourly billing
Instance size: Cost vs Speed
Content priority
Ad-hoc requests
Varied content length
Scaling Considerations:
AWS limitations
AWS scaling metrics can be slow
No automatic off switch
Can’t choose instances to scale down
(Instance protection now available)
MVP:
Don’t make things wait
too long
MVP:
Supply enough
capacity at all times
MVP:
Driven by drop folders
GXF, ABC1
Profile:
- Renditions (2)
- Crop
- Normalise audio
- Adjust ratio
- Add watermark
- GXF to MP4
var autoscaling = new AWS.AutoScaling(...);
var params = {
AutoScalingGroupName: groupName,
DesiredCapacity: capacity
Some white text
};
autoscaling.setDesiredCapacity(params, ...);
var autoscaling = new AWS.AutoScaling(...);
var params = {
AutoScalingGroupName: groupName,
DesiredCapacity: capacity
Some white text
};
autoscaling.setDesiredCapacity(params, ...);
Amazon Machine
Images (AMIs)
Which instance size?
Time vs Cost
for 1 hour of content
Time Cost
?
Winner:
c4.xlarge
Up: step scaling
Down: stop everything
An interesting puzzle :)
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
24 hours in
Transcoding
(10am - 10am)
$57.22
$42.86
US Dollars
EC2 Instances: $34.31
EC2 (other): $ 4.24
RDS: $ 2.66
S3: $ 1.65
SQS: $ 0.00
Total (USD): $42.86
Transcoding costs: 24 hrs
Next 24 hours
Approx 70% of the volume
$34.63
Australian Dollars
One year’s costs?
$16.5k
Australian Dollars
$12.5k
US Dollars
This is a BIG deal!
thesupercarkids.com
bikesandbeyond.ca
8 minutes 27 seconds
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
AWS & throughput
optimisations
Transcoding in
chunks/segments
Introspection &
Validation
GXF, ABC1
Profile:
- Crop
- Normalise audio
- Adjust ratio
- Add watermark
- GXF to MP4
ffprobe
1. What is Transcoding?
2. Why build our own system?
3. Architecture
4. Technology choices
5. Autoscaling transcoders
6. Costs
7. Future roadmap
Summary
8 minutes 27 seconds
@daphnechong
Thanks!
Q&A

Video Transcoding at Scale for ABC iview (NDC Sydney)

  • 1.
    Video Transcoding at Scalefor ABC iview Daphne Chong @daphnechong
  • 5.
  • 6.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 7.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 9.
  • 12.
  • 13.
  • 14.
  • 15.
    Step 1: Preparewatermark
  • 16.
    Step 1: Preparewatermark
  • 17.
    Step 1: Preparewatermark
  • 18.
    Step 2: Inputvideo (GXF)
  • 19.
  • 20.
    Step 4: Scaleand set aspect ratio
  • 21.
    Step 5: Applywatermark
  • 22.
    Step 6: Readyto stream 1500k
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
    That’s a lotof changes...
  • 28.
  • 29.
    GXF, ABC1 Profile: - Renditions(6) - Crop - Normalise audio - Adjust ratio - Add watermark - GXF to MP4
  • 30.
  • 31.
    GXF, ABC1 MOV, Arts Profile: -Renditions (6) - Adjust ratio - ProRes MOV to MP4
  • 32.
  • 33.
    What is this ā€œMagicVideo Softwareā€ you speak of?
  • 35.
  • 36.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 37.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 38.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 39.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 40.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 41.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 42.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 43.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 44.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 45.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 46.
    ./ffmpeg -i INPUT-c:v libx264 -filter_complex "[0:v]crop=720:576:0:32,yadif,scale=1024x576,setdar=16/9[ma in], [1:v]scale=54:-1[ovrl], [main][ovrl]overlay=main_w-overlay_w-47:main_h-overlay_h-44 " -crf 22 -maxrate 1404k -bufsize 1500k -pix_fmt yuv420p -profile:v high -level 4.0 -refs 3 -r 25 -g 50 -c:a libfdk_aac -b:a 96k -filter_complex "[0:a:0][0:a:1] amerge=inputs=2, dynaudnorm=f=500:g=31:p=0.82:m=30.0:r=0.0:s=0.0 [aout]" -ar 44100 -ac 2 -map 0:0 -map "[aout]" -movflags +faststart -threads 0 -y OUTPUT In reality, it looks like this
  • 48.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 49.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 50.
  • 51.
  • 54.
  • 55.
  • 56.
  • 58.
  • 59.
  • 61.
  • 62.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 63.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 64.
  • 80.
    8 minutes 27seconds
  • 81.
    Original length Time to producerendition 60 min 7 min 42 min Lowest (audio) Highest (1500k)
  • 83.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 84.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 85.
  • 88.
    Node.js Existing team experience Rapiddevelopment for APIs Untyped. Sadface.
  • 90.
  • 91.
    Infrastructure: EC2, SQS, S3,SNS, Dynamo / RDS, Cloudformation
  • 92.
  • 95.
    AWS - SQS SimpleQueuing System
  • 97.
    SQS First in firstout (FIFO) Single consumer per message Message has ā€œvisibility timeoutā€ Adjustable visibility timeout
  • 98.
  • 100.
  • 101.
  • 102.
    AWS - DynamoDB AWS- MySQL on RDS
  • 104.
    DynamoDB NoSQL Key-value pair storage Payfor number of records/sec read
  • 105.
    DynamoDB Our use casewas not optimal Manual aggregations Higher cost than expected Doesn’t scale automatically
  • 106.
    MySQL Switched to MySQLon RDS Managed hosting Aggregations! Data structure ported as-is
  • 107.
  • 109.
    "ExampleLoadBalancer" : { "Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "AvailabilityZones" : [ "us-east-1a", "us-east-1b" ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "8081", "Protocol" : "HTTP" } ] } }
  • 111.
    Node.js + Go AWSInfrastructure
  • 112.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 113.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 115.
  • 116.
    Scaling Considerations Hourly billing Instancesize: Cost vs Speed Content priority Ad-hoc requests Varied content length
  • 117.
    Scaling Considerations: AWS limitations AWSscaling metrics can be slow No automatic off switch Can’t choose instances to scale down (Instance protection now available)
  • 119.
  • 120.
  • 121.
  • 122.
    GXF, ABC1 Profile: - Renditions(2) - Crop - Normalise audio - Adjust ratio - Add watermark - GXF to MP4
  • 128.
    var autoscaling =new AWS.AutoScaling(...); var params = { AutoScalingGroupName: groupName, DesiredCapacity: capacity Some white text }; autoscaling.setDesiredCapacity(params, ...);
  • 129.
    var autoscaling =new AWS.AutoScaling(...); var params = { AutoScalingGroupName: groupName, DesiredCapacity: capacity Some white text }; autoscaling.setDesiredCapacity(params, ...);
  • 130.
  • 131.
  • 132.
    Time vs Cost for1 hour of content Time Cost ?
  • 133.
  • 134.
    Up: step scaling Down:stop everything
  • 140.
  • 141.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 142.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
    EC2 Instances: $34.31 EC2(other): $ 4.24 RDS: $ 2.66 S3: $ 1.65 SQS: $ 0.00 Total (USD): $42.86 Transcoding costs: 24 hrs
  • 148.
    Next 24 hours Approx70% of the volume
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
    This is aBIG deal!
  • 154.
  • 155.
  • 156.
    8 minutes 27seconds
  • 158.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 159.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 160.
  • 163.
  • 165.
  • 166.
    GXF, ABC1 Profile: - Crop -Normalise audio - Adjust ratio - Add watermark - GXF to MP4
  • 167.
  • 171.
    1. What isTranscoding? 2. Why build our own system? 3. Architecture 4. Technology choices 5. Autoscaling transcoders 6. Costs 7. Future roadmap
  • 172.
  • 177.
    8 minutes 27seconds
  • 179.
  • 180.