jackwener/OpenCLI · error · ArgumentError

不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm)

Error message

不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm)

What it means

ArgumentError thrown when the video file's extension (lowercased) is not one of .mp4, .mov, .avi, .webm. The library rejects unsupported containers before attempting upload.

Source

Thrown at clis/douyin/publish.js:119

        { name: 'allow_download', type: 'bool', default: false, help: '允许下载' },
        { name: 'collection', default: '', help: '合集 ID' },
        { name: 'activity', default: '', help: '活动 ID' },
        { name: 'poi_id', default: '', help: '地理位置 ID' },
        { name: 'poi_name', default: '', help: '地理位置名称' },
        { name: 'hotspot', default: '', help: '关联热点词' },
        { name: 'no_safety_check', type: 'bool', default: false, help: '跳过内容安全检测' },
        { name: 'sync_toutiao', type: 'bool', default: false, help: '同步发布到头条' },
    ],
    columns: ['status', 'aweme_id', 'url', 'publish_time'],
    func: async (page, kwargs) => {
        // ── Fail-fast validation ────────────────────────────────────────────
        const videoPath = path.resolve(kwargs.video);
        if (!fs.existsSync(videoPath)) {
            throw new ArgumentError(`视频文件不存在: ${videoPath}`);
        }
        const ext = path.extname(videoPath).toLowerCase();
        if (!['.mp4', '.mov', '.avi', '.webm'].includes(ext)) {
            throw new ArgumentError(`不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm)`);
        }
        const fileSize = fs.statSync(videoPath).size;
        const title = kwargs.title;
        if (title.length > 30) {
            throw new ArgumentError('标题不能超过 30 字');
        }
        const caption = kwargs.caption || '';
        if (caption.length > 1000) {
            throw new ArgumentError('正文不能超过 1000 字');
        }
        const timingTs = toUnixSeconds(kwargs.schedule);
        validateTiming(timingTs);
        const visibilityType = VISIBILITY_MAP[kwargs.visibility] ?? 0;
        const coverPath = kwargs.cover;
        if (coverPath) {
            if (!fs.existsSync(path.resolve(coverPath))) {
                throw new ArgumentError(`封面文件不存在: ${path.resolve(coverPath)}`);
            }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-encode/transcode the video to MP4 (e.g. ffmpeg -i in.mkv -c:v libx264 -c:a aac out.mp4).
  2. Rename the file with a correct supported extension if the container actually matches.
  3. Check that the extension is lowercase-valid; the check is case-insensitive but the extension must still be one of the four.
  4. Update the library if you need a newly supported format.

Example fix

// before
ffmpeg -i screen-recording.mkv -c copy out.mkv
// after
ffmpeg -i screen-recording.mkv -c:v libx264 -c:a aac out.mp4
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['.mp4', '.mov', '.avi', '.webm'];
const ext = path.extname(videoPath).toLowerCase();
if (!SUPPORTED.includes(ext)) throw new Error(`re-encode ${videoPath} (${ext}) to mp4 before publishing`);

Try / catch

try {
  await publish({ video, title });
} catch (e) {
  if (String(e.message).startsWith('不支持的视频格式')) {
    console.error('transcode with ffmpeg to .mp4 and retry');
  }
  throw e;
}

Prevention

When it happens

Trigger: Publishing a file with an extension outside the allowlist — e.g. .mkv, .flv, .ts, .wmv, or a misnamed file like video.mp4.txt (clis/douyin/publish.js:119).

Common situations: Screen recorders producing .mkv/.flv; OBS default mkv output; files downloaded as .webm.part or renamed with wrong extension; concatenating extensionless temp files.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/9c90e7d8c63f12d0. Report an issue: GitHub.