Bing Visual Search API能否单次事务处理多张图片?视频帧批量咨询
问题解答
核心结论
Bing Visual Search API 不支持将多张图片合并为单次事务处理,每个API请求只能处理单张图片,这是该API的设计限制,因此每一张图片都会被计为一次独立事务。
成本与效率优化方案
既然无法合并事务,可通过以下方式降低成本并提升批量处理能力:
- 帧预处理去重:先对提取的视频帧进行相似性去重(如使用dHash、pHash算法计算图片哈希值,过滤重复或高度相似的帧),只保留关键帧进行API调用。比如原本1000帧的视频,筛选后可能仅需处理200帧,直接将成本从15美元降至3美元。
- 控制请求并发数:当前代码使用
Promise.all无限制并发请求,即使升级到S9层级,也可能触发API限流。建议使用p-limit等库控制并发数(比如设置为50并发),既利用S9的高QPS配额,又避免请求被拒绝。 - 动态设置Content-Type:代码中硬编码了
contentType: 'image/jpeg',需根据文件扩展名动态判断(如.png对应image/png),避免因类型不匹配导致API请求失败。
代码优化示例
以下是加入并发控制和动态Content-Type的优化版本:
const pLimit = require('p-limit'); const limit = pLimit(50); // 控制并发数为50 exports.analyzeResubmittedFramesAndReturnWebSearchResults = async (framesArr) => { // 用p-limit包装请求,控制并发 const analyzeFramesPromise = framesArr.map(file => limit(() => analyzeSingleFrame(file))); const frameAnalysisResult = await Promise.all(analyzeFramesPromise); return frameAnalysisResult; }; async function analyzeSingleFrame(request) { try { const subscriptionKey = bingSearchConfig.subscriptionKey; const form = new FormData(); let imageData, contentType; if (request.includes("http")) { const imageResponse = await axios.get(request, { responseType: 'stream' }); imageData = imageResponse.data; // 从URL提取扩展名判断Content-Type const urlExt = new URL(request).pathname.split('.').pop(); contentType = urlExt === 'png' ? 'image/png' : 'image/jpeg'; } else { const filePath = path.resolve(request); imageData = fs.createReadStream(filePath); // 从本地文件提取扩展名判断Content-Type const fileExt = path.extname(filePath).slice(1); contentType = fileExt === 'png' ? 'image/png' : 'image/jpeg'; } form.append('image', imageData, { filename: `image.${contentType.split('/')[1]}`, contentType: contentType }); const requestOptions = { method: 'POST', url: appConstants.bingWebSearchEndPoint, headers: { 'Ocp-Apim-Subscription-Key': subscriptionKey, ...form.getHeaders() }, data: form }; const response = await axios(requestOptions); const hostPageData = []; response.data.tags.forEach(tag => { tag.actions.forEach(action => { if (action.actionType === "PagesIncluding") { action.data.value.forEach(pageData => { hostPageData.push(pageData); }); } }); }); return { frameAnalysis: hostPageData, frame: request }; } catch (error) { console.error(`分析帧出错: ${request}`, error); return { frameAnalysis: [], frame: request }; // 错误返回空数组而非空对象,保持结构一致 } }
额外提示
升级到S9层级后,可查看Azure门户中的API使用统计,根据实际处理量调整帧筛选的严格程度,平衡分析精度与成本。
内容的提问来源于stack exchange,提问作者Nishtha Bansal
相关产品推荐
相关产品推荐

