如何制作交互式视频,当用户单击某个对象时,该对象的数据会显示在屏幕上?

问题描述 投票:0回答:1

我尝试在用户单击视频中的对象时在视频上显示对象数据,但遇到一些困难。

问题:
除了 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;

reactjs html5-video mern video-processing google-vision
1个回答
0
投票

您需要像这样设置代码:

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
      });
}
© www.soinside.com 2019 - 2024. All rights reserved.