Reputation: 1273
I have a couple of these html blocks in a foreach loop:
<label class="">Replace video:</label>
<input type="file" name="replaced_main_video" class="input-video-preview" />
<!-- replaced main video -->
<video class="video" controls>
<source type="video/mp4">
</video>
<canvas></canvas>
<label class="">Preview replaced video:</label><br />
<img class="video-preview" width="100" src="#" />
For showing a preview from the chosen video that is uploaded, is use this js code:
$(function() {
var video = $('.video');
var thumbnail = $('canvas');
var input_video_preview = $('.input-video-preview');
var ctx = thumbnail.get(0).getContext("2d");
var duration = 0;
var img = $('.video-preview');
input_video_preview.on('change', function(e) {
var file = e.target.files[0];
// Set video source
video.find('source').attr('src', URL.createObjectURL(file));
// Load the video
video.get(0).load();
// Load metadata of the video to get video duration and dimensions
video.on('loadedmetadata', function(e) {
duration = video.get(0).duration;
// Set canvas dimensions same as video dimensions
thumbnail[0].width = video[0].videoWidth;
thumbnail[0].height = video[0].videoHeight;
// Set video current time to get some random image
video[0].currentTime = Math.ceil(duration / 2);
// Draw the base-64 encoded image data when the time updates
video.one("timeupdate", function() {
ctx.drawImage(video[0], 0, 0, video[0].videoWidth, video[0].videoHeight);
//$('.video-preview').attr("src", thumbnail[0].toDataURL());// THIS WORKS, but all imgs get src
$('.input-video-preview').next('.video-preview').attr("src", thumbnail[0].toDataURL()); // bind to the next img with class 'video-preview'
});
});
});
});
This works fine, but because the html blocks are repeated by a foreach, every img
gets the source. and i want only the next img
tag after the input type="file"
I tried to achieve this with this line below in the function:
$('.input-video-preview').next('.video-preview').attr("src", thumbnail[0].toDataURL()); // get input with class 'input-video-preview', take the next img with class '.video-preview' and bind it to the `src` attribute
But unfortunatley, this does not work.... How can i achieve this?
Upvotes: 1
Views: 141
Reputation: 807
To reference the specific input
, usually we use $(this)
inside the function:
$(this).next('.video-preview')
instead of
$('.input-video-preview').next('.video-preview')
Edit
As you have many nested calls to on()
, the command $(this)
may change context and not target the <input>
component. So you may need to do something like this:
input_video_preview.on('change', function(e) {
var selectedInput = $(this);
//...
//...
selectedInput.nextAll('.video-preview').eq( 0 ).attr("src", thumbnail[0].toDataURL());
});
Edit 2
Besides the topic of your question, there are other aspects of your code that may prevent it from working.
You should not before hand define the video
, thumbnail
and img
vars. This vars depend on the input that was choosen.
So you should define than inside the on()
using the nextAll()
as well, like that:
$(function() {
var input_video_preview = $('.input-video-preview');
var duration = 0;
input_video_preview.on('change', function(e) {
var selectedInput = $(this);
var video = selectedInput.nextAll('.video');
var thumbnail = selectedInput.nextAll('canvas');
var ctx = thumbnail.get(0).getContext("2d");
var img = selectedInput.nextAll('.video-preview');
var file = e.target.files[0];
//...
});
})
Upvotes: 2