jquery在尝试为缩略图捕获图像时不做任何事情



我有一个视频上传表单,像这样:

<form action='' method='post' id="videoUpload" align = "center" enctype="multipart/form-data">
<input type='hidden' name='id' value='<?php echo $row['videoID'];?>'>
<p><label>Title</label><br />
<input type='text' name='videoTitle' required value='<?php if(isset($error)){ echo $_POST['videoTitle'];}?>'></p>
<p><label>Video</label><br />
<input type="file" name="video" id="video" class="video" accept="video/*" required></p>
<video controls id="video-tag"  onloadedmetadata="$(this).trigger('thumbnail_generation')">
<source id="video-source" src="splashVideo">
</video>
<input type="hidden" id="thumbnail" name="thumbnail" value="" >

<input type="hidden" name='videoDuration' id="videoDuration" required value='<?php if(isset($error)){ echo $_POST['videoDuration'];}?>'></p>
<div id="duration" name="duration">Please choose a video</div>
<script src="duration.js"></script>
<p><input type="submit" value="Submit" name="submit" id="submit" /></p>
</form>

<div id="screen"></div>

我一直在努力做的是,当一个视频上传一个缩略图得到生成,为此,我发现了另一个堆栈溢出问题在这里:http://jsfiddle.net/vphyr/

所以我一直在尝试更新这一点,以便在视频上传时调用该函数,而不必点击按钮来运行它。

var VideoSnapper = {

/**
* Capture screen as canvas
* @param {HTMLElement} video element 
* @param {Object} options = width of screen, height of screen, time to seek
* @param {Function} handle function with canvas element in param
*/
captureAsCanvas: function(video, options, handle) {

// Create canvas and call handle function
var callback = function() {
// Create canvas
var canvas = $('<canvas />').attr({
width: options.width,
height: options.height
})[0];
// Get context and draw screen on it
canvas.getContext('2d').drawImage(video, 0, 0, options.width, options.height);
let image = canvas.toDataURL();
document.getElementById("thumbnail").value = image;
canvas.style.display="none";
// Seek video back if we have previous position 
if (prevPos) {
// Unbind seeked event - against loop
$(video).unbind('seeked');
// Seek video to previous position
video.currentTime = prevPos;
}
// Call handle function (because of event)
handle.call(this, canvas);    
}
// If we have time in options 
if (options.time && !isNaN(parseInt(options.time))) {
// Save previous (current) video position
var prevPos = video.currentTime;
// Seek to any other time
video.currentTime = options.time;
// Wait for seeked event
$(video).bind('seeked', callback);              
return;
}

// Otherwise callback with video context - just for compatibility with calling in the seeked event
return callback.apply(video);
}
};
$(function() {

$('video').bind('thumbnail_generation', function() {
var video = this;
$("#video-source").change(function() {
var canvases = $('canvas');
VideoSnapper.captureAsCanvas(video, { width: 160, height: 68, time: 40 }, function(canvas) {
$('#screen').append(canvas);                         
if (canvases.length == 4) 
canvases.eq(0).remove();     
})
}); 
});

});

然而,从做:$("# videosource").change(function(){什么都没有发生,我没有得到任何错误

在js的例子中,已经有预加载的视频,所以我添加了一个脚本,这样当一个文件被上传时,视频源就会被更新为这样的文件:

const videoSrc = document.querySelector("#video-source");
const videoTag = document.querySelector("#video-tag");
const inputTag = document.querySelector("#video");

inputTag.addEventListener('change',  readVideo)

function readVideo(event) {
if (event.target.files && event.target.files[0]) {
var reader = new FileReader();

reader.onload = function(e) {
videoSrc.src = e.target.result
videoTag.load()
}.bind(this)

reader.readAsDataURL(event.target.files[0]);
}
}

所以我的想法是,我应该得到的功能运行时,视频源更新,但不幸的是,我没有任何运气,有人可以帮助我吗?我哪里做错了?

编辑:

所以我刚刚又试着修复了一下,仍然在努力让它工作。

我已经尝试使用onloaddmeta如下:

$(function() {
$('video').bind('thumbnail_generation', function() {
var video = this;
var vid = document.getElementById("video-tag");
vid.onloadedmetadata = function() {
// $('#capture').click(function() {
var canvases = $('canvas');
VideoSnapper.captureAsCanvas(video, { width: 160, height: 68, time: 40 }, function(canvas) {
$('#screen').append(canvas);                         
if (canvases.length == 4) 
canvases.eq(0).remove();     
})
// });
}
});

});

然而,没有任何事情发生,我现在试着做Louys建议的,并使用一个突变观察者,像这样:

$(function() {

$('video').bind('thumbnail_generation', function() {
var video = this;
var img = document.querySelector("#video-tag video"),
observer = new MutationObserver((changes) => {
changes.forEach(change => {
if(change.attributeName.includes('src')){
console.dir(img.src);
var canvases = $('canvas');
VideoSnapper.captureAsCanvas(video, { width: 160, height: 68, time: 40 }, function(canvas) {
$('#screen').append(canvas);                         
if (canvases.length == 4) 
canvases.eq(0).remove();     
})
}
});
});
});
observer.observe(img, {attributes : true});
});

有了这个,然而,我得到了错误:add- videoos .php:159未捕获类型错误:在MutationObserver上执行'observe'失败:参数1不是'Node'类型。

我不太确定这个错误是什么意思。我的思路对吗?有人对我如何解决这个问题有任何建议吗?

Thanks in advance

我只是无法重现您的问题…所以这里有一些关于自己调试的提示:

您要检测的src更改位于<source>元素上。

<video controls id="video-tag"  onloadedmetadata="$(this).trigger('thumbnail_generation')">
<source id="video-source" src="splashVideo">
</video> 

现在,调试observe()功能,把一些控制台日志无处不在,你可以能够知道它可能卡住:

$(function() {
$('video').on('thumbnail_generation', function() {

console.log("thumbnail_generation event fired.")

var video = this;
var img = document.querySelector("#video-source");

console.log("This is img:", img) // Should output : "This is img:" "<source id='video-source' src='splashVideo'>"

var observer = new MutationObserver((changes) => {

console.log("A change occurred")

changes.forEach(change => {

console.log("change object:", change) // Should ouput all change objects.

if(change.type === "attributes" && change.attributeName === "src"){

console.log(img.src);  // Should output the new src value

// I can't tell about the rest...
var canvases = $('canvas');
VideoSnapper.captureAsCanvas(video, { width: 160, height: 68, time: 40 }, function(canvas) {
$('#screen').append(canvas);                         
if (canvases.length == 4) 
canvases.eq(0).remove();     
})

}
});
});

// Call the observe() function here
observer.observe(img, {attributes : true});

});

});

另外,jQuery .bind()自jQuery 3.0以来已弃用…因此,即使它仍然有效,我建议您开始使用。on()方法。

如果其他人偶然发现了我遇到的同样的问题,我实际上只需要将其更改为:

$(function() {
$('video').bind('thumbnail_generation', function() {
let video = this;
let canvases = $('canvas');
VideoSnapper.captureAsCanvas(video, { width: 160, height: 68, time: 40 }, function(canvas) {
$('#screen').append(canvas);                         
if (canvases.length == 4) 
canvases.eq(0).remove();     
})
});
});

原来我想得太多了,什么都没发生的原因是当这个剧本已经到达的时候,视频源已经改变了,所以在这一点上没有改变。

最新更新