Skill 104 · AWS Media Services
Subchapter 104.26
references/workflow-vod-pipeline.mdMarkdown5 KBView on GitHub
File-based VOD workflows: transcode → package → deliver.
IF simple VOD delivery (pre-rendered formats):
→ Basic: S3 → MediaConvert → S3 → CloudFront → Viewers
IF need multiple manifest formats (HLS+DASH) from single encode, or multi-DRM:
→ JIT packaging: S3 → MediaConvert → S3 → MediaPackage v2 VOD → CloudFront
IF content uploaded continuously (UGC, content library):
→ Automated: S3 event → Lambda → MediaConvert → S3 → CloudFrontDEPENDENCY GRAPH:
Step 1 [CloudFront] ← create first so content is immediately servable
Step 2 [S3 Buckets] (source + destination)
Step 3 [IAM Role] (trusts mediaconvert.amazonaws.com)
Step 4 [Job Template] (optional but recommended)
Step 5 [MediaConvert Job or Lambda automation]| Preconditions | S3 destination bucket (or create together) |
| Outputs | distribution_domain_name |
| Needed by | Viewers (immediate delivery once jobs complete) |
IF basic VOD (no JIT packaging):
→ Origin = S3 destination bucket with OAC
IF using MediaPackage v2 VOD:
→ Origin = MediaPackage v2 endpoint URLCache behavior: Segments cached indefinitely (immutable). Manifests cached minutes to hours. Set ViewerProtocolPolicy: redirect-to-https on all cache behaviors. For custom domains, attach an ACM certificate (provisioned in us-east-1) with minimum protocol version TLSv1.2_2021.
| Outputs | source_bucket, destination_bucket |
| Needed by | Step 3 (IAM permissions), Step 5 (job source/destination) |
May be same bucket with different prefixes, or separate buckets. Enable versioning on source if overwriting is possible. Enable SSE-KMS encryption at rest on both buckets (SSE-S3 minimum if KMS is not available); SSE-KMS is RECOMMENDED for media content as it provides an audit trail via CloudTrail. Enable S3 Block Public Access on both buckets.
| Preconditions | S3 buckets exist |
| Outputs | mediaconvert_role_arn |
mediaconvert.amazonaws.coms3:GetObject (source), s3:PutObject (destination)| Preconditions | None (defines encoding settings) |
| Outputs | job_template_name |
| Skip if | One-off jobs with inline settings |
IF delivering HLS only:
→ HLS_GROUP_SETTINGS
IF delivering DASH only:
→ DASH_ISO_GROUP_SETTINGS
IF delivering both HLS and DASH from single encode:
→ CMAF_GROUP_SETTINGS (produces both manifests)
IF producing downloadable files:
→ FILE_GROUP_SETTINGS (MP4, MXF, MOV)| Preconditions | IAM role (Step 3), source file in S3, endpoint URL discovered |
| Outputs | job_id, output files in S3 |
Actions:
https://mediaconvert.<region>.amazonaws.comAccelerationSettings.Mode: PREFERRED to enable accelerated transcoding (falls back to standard if content is ineligible)Validation: get-job shows Status: COMPLETE. Check OutputGroupDetails for actual output paths.
| Preconditions | S3 buckets, IAM role, job template |
| Trigger | S3 ObjectCreated event on source bucket |
S3 source bucket (ObjectCreated)
→ Lambda function
→ MediaConvert CreateJob API
→ Output to S3 destination bucketLambda IAM needs: mediaconvert:CreateJob, iam:PassRole, s3:GetObject
IF source and destination are same bucket:
→ Use prefix filters (e.g., input/ vs output/)
→ Or use suffix filters (.mp4, .mxf, .mov on source only)
IF source and destination are different buckets:
→ No recursion riskIdempotency: Use ClientRequestToken in CreateJob (S3 events can deliver more than once).
| Rung | Resolution | Codec | Bitrate | Notes |
|---|---|---|---|---|
| 2160p | 3840×2160 | H.265 | 12-15 Mbps | Premium, HEVC devices |
| 1080p | 1920×1080 | H.264 | 5-8 Mbps | Broad compatibility |
| 720p | 1280×720 | H.264 | 2.5-4 Mbps | Mobile |
| 480p | 854×480 | H.264 | 1-2 Mbps | Low bandwidth |
| 360p | 640×360 | H.264 | 600-1000 Kbps | Minimum |
Use QVBR for best quality-per-bit. VOD bitrates can be lower than live (multi-pass encoding).
| Mistake | Consequence | Fix |
|---|---|---|
| Hardcoding MediaConvert endpoint URL | 404 or access denied in other accounts | Discover endpoint or use regional URL |
| Missing S3 permissions on role | Job fails immediately | Add s3:GetObject + s3:PutObject |
| Assuming output file paths | Files not found | Check OutputGroupDetails in job result |
| Same bucket without prefix filters | Lambda recursive trigger loop | Separate buckets or strict filters |
| No CloudFront for delivery | High latency, S3 throttling | Always use CloudFront for viewers |
| Segment duration mismatch across rungs | Player switching issues | Identical segment duration on all rungs |