本文へ移動
cccskills
無料GitHub で公開

http-video-streaming-headers

Fix "Failed to load video" errors when network requests succeed (200/206 status). Use when: (1) Video element shows error but DevTools shows successful requests, (2) Videos download correctly via curl but fail in browser, (3) Range requests work but video won't play, (4) Building CDN/media server for video streaming. The root cause is often missing Accept-Ranges header which browsers need for video seeking and streaming.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md3.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

HTTP Video Streaming Header Requirements

Problem

HTML5 video elements fail to play with "Failed to load video" error even though network requests show successful 200/206 responses. The video file downloads correctly when tested with curl, but browsers refuse to play it.

Context / Trigger Conditions

  • Video element fires onerror event despite network success
  • DevTools Network tab shows 200 or 206 status for video requests
  • curl -O <video-url> downloads a valid MP4 file
  • Video plays locally when downloaded
  • Error message is generic: "Failed to load video" or media error code 4

Solution

Required Headers for Video Streaming

  1. Accept-Ranges: bytes (CRITICAL)

    • Tells browser that range requests are supported
    • Without this, browsers may not attempt range requests for seeking
    • Add to ALL video responses, even full (200) responses
  2. Content-Type: video/mp4 (or appropriate MIME type)

    • Must match actual video format
    • Browser uses this to select decoder
  3. Content-Length (for full responses)

    • Required for browser to know file size
    • Enables progress indicators and seeking calculations
    • Note: For 206 responses, this should be partial content size
  4. For Range Requests (206 Partial Content):

    • Content-Range: bytes START-END/TOTAL
    • Status code MUST be 206, not 200

Server Implementation

// Fastly Compute@Edge example
resp.set_header("Accept-Ranges", "bytes");
resp.set_header("Content-Type", "video/mp4");

// For full responses only (not 206):
if resp.get_status() != StatusCode::PARTIAL_CONTENT {
    resp.set_header("Content-Length", file_size.to_string());
}

CDN Considerations

  • Edge caches may strip or modify headers
  • Verify headers reach the client, not just origin
  • Fastly/CloudFront can serve range requests from cached full content
  • Test with curl -I -H "Range: bytes=0-1023" to verify 206 response

Verification

# Check Accept-Ranges header
curl -I https://cdn.example.com/video.mp4 | grep -i accept-ranges
# Expected: accept-ranges: bytes

# Test range request support
curl -I -H "Range: bytes=0-1023" https://cdn.example.com/video.mp4
# Expected: HTTP/2 206 with Content-Range header

# Verify partial download works
curl -H "Range: bytes=0-100" https://cdn.example.com/video.mp4 | wc -c
# Expected: 101 (bytes 0-100 inclusive)

Example

Before (broken):

HTTP/2 200
content-type: video/mp4
x-custom-header: value

Video fails to load in browser.

After (working):

HTTP/2 200
content-type: video/mp4
content-length: 1443199
accept-ranges: bytes

Video plays correctly with seeking support.

Notes

  • Even if your CDN handles range requests automatically, you should still include Accept-Ranges: bytes in the response headers
  • Some browsers are more forgiving than others; Safari often requires proper range support while Chrome may work without
  • HTTP/2 responses may have headers lowercased (this is normal)
  • For HLS/DASH streaming, the manifest and segments all need proper headers
  • Mobile browsers are particularly strict about video headers

References

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y". Use when: (1) ExternalSecret shows OutOfSync in ArgoCD but won't sync, (2) ArgoCD application status shows "namespace X is not permitted in project 'infrastructure'", (3) ExternalSecret targets a namespace managed by a different ArgoCD project, (4) Using apps-of-apps pattern with separate infrastructure and application projects.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language. After selection, generates AI image prompts and visual briefs section-by-section. Use when the user shares content and needs visual direction, image sourcing, or creative direction for any material.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Fix "Null check operator used on a null value" errors when an object is set to null during an async await. Use when: (1) Object reference is nullified while awaiting, (2) Code accesses object with ! after await returns, (3) Cancel/dispose operations run concurrently with async operations on same object. Solution: capture local reference before await.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Add custom metadata headers (x-amz-meta-*) to AWS v4 signed requests for GCS S3-compatible API. Use when: (1) Adding custom metadata to GCS uploads via S3 API, (2) Getting signature mismatch errors after adding new headers, (3) x-amz-meta-* headers being ignored or causing 403 errors. Custom headers MUST be included in canonical headers and signed headers list.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings. Use when: (1) Password authentication fails with correct password, (2) Secret created with `<<< "value"` syntax, (3) Error like "password authentication failed" or "invalid token" despite correct value. Bash here-strings (`<<<`) add a trailing newline that corrupts secrets.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp). Use when: (1) Media moderation, transcoding, or analysis silently skips files from Blossom or content-addressed storage servers, (2) URL extraction from Nostr event tags (imeta, r tags) drops URLs without recognized extensions, (3) CDN fallback URLs append .mp4 but the actual server uses extensionless content-addressed paths like /{sha256}. Common in Nostr video events (kind 34236) where different clients use different URL formats.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

divinevideo のスキルをすべて見る

このスキルの問題を報告する