const models = require('../../models'); const fetch = require('node-fetch'); let apiKey = require('process').env.ARK_API_KEY; const url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"; let headers = { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } /** * 豆包视觉API * 从豆包获取图片的标题和文案描述 * @param {*} imageUrl */ async function fetchMetaByImageFromDoubao(imageUrl) { let data = { "model": "ep-20250206115552-7qg5c", // Doubao-1.5...ion-pro-32k 当前最新,贵,响应慢,效果好 // "model": "ep-20250204231910-4phb8", // Doubao-vision-lite-32k 便宜点,相应速度快 "messages": [ { "role": "user", "content": [ { "type": "text", "text": "根据图片生成一个简短标题(title), 以json格式输出,支持语言中文(zh)、英语(en)、西班牙语(es)、葡萄牙语(pt)、日语(ja),形如: { title: {zh:'', en:'', es: '', pt: '', ja: ''}}" }, { "type": "image_url", "image_url": { "url": `${imageUrl}` } } ] } ] } console.log(data); const jsonData = JSON.stringify(data); const response = await fetch(url, { method: 'POST', headers, body: jsonData }); let responseJson = await response.json(); console.log(responseJson); return responseJson.choices[0].message.content; } async function runArtMeta() { let done = 0; let duration = 0; let hour, minute, second; let start = Date.now(); // 筛选出所有已经ready并且还没有title的图 let query = { status: { $gte: 7000 }, $or: [{ subtitle: { $exists: false } }, { subtitle: null }] }; let docs = await models.Art.find(query).limit(1000).sort({ publishTime: 'desc' }); // 内存有限,每次跑1000个 let total = docs.length; console.log('total:', total); if (total <= 0) return; for (let doc of docs) { console.log(`process ${doc._id}`); let thumbUrl = `http://color.jccytech.cn/thumbs/v2/work/320/${doc._id}.png`; if (doc.hasSpecial) { thumbUrl = `http://color.jccytech.cn/thumbs/v2/special/320/${doc._id}.png`; } console.time(doc._id); try { let metaInfo = await fetchMetaByImageFromDoubao(thumbUrl); console.log(metaInfo); let metaInfoJson = JSON.parse(metaInfo); let titleJson = metaInfoJson.title; let title = JSON.stringify(titleJson); doc.subtitle = title; await doc.save(); } catch (e) { console.error(e.message); } console.timeEnd(doc._id); done++; duration = (Date.now() - start) / 1000; hour = (Math.floor(duration / 60 / 60)).toString().padStart(2, '0'); minute = (Math.floor(duration / 60) % 60).toString().padStart(2, '0'); second = (Math.floor(duration) % 60).toString().padStart(2, '0'); console.log('progress: ' + Math.floor((100 * done / total)) + '% used time: ' + hour + ':' + minute + ':' + second); } runArtMeta(); } async function run() { await runArtMeta(); } async function test() { let metaInfo = await fetchMetaByImageFromDoubao("https://color.jccytech.cn/thumbs/v2/work/640/67a254ec4f9d65537938e5c5.png"); console.log(metaInfo); let metaInfoJson = JSON.parse(metaInfo); let titleJson = metaInfoJson.title; let descJson = metaInfoJson.copy; let title = JSON.stringify(titleJson); let desc = JSON.stringify(descJson); console.log(title); console.log(desc); } module.exports = { run } if (require.main == module) { run(); }