您好,我有一个使用Rails5的应用程序,我在其中添加了用于人脸识别的Face-api.js库。
在我看来,我有用于人脸检测和识别的脚本和视频,但当我转到浏览器并加载页面时,控制台返回以下错误。
Uncaught TypeError: Cannot read property 'addEventListener' of null
at new:161
(anonymous) @ new:161
new:149 NotReadableError: Could not start video source包含脚本和网络摄像头视频的我的视图:
<head>
<%= javascript_include_tag 'face_api'%>
<%= javascript_include_tag "face-api.js/dist/face-api.min.js" %>
<%= javascript_include_tag "face-api.js/dist/face-api.js" %>
<script>
const camfr = document.getElementById('camfr')
const startVideo = () => {
var constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
var video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
}
Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri("<%= asset_path('face-api.js/models/tiny_face_detector/tiny_face_detector_model-weights_manifest.json') %>"),
faceapi.nets.faceLandmark68Net.loadFromUri("<%= asset_path('face-api.js/models/face_landmark_68/face_landmark_68_model-weights_manifest.json') %>"), //desenha os traços do rosto
faceapi.nets.faceRecognitionNet.loadFromUri("<%= asset_path('face-api.js/models/face_recognition/face_recognition_model-weights_manifest.json') %>"),//faz o conhecimento do rosto
faceapi.nets.faceExpressionNet.loadFromUri("<%= asset_path('face-api.js/models/face_expression/face_expression_model-weights_manifest.json') %>"),//detecta expressoes
faceapi.nets.ageGenderNet.loadFromUri("<%= asset_path('face-api.js/models/age_gender_model/age_gender_model-weights_manifest.json') %>"),//idade e genero
faceapi.nets.ssdMobilenetv1.loadFromUri("<%= asset_path('face-api.js/models/ssd_mobilenetv1/ssd_mobilenetv1_model-weights_manifest.json') %>") // usada para detectar rosto
]).then(startVideo)
camfr.addEventListener('play', async () => {
const canvas = faceapi.createCanvasFromMedia(camfr)
const canvasSize = {
width: camfr.width,
height: camfr.height
}
faceapi.matchDimensions(canvas, canvasSize)
document.body.appendChild(canvas)
setInterval(async () => {
const detections = await faceapi
.detectAllFaces(
camfr,
new faceapi.TinyFaceDetectorOptions()
)
.withFaceLandmarks()
.withFaceExpressions()
.withAgeAndGender()
const resizedDetections = faceapi.resizeResults(detections, canvasSize)
canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height)
faceapi.draw.drawDetections(canvas, resizedDetections)
faceapi.draw.drawFaceLandmarks(canvas, resizedDetections)
faceapi.draw.drawFaceExpressions(canvas, resizedDetections)
resizedDetections.forEach(detection => {
const {age, gender, genderProbability} = detection
new faceapi.draw.DrawTextField([
`${parseInt(age, 10)} years`,
`${gender} (${ parseInt(genderProbability * 100, 10)})`
], detection.detection.box.topRight).draw(canvas)
})
}, 100)
})
</script>
</head>
<body>
<video autopĺay id="camfr" width="400" height="400" muted></video>
</body>我不明白这有什么不起作用的--faceapi.js在供应商/资产/javascript上,在assets.rb中,我对新的javascript和faceapi.js模型进行了预编译。
我的脸-api.js
//= require face-api.js/dist/face-api
//= require face-api.js/dist/face-api.js
//= require face-api.js/dist/face-api.min.js发布于 2020-08-08 07:44:33
<head>标记在页面的其余部分之前加载,因此在camfr = document.getElementById('camfr')运行时不会加载DOM。您需要将脚本包装在一个事件中,以确保DOM在执行之前已完全加载。如果你使用turbolinks:
document.addEventListener('turbolinks:load', () => {
const camfr = document.getElementById('camfr');
if (element) {
...
}
});如果不使用turbolink,那么可以使用onload事件而不是turbolinks:load。
此外,使用Javascript的“Rails方式”是将代码提取到资产路径中的一个单独的.js文件中(如果使用的是Rails6,则为webpacker包),而不是直接嵌入到<script>标记中。
https://stackoverflow.com/questions/63309742
复制相似问题