jackwener/OpenCLI · error · ArgumentError
不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm)
Error message
不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm) What it means
The douyin draft command validates the uploaded video's file extension against an allowlist (.mp4, .mov, .avi, .webm) before opening the upload page. If path.extname returns anything else, an ArgumentError is thrown naming the offending extension. This is a client-side guard so the browser automation never submits a file Douyin's uploader will reject.
Source
Thrown at clis/douyin/draft.js:313
domain: 'creator.douyin.com',
strategy: Strategy.COOKIE,
navigateBefore: false,
args: [
{ name: 'video', required: true, positional: true, help: '视频文件路径' },
{ name: 'title', required: true, help: '视频标题(≤30字)' },
{ name: 'caption', default: '', help: '正文内容(≤1000字,支持 #话题)' },
{ name: 'cover', default: '', help: '封面图片路径' },
{ name: 'visibility', default: 'public', choices: ['public', 'friends', 'private'] },
],
columns: ['status', 'draft_id'],
func: async (page, kwargs) => {
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 title = kwargs.title;
if (title.length > 30) {
throw new ArgumentError('标题不能超过 30 字');
}
const caption = kwargs.caption || '';
if (caption.length > 1000) {
throw new ArgumentError('正文不能超过 1000 字');
}
const coverPath = kwargs.cover;
if (coverPath) {
if (!fs.existsSync(path.resolve(coverPath))) {
throw new ArgumentError(`封面文件不存在: ${path.resolve(coverPath)}`);
}
}
if (!page.setFileInput) {
throw new CommandExecutionError('当前浏览器适配器不支持文件注入', '请使用 Browser Bridge 或支持 setFileInput 的浏览器模式');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Convert the video to MP4 (e.g. `ffmpeg -i input.mkv -c copy output.mp4`) and pass the new file
- Rename the file with a supported extension ONLY if the actual container matches (renaming .mkv to .mp4 will fail at upload)
- Check the extension: `node -e "console.log(require('path').extname(process.argv[1]))" yourfile` to confirm what the CLI sees
Example fix
// before
await cli.draft({ video: 'clip.mkv' });
// after
// convert first: ffmpeg -i clip.mkv clip.mp4
await cli.draft({ video: 'clip.mp4' }); Defensive patterns
Strategy: validation
Validate before calling
const ok = ['.mp4', '.mov', '.avi', '.webm'].includes(path.extname(video).toLowerCase());
if (!ok) throw new Error(`Convert ${video} to mp4/mov/avi/webm first`); Type guard
const isSupportedVideo = (p) => ['.mp4', '.mov', '.avi', '.webm'].includes(require('path').extname(String(p)).toLowerCase()); Try / catch
try {
await cli.draft({ video, title });
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('不支持的视频格式')) {
console.error(`Re-encode with: ffmpeg -i ${video} ${video.replace(/\.\w+$/, '')}.mp4`);
} else throw e;
} Prevention
- Standardize recording output to MP4 in OBS/editor settings
- Run ffmpeg batch conversion as a pre-upload step in CI
- Validate extensions in scripts before invoking the CLI
When it happens
Trigger: Calling `opencli douyin draft --video <file>` where the file exists but its extension (case-insensitive) is not .mp4/.mov/.avi/.webm — e.g. .mkv, .flv, .wmv, .m4v, .ts, or a file with no extension.
Common situations: Screen recordings saved as .mkv, GoPro/OBS footage in exotic codecs, renamed files without extensions, or passing a directory path that happens to resolve.
Related errors
- Unsupported image format "${ext}". Supported: jpg, png, gif,
- Unsupported image format "${ext}". Supported: jpg, jpeg, png
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5b223eb023f509ef.
Report an issue: GitHub.