Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Leveraging Open Source to Create Virtual Live C...
Search
Flávio Ribeiro
July 01, 2020
Programming
240
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Leveraging Open Source to Create Virtual Live Channels from On-Demand Video
Flávio Ribeiro
July 01, 2020
More Decks by Flávio Ribeiro
See All by Flávio Ribeiro
Building a Live Streaming Stack for Big Brother
flavioribeiro
0
75
Engineering a Live Streaming Workflow for Super Bowl 53 at CBS
flavioribeiro
0
200
Live Streaming Challenges & How we are Dealing with Them
flavioribeiro
0
310
How Video Works?
flavioribeiro
2
820
Improving the Video Delivery at The New York Times
flavioribeiro
1
380
Building a Closed Captions Ecosystem at The New York Times
flavioribeiro
0
220
Snickers: Open Source HTTP API for Media Encoding
flavioribeiro
0
350
The New York Times: Flash Free Video in 2016
flavioribeiro
0
110
Towards the Application of WebRTC Peer-to-Peer to Scale Live Video Streaming over the Internet
flavioribeiro
1
200
Other Decks in Programming
See All in Programming
技術記事、 専門家としてのプログラマ、 言語化
mizchi
13
6.5k
Inside Stream API
skrb
1
770
Oxlintのカスタムルールの現況
syumai
6
1.1k
The NotImplementedError Problem in Ruby
koic
1
920
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
800
New "Type" system on PicoRuby
pocke
1
1k
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
130
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
230
エージェンティックRAGにAWSで入門しよう!
har1101
9
1.7k
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
12
6.4k
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
7.8k
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
180
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
28
2.7k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
750
Measuring & Analyzing Core Web Vitals
bluesmoon
9
870
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1.1k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
Building Adaptive Systems
keathley
44
3.1k
Navigating Team Friction
lara
192
16k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Transcript
Leveraging Open Source to Create Virtual Live Channels from On-Demand
Video July, 2020
@flavioribeiro /in/flavioribeiro /flavioribeiro Flavio Ribeiro Director of Engineering, Video Technology
Group ViacomCBS Digital
None
None
None
None
AGENDA • Why? • How?
WHY? • recycle on-demand catalog • possible new revenue streams
• pop-up channels • personalized channels • cheap "rundown/playout" alternative • cheap (no encoding) streaming alternative
ON THE FLY PACKAGING from https://open.nytimes.com/improving-our-video-experience-part-one-our-on-demand-video-platform-cf818e03353d
OUR DEPLOYMENT
OUR DEPLOYMENT
Goofy is a R&D Project For Virtual 24/7 Linear Channels
from VoD Assets
Architecture AWS S3 Scheduler Playout MP4 MP4 MP4 Google Cloud
Storage MP4 MP4 MP4 File Streamer https://github.com/nytimes/gcs-helper https://github.com/crunchyroll/evs-s3helper
SCHEDULER • REST API • Mediainfo ◦ calculate asset duration
• detect overlap/content collision
SCHEDULER $ http POST http://scheduler <<< ' { "title": "STAR
TREK SEASON 01 EP 01", "airing_time_start": "2020-07-01T18:14:52Z", "renditions": [ { "label": "720p", "url": "http://gcs-helper:2000/proxy/STARTREK_S01E01_720p.mp4" }, { "label": "540p", "url": "http://gcs-helper:2000/proxy/STARTREK_S01E01_540p.mp4" }, { "label": "360p", "url": "http://gcs-helper:2000/proxy/STARTREK_S01E01_360p.mp4" }, ]
None
PLAYOUT • fetch & display "rolling window" of scheduled content
• format JSON payload expected by the NGINX VOD Module
PLAYOUT $ http GET http://playout { "clipSegments": [305, 305], "durations":
[3045000, 3049000], "clipTimes": [ 1593174206000, 1593618600000, ], "currentTime": 1593618583000, "discontinuity": true, "initialClipIndex": 890, "initialSegmentIndex": 84913, "playlistType": "live", "sequences": [ { "clips": [ {"path": "/proxy/STARTREK_S01E01_720p.mp4", "type": "source"}, {"path": "/proxy/STARTREK_S01E02_720p.mp4", "type": "source"} ], "language": "eng" }, { "clips": [ {"path": "/proxy/STARTREK_S01E01_640p.mp4", "type": "source"}, {"path": "/proxy/STARTREK_S01E02_640p.mp4", "type": "source"} ], "language": "eng" } ] }
PLAYOUT $ http GET http://playout { "clipSegments": [305, 305], "durations":
[3045000, 3049000], "clipTimes": [ 1593174206000, 1593618600000, ], "currentTime": 1593618583000, "discontinuity": true, "initialClipIndex": 890, "initialSegmentIndex": 84913, "playlistType": "live", "sequences": [ { "clips": [ {"path": "/proxy/STARTREK_S01E01_720p.mp4", "type": "source"}, {"path": "/proxy/STARTREK_S01E02_720p.mp4", "type": "source"} ], "language": "eng" }, { "clips": [ {"path": "/proxy/STARTREK_S01E01_640p.mp4", "type": "source"}, {"path": "/proxy/STARTREK_S01E02_640p.mp4", "type": "source"} ], "language": "eng" } ] } from scheduler airing time since epoch # of clips in the past (+1) # of segments in the past sum(clip durations) / segment length
NGINX http { vod_mode mapped; vod_upstream_location /goofy-playout-map; vod_hls_segment_file_name_prefix "segment"; vod_segment_duration
10000; vod_align_segments_to_key_frames on; vod_live_window_duration 60000; upstream goofy-playout { server playout:2828; } server { listen 80; server_name localhost; location /goofy-playout-map { rewrite ^/goofy-playout-map/h/(.*)$ /$2 break; proxy_pass http://goofy-playout; proxy_http_version 1.1; proxy_set_header Connection ""; } location /h { vod hls; add_header Access-Control-Allow-Headers '*'; add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS'; add_header Access-Control-Allow-Origin '*'; } }
NGINX http { vod_mode mapped; vod_upstream_location /goofy-playout-map; vod_hls_segment_file_name_prefix "segment"; vod_segment_duration
10000; vod_align_segments_to_key_frames on; vod_live_window_duration 60000; upstream goofy-playout { server playout:2828; } server { listen 80; server_name localhost; location /goofy-playout-map { rewrite ^/goofy-playout-map/h/(.*)$ /$2 break; proxy_pass http://goofy-playout; proxy_http_version 1.1; proxy_set_header Connection ""; } location /h { vod hls; add_header Access-Control-Allow-Headers '*'; add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS'; add_header Access-Control-Allow-Origin '*'; } } point vod module to the playout service Initiate vod module in mapped mode create a location for the hls delivery
None
FUTURE • UI/CMS for linear "programming"
None
FUTURE • UI/CMS for linear "programming" • ads support (via
scte-35 manifest decoration)
FUTURE • UI/CMS for linear "programming" • ads support (via
scte-35 manifest decoration) • support for mixed "real" live and virtual live
FUTURE • UI/CMS for linear "programming" • ads support (via
scte-35 manifest decoration) • support for mixed "real" live and virtual live • support for personalized slots on the linear feed • DASH (variant bitrates on the VOD library)
Thanks!