DistroTV Studio

User Guide

«

Introduction

Welcome to the DistroTV Studio User Guide.

DistroTV Studio allows you to build a full-suite linear streaming HLS channel equipped with ad markers and accompanying EPG.

The purpose of this document is to provide an in-depth look on different configurations available within the DistroTV Studio AMI to customize your FAST channel with your needs.

In this guide, you will learn how to:

Here is a System Architecture Diagram of what you will setup by the end of this guide.

Prerequisites

Before you begin, you should have:

Setting Up the AWS Environment

Creating an S3 Bucket

A screenshot of a bucket AI-generated content may be incorrect.

A screenshot of a bucket AI-generated content may be incorrect.A screenshot of a computer AI-generated content may be incorrect.

Edit Bucket Permissions

[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET", "HEAD" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [], "MaxAgeSeconds": 3000 } ]

A screenshot of a web browser AI-generated content may be incorrect.A screenshot of a computer AI-generated content may be incorrect.

Access Management Setup

Create a New IAM Policy

A screenshot of a computer AI-generated content may be incorrect.

A screenshot of a computer AI-generated content may be incorrect.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:PutObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::bucket name", "arn:aws:s3:::bucket name/*" ] } ] }

A screenshot of a computer AI-generated content may be incorrect.

Create a New Role

A screenshot of a phone AI-generated content may be incorrect.

A screenshot of a computer AI-generated content may be incorrect.

Create a Global Conf File

The global conf file is a configuration file which helps point the DistroTV Studio AMI to access the correct public S3 directories for files.

It takes 4 required parameters:

s3_meta is the folder where the channel configuration files are being placed.

s3_output is the folder where the m3u8s and ts files will be uploaded. they will be uploaded into this folder /strm/ for linear and built channels and in /vid/ for content generated by the DistroTV Studio Transcoder.

s3_transcode is the folder where the preramp will communicate with the DistroTV Studio Transcoder when new videos are to be encoded.

channel_list are the names of the configuration files the DistroTV Studio AMI will scan for within your S3 directory. In this guide we assume the names of the channel files will be yourchannelname_preramp and yourchannelname.

Create Global Conf File

https://docs.distro.tv/samples/channel-builder/globals/global_1.conf

[General] s3_meta=s3://bucket name/meta/ s3_output=s3://bucket name/ s3_transcode=s3://bucket name/transcode/ channel_list=yourchannelname_preramp,yourchannelname

Create globals Folder

A screenshot of a computer AI-generated content may be incorrect.

A screenshot of a phone AI-generated content may be incorrect.

Upload Your Global Conf File

Creating S3 Bucket Directories

Create meta Folder

Create transcode Folder

Create content Folder

Create channels Folder

Create schedule Folder

After this chapter, your S3 bucket should have the following structure:

bucket-name/ ├── content/ (Created in Chapter 5) │ ├── globals/ (Created in Chapter 4) │ └── global_1.conf (Uploaded in Chapter 4) │ ├── meta/ (Created in Chapter 5) │ ├── channels/ (Created in Chapter 5) │ └── schedule/ (Created in Chapter 5) │ └── transcode/ (Created in Chapter 5)

Launch a DistroTV Studio Image

A screenshot of a web page AI-generated content may be incorrect.

A screenshot of a website AI-generated content may be incorrect.

globals=s3://bucket name/globals/global_1.conf

A screenshot of a phone AI-generated content may be incorrect.

Ingest Content

Create Metadata File(s)

Download the sample content metadata Excel template found below. Populate the spreadsheet with your own content details and save as a TSV file with the name category_name.tsv where category_name is the name of your category/grouping of content. If you have a particular grouping of content, such as a playlist, collection of movies, a certain series, etc. that you wish to be tagged together as a certain category then you are advised to include all of them in the same metadata file.

https://docs.distro.tv/samples/channel-builder/content/DistroTV%20-%20Channel%20Content%20Sample%20Metadata%20Template.xlsx

Within the Excel template, you will see different columns for various metadata. Some are required while others are optional. For each piece of content, a Global Unique ID (GUID), content title, and the link to or file path of the video file associated are required. Things such as content description, genre, publish date,

etc. are optional – but all info should be shared in a Metadata Mapping spreadsheet.

Reference the table below to see which metadata columns are required:

Metadata Column Name Field Description Requirement
#guid Global Unique ID Required
title Title of the content Required
description Description of the content Optional
pub_date Publish date of the content in YYYY-MM-DD format Optional
video_path S3 file path of the video file, or publicly readable URL Required
thumbnail_path S3 file path of the video content thumbnail in 16:9 aspect ratio, or publicly readable URL Optional
rating Rating of the content Optional
audio_tracks S3 file paths of the audio track files, or publicly readable URL as a CSV for content with multiple audio tracks Optional
subtitle_tracks S3 file paths of the subtitle track files, or publicly readable URL as a CSV for multiple subtitle tracks Optional
cuepoints Timestamps for the content’s ad break timings as a CSV for multiple timestamps Optional

Create a Preramp Conf File

https://docs.distro.tv/samples/channel-builder/meta/channels/yourchannelname_preramp.conf

[General] cid=11111 parser=pt freq=* * * * * maxitems=0 uniquetitle=1 deleted=1 ccount=1 [Category1] name=category_name url=HTTPS URL OR S3 FILE PATH TO category_name.tsv
Flag Description Values
cid This channel ID will place all related transcoded-content under a parent folder named Only positive integers are allowed.
parser Set the content parser based on your input source. You can select from one of our existing mRSS feed parsers, our existing TSV parser (pt), or upload your own. A name of a parser. Use pt if ingesting from the TSV content metadata templates.
freq Cronjob-like string to sets the frequency for how often DistroTV Studio will scan the category source(s) for new content. ex. 17 10 * * 0
maxitems Sets the maximum amount of items to import per category each time the ingest is ran. Setting this value to 0 indicates no limit and will ingest all items found in each category feed. Only 0, or positive integers are allowed.
uniquetitle

Enabling Unique Titles ensures that items with the same title, which exist across multiple categories, will only be ingested once. This helps avoid duplicating videos and saves memory storage by preventing the transcoding of the same video multiple times. If this option is disabled, the system will check for duplicates using the GUID instead of the titles.

Recommended to keep this enabled for non-advanced users.

"Enabled": "1", "Disabled": "0"
deleted

Enabling Clean Up Categories ensures that the system checks whether items still exist in their assigned category source feed(s) each time it scans for new content. If an item is no longer present in a source feed, its associated category label(s) will be removed from the database.

Recommended to keep this enabled for non-advanced users.

"Enabled": "1", "Disabled": "0"
ccount Sets the number of categories to import. Only positive integers are allowed.
[General] cid=11111 parser=pt freq=* * * * * maxitems=0 uniquetitle=1 deleted=1 ccount=3 [Category1] name=category_name1 url=HTTPS URL OR S3 FILE PATH TO category_name1.tsv [Category2] name=category_name2 url=HTTPS URL OR S3 FILE PATH TO category_name2.tsv [Category3] name=category_name3 url=HTTPS URL OR S3 FILE PATH TO category_name3.tsv
Flag Description Values
watermark If you wish you burn in a watermark on each of your videos, input watermark image URL or S3 file path. Images should be png, jpeg, or jpg. Ensure the URL is publicly readable or your instance has permissions for the S3 file path. A URL or S3 file path to a png, jpeg, or jpg file.
wm_transp Sets the transparency of the watermark. 0% being fully transparent and 100% being fully opaque. Ex. 0.7 means the watermark will be set to 70% opacity. Float between 0.0 and 1.0
wm_scale Sets the size scaling of the watermark relative to the original video. Ex. .15 means the watermark will be scaled to a 15% of the video's resolution. Float between 0.0 and 1.0
wm_pos

Sets the position of where the watermark will be burned in relative to the original video as an X:Y pixel coordinate. With x='0':y='0' being the top left. You can use 'W' and 'H' to reference the original video's Width and Height respectively, and 'w' and 'h' to reference the watermark's width and height respectively.

Some examples:

  • Watermark in top left with padding= x='0.01*W':y='0.01*H'

  • Watermark in top right with padding= x='0.99*W-w':y='0.01*H'

  • Watermark in bottom left with padding= x='0.01*W':y='0.99*H-h'

  • Watermark in bottom right with padding= x='0.99*W-w':y='0.99*H-h'

  • Watermark in top left= x='0':y='0'

  • Watermark in top right x='W-w':y='0'

  • Watermark in bottom left= x='0':y='H-h'Watermark in bottom right= x='W-w':y='H-h'

See examples in the description

The following preramp conf file would burn in a watermark at 70% opacity (wm_transp=0.7), 15% scale of the source video (wm_scale=0.15), in the top left corner with padding equal to 1% of the source video’s Width and Height (wm_pos=x='0.01*W':y='0.01*H').

[General] cid=11111 parser=pt freq=* * * * * maxitems=0 uniquetitle=1 deleted=1 watermark=https://docs.distro.tv/samples/channel-builder/content/dtv_studio_logo.png wm_transp=0.7 wm_scale=0.15 wm_pos=x='0.01*W':y='0.01*H' ccount=3 [Category1] name=category_name1 url=HTTPS URL OR S3 FILE PATH TO category_name1.tsv [Category2] name=category_name2 url=HTTPS URL OR S3 FILE PATH TO category_name2.tsv [Category3] name=category_name3 url=HTTPS URL OR S3 FILE PATH TO category_name3.tsv

Launch a DistroTV Studio Transcoder Image

A screenshot of a computer AI-generated content may be incorrect.

A red circle with black text AI-generated content may be incorrect.

globals=s3://bucket name/globals/global_1.conf

A screenshot of a phone AI-generated content may be incorrect.

Create Channel Schedule

Create a Schedule File

Scheduling: The Order in Which Content is Played

There are several ways in which we can build a channel, and the differences are in how we organize/ select content to be played, as well as the timings in which ad breaks are stitched.

Read the table below to see which schedule type you’re interested in creating. The schedule type you choose will dictate which flags are needed in your channel’s conf file.

Schedule Type Organization Type Ad Break Stitch Style
pgen (Time Based) (Ads at regularly timed intervals) Time based, based on specified start time and end time blocks Requires cadence and length attributes to be defined in the channel conf file. Inserts ad breaks based on the specified cadence and filler length in the conf file.
lgen (Playlist Based)(Ads at regularly timed intervals) Playlist based, does not adhere to any time schedule. Simply plays out what is in the schedule based on specified order Requires cadence and length attributes to be defined in the channel conf file. Inserts ad breaks based on the specified cadence and filler length in the conf file.
atgen (Time Based)(Ads every X videos intervals) Time based, based on specified start time and end time blocks Requires every attribute to be defined in the channel conf file. Inserts ad breaks after every X videos specified in the conf file. It plays the filler file for the entire duration
agen (Playlist Based)(Ads every X videos intervals) Playlist based, does not adhere to any time schedule. Simply plays out what is in the schedule based on specified order Requires every attribute to be defined in the channel conf file. Inserts ad breaks after every X videos specified in the conf file. It plays the filler file for the entire duration
cgen (Time & Playlist Based support)(Ads at pre-defined timings) Supports both time based and playlist based. Requires cpoints attribute to be defined in the channel conf file. Inserts ad breaks at the timings specified by the cuepoints in the database for the content. Rounded UP to the nearest TS file. It plays the filler file for the entire duration.

Schedule Type Samples

Below are samples of the different schedule formats. You will notice that all of them have a similar header line which dictates the schedule start time, the rebuild cycle increment (length in hours), and the playback window duration (length in hours) respectively.

Time Based Schedule

Time based schedules will play out content according to start and end time.

Schedule Header Line Fornat
#YYYY-MM-DD HH:MM:SS rebuild cycle increment length in hours playback window length in hours

Schedule Body Format
start time end time category
name/guid:video_guid/title:video_title (can be a CSV for multiple)

#2025-01-01 00:00:00 168 168 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller 00:00:00 10:00:00 Comedy 10:00:00 12:00:00 Drama 12:00:00 20:00:00 Action 20:00:00 00:00:00 Horror,Thriller

Playlist Based Schedule

Playlist based schedules will play out content based on the specified order.

Schedule Header Line Fornat
#YYYY-MM-DD HH:MM:SS rebuild cycle increment length in hours playback window length in hours

Schedule Body Format
start time end time category
cat:category_name/guid:video_guid/title:video_title

#2025-01-01 00:00:00 24 24 guid:vid_1 title:Escandalo Secreto guid:vid_2 cat:Comedy cat:Comedy cat:Drama cat:Drama cat:Action cat:Action cat:Horror cat:Thriller

Create your schedule based on either a time-based or playlist-based approach following the sample formats above. Be sure to reference your own category_name(s), video_guid(s), and video_title(s) as needed.

The cadence in which the ads will be stitched is dictated in the channel configuration file and will be discussed in a later section.

Once you create your schedule file, save it with the name of your liking with a .tsv file extension.

Create yourchannelname Folder

Upload Your Schedule

Launch Your Channel

https://docs.distro.tv/samples/channel-builder/meta/channels/yourchannelname.conf

Flag Description Value
playlist Must be set. Indicates to DistroTV Studio that this is a channel conf file. 1
freq Cronjob-like string to sets the frequency for how often DistroTV Studio will rebuild and increment the schedule file(s). ex. 17 10 * * 0
cid This channel ID will place all related transcoded-content under a parent folder named Only positive integers are allowed.
cpoints

When Enabled, ad breaks will be inserted based on the given cuepoint timestamps associated with each video in your library. Only enable this is you have cuepoint timestamp data for your videos.

Cannot be used together with the every flag.

"Enabled": "1", "Disabled": "0"
cadence

Determines how often an ad break will be inserted on a time-based interval. An ad break will be inserted after the specified number of seconds have elapsed since the previous ad break (or the start of the schedule).

Must be paired with length flag.

Cannot be used together with the every flag.

Only positive integers are allowed.
length

Determines the length/duration of your ad breaks in seconds.

Must be paired with cadence flag.

Cannot be used together with the every flag.

Only positive integers are allowed.
every

Determines how often an ad break will be inserted on a per-X-videos interval. An ad break will be inserted after the specified amount of videos air. The ad break will select and playout for the duration of one of your [Fillers].

Cannot be used together with cpoints, cadence, or length flags.

Only positive integers are allowed.
usedbcat

When Enabled, the schedule builder will search the database using the category column rather than the guid prefix.

Recommended to keep this enabled for non-advanced users.

"Enabled": "1", "Disabled": "0"

Additionally, there are more advanced flags to use:

Flag Description Value
vcount

Lists the number of variants in the stream.

Recommended to keep this default value for non-advanced users.

Leave as 3
awsparams

These params are used when running aws s3 cp command to upload the m3u8s to s3.

Recommended to keep this default value for non-advanced users.

--acl public-read --recursive --cache-control max-age=3
abumper_before

When Enabled, the specified ad bumper will be played before cutting to an ad break.

Must be used together with abumper.

"Enabled": "1", "Disabled": "0"
abumper_after

When Enabled, the specified ad bumper will be played after returning from an ad break.

Must be used together with abumper.

"Enabled": "1", "Disabled": "0"
abumper

Source HTTPS link to the folder that holds your ad bumper.

Must be used together with abumper_len.

URL to the folder that contains your ad bumper video m3u8.

Ex. https://your-s3-bucket.com/vid/cid/vid/adbumper
abumper_len

Specifies the duration of your ad bumper in seconds.

Must be used together with abumper.

Only positive integers are allowed.
cbumper

When present in the conf file, the channel will insert a content bumper before every video.

Must be used together with cbumper_len.

URL to the folder that contains your content bumper video m3u8.

Ex. https://your-s3-bucket.com/vid/cid/vid/cbumper
cbumper_len

Specifies the duration of your content bumper in seconds.

Must be used together with cbumper.

Only positive integers are allowed.
sqlsort

Allows the user to adjust how content is prioritized in the scheduling mechanism.

The value input will be added as a string in the SQL query after 'ORDER BY '. Can be used if you wish to organize your schedule generation in a specific way.

A valid SQL statement proceeding ‘ORDER BY ‘.

For example, you can input 'id desc' if you wish you have your schedule created prioritizing the most recent content in a category.

loopforever

When Enabled, the generated schedule will loop and playout indefinitely until a new schedule is uploaded.

Recommended to keep this disabled for non-advanced users.

If you choose to enable this, ensure that the cronjob set in the freq flag is an invalid cronjob time that never runs.

"Enabled": "1", "Disabled": "0"
ts_prefix

Adds a prefix to the TS files so instead of a relative domain filepath, you can input a new domain file path prefix to the TS files within the m3u8 playlists.

Recommended to leave this disabled for non-advanced users.

A valid CDN domain to route your TS files through

In the [Fillers] section is where you will point to the video(s) you would like to use as ad break fillers, that is, the content that will be aired during ad breaks. It acts as a pool of possible videos that can air during the ad breaks, like a Category during content ingest. The count flag denotes the number of filler videos you have, and the N integer points to the associated URL. It should be noted that DistroTV Studio will only read the first N number of filler URLs denoted by count. For example, if you have count=3 but 5 filler URLs, it will only read the first 3.

When using cpoints=1 or the every=X flag to insert ad breaks, the entire duration of the selected filler will playout and used as the duration of the ad break. Whereas with cadence and length, the length flag is what dictates the length of your ad break and will concatenate or crop your filler(s) as needed to reach the assigned ad duration.

Sample channel conf file using every=X ad break pattern

[General] playlist=1 freq=7 9 * * * cid=11111 every=3 usedbcat=1 vcount=3 awsparams=--acl public-read --recursive --cache-control max-age=3 [Variants] var1_path=640x360/ var1_pindex=640x360/index.m3u8 var1_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=928000,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2" var2_path=854x480/ var2_pindex=854x480/index.m3u8 var2_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1728000,RESOLUTION=854x480,CODECS="avc1.64001e,mp4a.40.2" var3_path=1280x720/ var3_pindex=1280x720/index.m3u8 var3_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3328000,RESOLUTION=1280x720,CODECS="avc1.64001e,mp4a.40.2" [Fillers] count=2 1=https://d14c63magvk61v.cloudfront.net/hls/1/vid/fillers/120alpha 2=https://d14c63magvk61v.cloudfront.net/hls/1/vid/fillers/150alpha

Sample channel conf file using cadence & length ad break pattern

[General] playlist=1 freq=7 9 * * * cid=11111 cadence=480 length=120 usedbcat=1 vcount=3 awsparams=--acl public-read --recursive --cache-control max-age=3 [Variants] var1_path=640x360/ var1_pindex=640x360/index.m3u8 var1_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=928000,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2" var2_path=854x480/ var2_pindex=854x480/index.m3u8 var2_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1728000,RESOLUTION=854x480,CODECS="avc1.64001e,mp4a.40.2" var3_path=1280x720/ var3_pindex=1280x720/index.m3u8 var3_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3328000,RESOLUTION=1280x720,CODECS="avc1.64001e,mp4a.40.2" [Fillers] count=1 1=https://d14c63magvk61v.cloudfront.net/hls/1/vid/fillers/120alpha

Sample channel conf file with ad bumper and content bumpers and sqlsort set to prioritize newly ingested content

[General] playlist=1 freq=7 9 * * * cid=11111 cadence=480 length=120 abumper_before=1 abumper_after=1 abumper= https://d14c63magvk61v.cloudfront.net/hls/1/vid/adbumper abumper_len=10 cbumerp= https://d14c63magvk61v.cloudfront.net/hls/1/vid/cbumper cbumper_len=5 sqlsort=id desc usedbcat=1 vcount=3 awsparams=--acl public-read --recursive --cache-control max-age=3 [Variants] var1_path=640x360/ var1_pindex=640x360/index.m3u8 var1_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=928000,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2" var2_path=854x480/ var2_pindex=854x480/index.m3u8 var2_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1728000,RESOLUTION=854x480,CODECS="avc1.64001e,mp4a.40.2" var3_path=1280x720/ var3_pindex=1280x720/index.m3u8 var3_ext=#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3328000,RESOLUTION=1280x720,CODECS="avc1.64001e,mp4a.40.2" [Fillers] count=1 1=https://d14c63magvk61v.cloudfront.net/hls/1/vid/fillers/120alpha

It is highly recommended to leave the [Variants] section untouched.

cronjob started processing (pgen) name-of-schedule.tsv generating name-of-schedule.tsv coding name-of-schedule.tsv pcode: completed: /data/onramp/runtime/yourchannelname/schedule/name-of-schedule.done found tsv files: [‘name-of-schedule.tsv’] cronjob finished in n minutes processing /data/onramp/runtime/yourchannelname/schedule/name-of-schedule.done- start time: YYYY-MM-DD HH:MM:SS master playlist building complete… (timestamp of when the schedule finished being built) cronjob finished in X minutes watchdog.py process not found, restarting... v1.m3u8 doesnt exist, restarting... cencoder init... playlist changed: /data/onramp/runtime/yourchannelname/schedule/name-of-schedule.done- start: YYYY-MM-DD HH:MM:SS / endt: YYYY-MM-DD HH:MM:SS watchdog.py process not found, restarting...

After all chapters, your S3 bucket should have the following structure:

bucket-name/ ├── content/ (Created as per Chapter 5) │ └── category_name.tsv (Uploaded as per Chapter 7) │ ├── globals/ (Created as per Chapter 4) │ └── global_1.conf (Uploaded as per Chapter 4, referenced by EC2 instances) │ ├── meta/ (Created as per Chapter 5) │ ├── channels/ (Created as per Chapter 5) │ │ ├── yourchannelname.conf (Uploaded as per Chapter 10) │ │ └── yourchannelname_preramp.conf (Uploaded as per Chapter 7) │ │ │ ├── epg/ (System generated, implied by Chapter 10) │ │ └── yourchannelname/ (System generated, implied by Chapter 10) │ │ └── datetimestamp/ (System generated, contains EPG files) │ │ │ └── schedule/ (Created as per Chapter 5) │ └── yourchannelname/ (Created as per Chapter 9) │ └── schedule_name.tsv (Uploaded, name depends on UTC time, as per Chapter 9) │ ├── strm/ (System generated, implied by Chapter 10) │ └── channels/ (System generated, implied by Chapter 10) │ └── yourchannelname/ (System generated, implied by Chapter 10) │ ├── master.m3u8 (System generated, playback URL target in Chapter 10) │ └── *.ts (Video segment files, system generated) │ ├── transcode/ (Created as per Chapter 5) │ └── new/ (System generated, implied by Chapter 8) │ └── (Video files to be processed by DistroTV Studio Transcoder would appear here) │ └── vid/ (System generated, implied by Chapter 8) └── (Transcoded video output from DistroTV Studio Transcoder would appear here)