Skip to content

RESOURCES / BLOG

How to Get Video Dimensions in PHP

Validating video uploads is a common need in web apps. Maybe you only want landscape videos, or you need to auto-generate posters that match the source aspect ratio. A frequent ask in dev threads is how to quickly read width and height without buffering the whole file. 

Hi folks,
I need to validate user-uploaded videos by resolution and aspect ratio before processing. What is the most reliable way to get video width and height using PHP? Ideally a solution that works in common hosting environments and can handle formats like MP4, MOV, and WEBM. In short, how to get video dimensions in PHP, plus any tips for rotation metadata and odd pixel aspect ratios would be great. Thanks!

Great question. The most robust approaches use FFprobe from FFmpeg or a metadata library. Let’s cover three practical methods, plus a way to do this at scale if you manage your media assets in the cloud.

FFprobe is accurate across formats and codecs. You can use a PHP wrapper or invoke FFprobe directly. If you are curious about FFmpeg’s broader capabilities, see this overview.

use FFMpeg\FFProbe;

$videoPath = '/path/to/video.mp4'; // local file or accessible URL

$ffprobe = FFProbe::create();

// Get the first video stream
$stream = $ffprobe->streams($videoPath)->videos()->first();
$width  = (int) $stream->get('width');
$height = (int) $stream->get('height');

// Handle rotation if present (e.g., phone videos)
$rotate = (int) ($stream->get('tags')['rotate'] ?? 0);
if (in_array(abs($rotate), [90, 270], true)) {
    [$width, $height] = [$height, $width];
}

echo "Dimensions: {$width}x{$height}\n";Code language: PHP (php)

Notes:

  • If width or height are missing, try coded_width and coded_height as a fallback.
  • Phone videos often include a rotate tag; swap width and height for 90 or 270 degrees.
  • If pixel aspect ratio is not 1:1, consider sample_aspect_ratio to compute display width.

If you cannot install a PHP wrapper, you can shell out to FFprobe. This is often available on servers or containers.

$videoPath = '/path/to/video.mp4';
$cmd = 'ffprobe -v error -select_streams v:0 -show_entries stream=width,height,rotation:stream_tags=rotate ' .
      '-of json ' . escapeshellarg($videoPath);

$json = shell_exec($cmd);
$data = json_decode($json, true);

$w = (int)($data['streams'][0]['width'] ?? 0);
$h = (int)($data['streams'][0]['height'] ?? 0);

$rotate = 0;
// rotation can appear under "rotation" or tags.rotate depending on build
if (isset($data['streams'][0]['tags']['rotate'])) {
    $rotate = (int)$data['streams'][0]['tags']['rotate'];
} elseif (isset($data['streams'][0]['rotation'])) {
    $rotate = (int)$data['streams'][0]['rotation'];
}

if (in_array(abs($rotate), [90, 270], true)) {
    [$w, $h] = [$h, $w];
}

echo "Dimensions: {$w}x{$h}\n";Code language: PHP (php)

The getID3 library can parse containers like MP4 and MOV. It is not as exhaustive as FFprobe for certain codecs, but it is pure PHP and easy to drop in.

require 'vendor/autoload.php';

$getID3 = new getID3;
$info = $getID3->analyze('/path/to/video.mp4');

$w = $info['video']['resolution_x'] ?? null;
$h = $info['video']['resolution_y'] ?? null;

// Some files report rotation
$rotate = (int)($info['video']['rotate'] ?? 0);
if ($w && $h && in_array(abs($rotate), [90, 270], true)) {
    [$w, $h] = [$h, $w];
}

echo "Dimensions: {$w}x{$h}\n";Code language: PHP (php)
  • Remote URLs: Try probing after a server-side download to avoid partial reads and redirects.
  • Multiple video streams: Most files have one; if not, pick v:0 unless you have specific rules.
  • Rotation and SAR: Treat rotation and sample aspect ratio carefully. For a refresher on how encoding impacts display, see this guide to video encoding.
  • Performance: Cache the result keyed by file hash to avoid re-probing on every request.

If you already store videos in Cloudinary, you can fetch dimensions using the Admin API without downloading the file. You also get other metadata like duration and bitrate in the same call.

use Cloudinary\Configuration\Configuration;
use Cloudinary\Api\Admin\AdminApi;

Configuration::instance([
  'cloud' => [
    'cloud_name' => 'YOUR_CLOUD_NAME',
    'api_key'    => 'YOUR_API_KEY',
    'api_secret' => 'YOUR_API_SECRET',
  ],
]);

$api = new AdminApi();

// Get metadata for a video asset
$result = $api->asset('samples/sea_turtle', ['resource_type' => 'video']);

$width  = $result['width'] ?? null;
$height = $result['height'] ?? null;
echo "Cloudinary Dimensions: {$width}x{$height}\n";Code language: PHP (php)

For delivery, you can also resize on the fly using URL-based transformations, which is handy when you want to cap resolution or generate thumbnails. See Cloudinary’s short explainer on video URLs for the basics. Example:

https://res.cloudinary.com//video/upload/w_1280,h_720,c_limit/samples/sea_turtle.mp4

  • FFprobe is format aware and accurate across edge cases.
  • getID3 is a pure PHP fallback when you cannot install FFmpeg.
  • Cloud APIs centralize metadata and offload heavy processing from your app tier.
  • Preferred: Use FFprobe to read width and height, accounting for rotation and aspect ratio.
  • Fallback: Use getID3 for pure PHP environments.
  • At scale: Store videos in Cloudinary and query dimensions via the Admin API, then deliver resized versions via URL transformations.

Ready to streamline how you store, transform, and deliver video? Create a free Cloudinary account and start building now.

Start Using Cloudinary

Sign up for our free plan and start creating stunning visual experiences in minutes.

Sign Up for Free