Overview

HTTP Live Streaming (HLS) validation ensures your streams meet Apple’s technical specifications and work reliably across all Apple devices. Probe.dev provides Apple’s official MediaStreamValidator tool as a service, eliminating the need for local tool installation while providing comprehensive validation reports.

MediaStreamValidator is essential for App Store submissions, streaming service quality assurance, and debugging playback issues across iOS, macOS, and tvOS devices.

Why HLS Validation Matters

App Store Requirements

Mandatory for iOS Apps
Apple requires HLS compliance for video streaming apps

Rejection Prevention
Avoid App Store rejections due to streaming issues

Playback Quality

Universal Compatibility
Ensure streams work across all Apple devices

Error Prevention
Catch issues before they reach end users

Specification Compliance

RFC 8216 Standards
Validate against official HLS specifications

Future-Proofing
Ensure compatibility with upcoming iOS versions

Debugging Support

Detailed Error Reports
Identify specific compliance violations

Root Cause Analysis
Pinpoint encoding or packaging issues

Getting Started

Basic HLS Validation

Validate an HLS playlist for Apple compliance:

curl -G https://api.probe.dev/v1/probe/mediastreamvalidator \
  --data-urlencode "token=${PROBE_API_TOKEN}" \
  --data-urlencode "url=https://example.com/master.m3u8"

Quick Playlist-Only Check

For faster validation during development:

curl -G https://api.probe.dev/v1/probe/mediastreamvalidator \
  --data-urlencode "token=${PROBE_API_TOKEN}" \
  --data-urlencode "url=https://example.com/master.m3u8" \
  --data-urlencode "parse_playlist_only=true"

Use parse_playlist_only=true for rapid iteration during development. Switch to full validation before production deployment.

Comprehensive Validation

Full Stream Analysis

For production-ready validation including segment analysis:

curl -X POST https://api.probe.dev/v1/probe/mediastreamvalidator \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/master.m3u8",
    "parse_playlist_only": false,
    "enable_cli_output": true,
    "timeout": 650000,
    "inject_json": true
  }'

Parameter Configuration

ParameterPurposeRecommended Values
parse_playlist_onlySkip segment download/analysistrue for development, false for production
enable_cli_outputInclude raw MediaStreamValidator outputtrue for debugging
timeoutMaximum analysis time (milliseconds)650000 (10+ minutes for large streams)
inject_jsonEnhanced JSON formattingtrue for easier parsing

Apple HLS Compliance Requirements

Essential Compliance Checks

MediaStreamValidator verifies these critical requirements:

Common Validation Errors

Critical Issues

1

Bitrate Declaration Mismatch

Error: BANDWIDTH attribute doesn't match measured bitrate

Cause: Playlist declares different bitrate than actual stream

Solution:

# Re-encode with correct bitrate or update playlist
ffmpeg -i input.mp4 -b:v 2500k -maxrate 2750k -bufsize 5000k output.m3u8
2

Segment Duration Violations

Error: Segment duration exceeds target duration

Cause: Individual segments longer than #EXT-X-TARGETDURATION

Solution:

# Adjust segment duration during encoding
ffmpeg -i input.mp4 -hls_time 6 -hls_list_size 0 output.m3u8
3

Missing Audio-Only Variant

Error: No audio-only variant found

Cause: Required 64 kbps audio stream missing from master playlist

Solution:

# Create audio-only variant
ffmpeg -i input.mp4 -vn -acodec aac -b:a 64k audio_only.m3u8

Warning-Level Issues

Warnings:

  • Inefficient bitrate ladder gaps
  • Missing I-frame playlists
  • Suboptimal segment counts

Impact: Playback experience degradation

Integration Workflows

CI/CD Pipeline Integration

GitHub Actions Example

name: HLS Validation
on:
  push:
    paths: ['streams/**/*.m3u8']

jobs:
  validate-hls:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Validate HLS Streams
        run: |
          for playlist in streams/**/*.m3u8; do
            echo "Validating $playlist"
            response=$(curl -s -G https://api.probe.dev/v1/probe/mediastreamvalidator \
              --data-urlencode "token=${{ secrets.PROBE_API_TOKEN }}" \
              --data-urlencode "url=https://cdn.example.com/$playlist" \
              --data-urlencode "parse_playlist_only=true")
            
            if echo "$response" | jq -r '.success' | grep -q false; then
              echo "❌ Validation failed for $playlist"
              echo "$response" | jq -r '.error'
              exit 1
            else
              echo "✅ Validation passed for $playlist"
            fi
          done

Jenkins Pipeline

pipeline {
    agent any
    environment {
        PROBE_API_TOKEN = credentials('probe-api-token')
    }
    
    stages {
        stage('HLS Validation') {
            steps:
                script {
                    def playlists = sh(
                        script: "find streams/ -name '*.m3u8'",
                        returnStdout: true
                    ).trim().split('\n')
                    
                    playlists.each { playlist ->
                        def response = sh(
                            script: """
                                curl -s -G https://api.probe.dev/v1/probe/mediastreamvalidator \\
                                --data-urlencode "token=${PROBE_API_TOKEN}" \\
                                --data-urlencode "url=https://cdn.example.com/${playlist}"
                            """,
                            returnStdout: true
                        )
                        
                        def result = readJSON text: response
                        if (!result.success) {
                            error("HLS validation failed for ${playlist}: ${result.error}")
                        }
                    }
                }
            }
        }
    }
}

Pre-Publish Validation Script

#!/usr/bin/env python3
import requests
import sys
import time
from urllib.parse import urljoin

def validate_hls_stream(base_url, playlist_path, api_token):
    """Validate HLS stream before publishing"""
    
    full_url = urljoin(base_url, playlist_path)
    
    # Start validation
    response = requests.get(
        'https://api.probe.dev/v1/probe/mediastreamvalidator',
        params={
            'token': api_token,
            'url': full_url,
            'parse_playlist_only': False,
            'enable_cli_output': True
        }
    )
    
    if response.status_code != 200:
        print(f"❌ API Error: {response.status_code}")
        return False
    
    data = response.json()
    
    if not data.get('success', False):
        print(f"❌ Validation Failed: {data.get('error', 'Unknown error')}")
        if 'cli_output' in data:
            print("\nDetailed Output:")
            print(data['cli_output'])
        return False
    
    print(f"✅ Validation Passed: {playlist_path}")
    return True

if __name__ == "__main__":
    # Validate all streams before deployment
    streams = [
        "master.m3u8",
        "audio_only/playlist.m3u8",
        "video/720p/playlist.m3u8"
    ]
    
    base_url = "https://cdn.example.com/streams/"
    api_token = os.getenv('PROBE_API_TOKEN')
    
    all_passed = True
    for stream in streams:
        if not validate_hls_stream(base_url, stream, api_token):
            all_passed = False
    
    sys.exit(0 if all_passed else 1)

App Store Submission Workflow

Pre-Submission Checklist

Documentation for App Review

Include MediaStreamValidator reports in your App Store submission:

# Generate comprehensive validation report
curl -X POST https://api.probe.dev/v1/probe/mediastreamvalidator \
  -H "Authorization: Bearer $PROBE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-cdn.com/master.m3u8",
    "parse_playlist_only": false,
    "enable_cli_output": true
  }' > hls_validation_report.json

Performance Optimization

Validation Speed Tips

  1. Development Phase: Use parse_playlist_only=true
  2. Staging Phase: Full validation with reasonable timeout
  3. Production Phase: Validate representative samples
  4. CI/CD: Parallel validation of multiple streams
Stream TypeRecommended TimeoutReasoning
Short clips (< 5 min)2-3 minutesQuick analysis
Standard content (5-60 min)5-8 minutesThorough checking
Long-form content (> 1 hour)10-15 minutesComplete validation
Live streams3-5 minutesSample-based analysis

Troubleshooting

Common Issues and Solutions

Debugging with CLI Output

Enable detailed output for troubleshooting:

curl -X POST https://api.probe.dev/v1/probe/mediastreamvalidator \
  -H "Authorization: Bearer $PROBE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://problematic-stream.com/playlist.m3u8",
    "enable_cli_output": true,
    "parse_playlist_only": false
  }' | jq -r '.cli_output'

Best Practices

Development Workflow

  • Validate frequently during encoding
  • Use playlist-only validation for quick checks
  • Automate validation in build pipelines
  • Keep validation reports for debugging

Production Deployment

  • Full validation before CDN upload
  • Validate after CDN propagation
  • Monitor validation results over time
  • Document compliance for App Store

Performance

  • Cache validation results for unchanged content
  • Validate samples of long-form content
  • Use appropriate timeouts for content length
  • Parallel validation for multiple streams

Quality Assurance

  • Validate across all bitrate variants
  • Test accessibility features
  • Verify closed caption compliance
  • Check audio-only variant functionality

Next Steps

Need help with HLS validation or App Store submission? Contact our support team at support@probe.dev for personalized assistance with your streaming workflows.