# Inspect a Local MP4 with Node.js Without Calling a Model API

> Source: <https://dev.to/davidyangplus/inspect-a-local-mp4-with-nodejs-without-calling-a-model-api-4con>
> Published: 2026-10-16 15:38:20+00:00

A small media-review utility can answer basic questions before you open a video: does it contain a video stream, what dimensions does it report, how long is it, and is there an audio stream? You can collect those fields with Node's standard library and an installed ffprobe binary.

Gemini assisted this draft and the example was checked locally. The team preparing it also works on ReelBoop; this article is a technical inspection example, with no sales call to action.

Use Node.js 18 or later with ffprobe already on PATH. Save the following as `inspect-video.mjs`:

``` js
import {execFileSync} from 'node:child_process';
import {resolve} from 'node:path';

const input = process.argv[2];
if (!input) {
  console.error('Usage: node inspect-video.mjs <local-video>');
  process.exit(2);
}

try {
  const data = JSON.parse(execFileSync('ffprobe', [
    '-v', 'error',
    '-show_entries',
    'format=duration,size:stream=codec_type,codec_name,width,height',
    '-of', 'json', resolve(input)
  ], {encoding: 'utf8', maxBuffer: 1024 * 1024}));

  const video = (data.streams || []).filter(s => s.codec_type === 'video');
  if (!video.length) throw new Error('No video stream found');
  console.log(JSON.stringify({
    durationSeconds: Number(data.format?.duration),
    video,
    audioStreams: (data.streams || []).filter(s => s.codec_type === 'audio').length
  }, null, 2));
} catch (error) {
  console.error('Inspection failed:', error.message);
  process.exit(1);
}
```

Run `node inspect-video.mjs ./clip.mp4`. The program receives a filename as an argument and resolves it as a local path. Passing arguments as an array avoids shell interpolation of characters in the filename. That does not make arbitrary media processing universally safe: keep ffprobe updated and consider process isolation for untrusted files in a production service.

The wrapper makes no model request and does not upload media. Missing arguments return exit status 2. A failed read or absence of video returns a nonzero status, allowing a caller to keep that case separate from a successful report.

For the existing headphone example used while checking this utility, the report contained H.264 video at 832×464, a duration of 5.0625 seconds and zero audio streams. The zero counts streams in that file; it does not mean that the script removed sound.

A readable metadata report does not prove the full file decodes correctly or plays in every browser. Test playback separately. Likewise, frame dimensions do not establish whether the content fits a social platform's current requirements. Keep your destination checks explicit rather than giving every file a generic “passed” status.

If a duration or another required field is missing, validate it separately before relying on it. JSON can serialize a non-finite numeric conversion as null; do not confuse that with a real zero-second measurement.

For generated product clips, use another record for geometry, component count, lettering, color and unexpected objects. Compare the original still with the beginning, middle and end, and watch the entire sequence. A technically readable file can still show a bent handle or changing label.

In the headphone example, the view turns and the inner cushions become more visible, while apparent cup spacing changes. No codec or duration check identifies whether that is acceptable for a particular product listing. That is a separate judgment about intended use, not a media-parser result.

These two reports answer different questions: what file you received, and whether its visual content is suitable. Keep them distinct in the interface and in any approval process.
