我尝试在用户单击视频中的对象时在视频上显示对象数据,但遇到一些困难。
问题:
除了 Google Vision API 之外,我还使用 MERN 堆栈,并将数据存储在我的 MongoDB 中,并且可以通过 Postman 获取数据,但是当我单击浏览器中的对象时,不会发出获取请求,也不会发生任何事情。
我使用函数
fetchObjectData
来获取数据。
我想我必须获得每个帧中对象的位置并进行必要的对应,但我不太确定。似乎无法弄清楚,所以如果有人有建议,我很乐意听到他们!
我尝试过的:
我尝试过制作各种控制台。日志,但我没有收到任何错误,并且“网络”选项卡也没有告诉我任何信息 - 没有发出提取请求。我尝试在 YouTube 上搜索用于制作可点击视频的 Google Vision API 演示以及搜索文档,但没有找到任何结果。
我的代码:
客户
import React, { useEffect, useState } from 'react';
function VideoPlayer() {
const [objects, setObjects] = useState([]);
const [selectedObject, setSelectedObject] = useState(null);
const [videoUrl, setVideoUrl] = useState('');
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(true);
// Fetch object data when an object is clicked
function fetchObjectData(objectId) {
// Set loading state while fetching
setIsLoading(true);
// Fetch detected object data for the specific object
fetch(`http://localhost:3001/annotation/${objectId}`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json(); // Assuming the response contains JSON data
})
.then(data => {
setSelectedObject(data); // Update selectedObject with the fetched data
setIsLoading(false); // Clear loading state
})
.catch(error => {
console.error('Error fetching object data:', error);
setIsLoading(false); // Clear loading state on error
});
}
useEffect(() => {
// Fetch video URL from the backend
fetch('http://localhost:3001/videourl')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const contentType = response.headers.get('content-type');
if (contentType && contentType.startsWith('video')) {
return response.blob();
} else {
console.error('Unexpected response type:', contentType);
setError(new Error('Unexpected response type'));
}
})
.then(videoBlob => {
setVideoUrl(URL.createObjectURL(videoBlob));
})
.catch(error => {
console.error('Error fetching video URL:', error);
setError(error);
});
}, []);
function handleObjectClick(objectId) {
console.log('Clicked object ID:', objectId);
// Clear selectedObject when a new object is clicked
setSelectedObject(null);
// Fetch object data when an object is clicked
fetchObjectData(objectId);
}
return (
<div>
{error ? (
<div>Error: {error.message}</div>
) : (
<>
<video
src={videoUrl}
muted
autoPlay
playsInline
loop
style={{ width: '100%', height: '300pt' }}
/>
<div className="annotationsContainer">
{isLoading ? (
<div>Loading data...</div>
) : (
objects.map((object, index) => (
<div
key={index}
className="annotation"
onClick={() => handleObjectClick(object.id)}
>
<strong>{object.entity.description}</strong>
<br />
Confidence: {object.confidence}
</div>
))
)}
</div>
{selectedObject && (
<div className="selectedObject">
<strong>Selected Object:</strong> {selectedObject.entity.description}
<br />
Confidence: {selectedObject.confidence}
</div>
)}
</>
)}
</div>
);
}
export default VideoPlayer;
服务器和路由
const express = require('express');
const router = express.Router();
const {ObjectModel} = require('../../model/index');
router.get('/:objectId', async (req, res) => {
const objectId = req.params.objectId;
try {
// Use the objectId to retrieve the specific object from the database
const object = await ObjectModel.findById(objectId);
if (!object) {
return res.status(404).json({ error: 'Object not found' });
}
res.json(object);
} catch (error) {
console.error('Error fetching object:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});
module.exports = router;
const router = require('express').Router();
const annotationRoutes = require('./api/annotationroute');
const videoURLRoutes = require('./api/videourlroute');
router.use('/annotation', annotationRoutes);
router.use('/videourl', videoURLRoutes);
router.use((req, res) => {
return res.send('Wrong route!');
});
module.exports = router;
型号
const { Schema, model } = require('mongoose');
const objectSchema = new Schema({
objectDescription: {
type: String,
},
objectEntityId: {
type: String,
},
objectStartTime: {
type: String,
},
objectEndTime: {
type: String,
},
objectConfidence: {
type: Number,
},
});
const ObjectModel = model('Object', objectSchema);
module.exports = ObjectModel;
您需要像这样设置代码:
fetch( "http://localhost:3001/annotation/" + `${objectId}` )
或者...
由于您的函数获得了一个参数,因此只需使用传入参数名称,如下所示:
fetch( "http://localhost:3001/annotation/" + objectId )
所以理想的是:
使用
+ ${objectId}
访问 DOM 中某处存在的变量(例如: 在 Window 中)。
在函数希望通过名称引用其输入
参数时使用
+ objectId
。
可能的解决方案:
尝试看看下面的修改版本是否开始向您的文件路径发出 Fetch 请求...
/*
//# Where...
//# Fetch object data when an object is clicked
fetchObjectData(objectId); //# add function parameter: objectId
*/
//## Fetch object data when an object is clicked
function fetchObjectData( my_objectId )
{
//# Set loading state while fetching
setIsLoading(true);
//# Fetch detected object data for the specific object
//fetch( "http://localhost:3001/annotation/" + `${objectId}` ) //# only if objectId is a Global var
fetch( "http://localhost:3001/annotation/" + my_objectId ) //# access via the given func parameter name
.then(response => {
if (!response.ok) {
throw new Error("HTTP error! Status: " + response.status); //# or `${response.status}`
}
return response.json(); //# Assuming the response contains JSON data
})
.then(data => {
setSelectedObject(data); //# Update selectedObject with the fetched data
setIsLoading(false); //# Clear loading state
})
.catch(error => {
console.error("Error fetching object data: ", error);
setIsLoading(false); //# Clear loading state on error
});
}