Working with Videos

Mushu provides static video optimization. Upload your videos and receive optimized MP4 and WebM variants plus thumbnails. Videos are served as static files with free downloads via Cloudflare R2.

Video Processing

When you upload a video, Mushu automatically creates:

  • Original - Your uploaded video, preserved as-is
  • Optimized (MP4) - H.264, 1080p max, 8Mbps for universal playback
  • Web (WebM) - VP9, 1080p max, 5Mbps for smaller file sizes
  • Thumbnail - JPEG, 640x360
  • Poster - JPEG, 1280x720

Upload Flow

1. Request Upload URL

POST /media/video/upload-url
Authorization: Bearer YOUR_TOKEN

{
  "org_id": "org_abc123",
  "filename": "announcement.mp4",
  "content_type": "video/mp4",
  "size_bytes": 52428800
}

Response:

{
  "media_id": "media_xyz789",
  "upload_url": "https://...",
  "expires_in": 3600,
  "key": "org_abc123/_org/media_xyz789/announcement.mp4"
}

2. Upload Video

PUT {upload_url}
Content-Type: video/mp4

[video file bytes]

3. Confirm Upload

POST /media/{media_id}/confirm
Authorization: Bearer YOUR_TOKEN

This starts transcoding. The response shows status uploaded (processing) with the original video URL.

4. Check Status

GET /media/{media_id}/video
Authorization: Bearer YOUR_TOKEN

Response (processing):

{
  "media_id": "media_xyz789",
  "status": "processing",
  "job_id": "1234567890123-abc123",
  "original": "https://..."
}

Response (ready):

{
  "media_id": "media_xyz789",
  "status": "ready",
  "job_id": "1234567890123-abc123",
  "original": "https://...",
  "optimized": "https://...",
  "web": "https://...",
  "thumbnail": "https://...",
  "poster": "https://..."
}

Video Status Values

StatusDescription
pending Upload URL generated, awaiting upload
processing Video is being transcoded
ready All variants available for download
error Transcoding failed

Playing Videos

Videos are served as static MP4 files. Use a standard HTML5 video element:

HTML

<video controls poster="{poster_url}">
  <source src="{optimized_url}" type="video/mp4">
  <source src="{web_url}" type="video/webm">
  Your browser does not support the video tag.
</video>

React

function VideoPlayer({ video }) {
  if (video.status !== 'ready') {
    return <div>Video processing...</div>;
  }

  return (
    <video controls poster={video.poster}>
      <source src={video.optimized} type="video/mp4" />
      <source src={video.web} type="video/webm" />
    </video>
  );
}

iOS (AVPlayer)

import AVKit

class VideoViewController: UIViewController {
    var player: AVPlayer?

    func playVideo(mp4Url: String) {
        guard let url = URL(string: mp4Url) else { return }

        player = AVPlayer(url: url)
        let playerController = AVPlayerViewController()
        playerController.player = player

        present(playerController, animated: true) {
            self.player?.play()
        }
    }
}

Downloading Videos

All video URLs are direct download links. Users can right-click and save, or you can provide download buttons:

<a href="{optimized_url}" download="video.mp4">
  Download MP4
</a>

Listing Videos

CLI

mushu media list --org ORG_ID --type video

API

GET /media/org/{org_id}?media_type=video
Authorization: Bearer YOUR_TOKEN

Deleting Videos

CLI

mushu media delete MEDIA_ID

API

DELETE /media/{media_id}
Authorization: Bearer YOUR_TOKEN

Deletion removes the original video and all variants from storage.

FAQ

How long does processing take?

Processing time depends on video length and resolution. A 1-minute 1080p video typically processes in 1-2 minutes.

What's the maximum video size?

Maximum upload size is 500MB. For larger videos, consider compressing before upload.

What video formats are supported?

Input: MP4, MOV, MKV, AVI, WebM, and most common formats. Output: Always MP4 (H.264) and WebM (VP9).

Can I get just the thumbnail without transcoding?

Currently, thumbnails are generated as part of the full transcoding process. All variants are created together.

Are downloads really free?

Yes! Videos are stored in Cloudflare R2 which has zero egress fees. You only pay for storage and the initial transcoding.

Pricing

OperationPrice
Video upload $0.005 per video
Video transcode $0.02 per video
Video storage $0.018 per GB/month
Video download Free