跳到正文
DEV Community· David Yang·· 3 小時前AI 評分47

用 Node.js 檢查本機 MP4,無需呼叫模型 API

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

AI 導讀

這個 Node.js 小工具透過標準函式庫呼叫已安裝的 ffprobe,檢查本機 MP4 的影片串流、尺寸、時長及音訊串流,毋須呼叫模型 API 或上載媒體。工具需使用 Node.js 18 或以上,並確保 ffprobe 已在 PATH;程式會以 JSON 輸出結果,缺少參數或讀取失敗時會回傳非零狀態。中繼資料可讀不代表影片必定能正常解碼或播放,檔案狀態與畫面內容是否適用須分開判斷。

正文

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.

Run ffprobe as a child process, not a shell string

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

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.

Interpret the output carefully

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.

Keep a separate visual worksheet

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.

來源:DEV Community · dev.to