-
-
Notifications
You must be signed in to change notification settings - Fork 691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
preloading video #535
preloading video #535
Conversation
@andytwoods @jodeleeuw |
Any pref what I have a go at next Josh? There was something about blocking automatic preloading? |
@andytwoods Anything on the issues list that you feel comfortable tackling would be awesome! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @andytwoods -- finally had a chance to look this over more carefully. couple small change requests if you have the time... thanks again!
jspsych.js
Outdated
audio = typeof audio === 'undefined' ? [] : audio; | ||
images = images || []; | ||
audio = audio || []; | ||
video = video || video; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is line 2379 right? why video || video?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch, yes, mistake. Fixing.
plugins/jspsych-video.js
Outdated
var video_blob = jsPsych.pluginAPI.getVideoBuffer(file_name); | ||
if(!video_blob) throw(file_name + ' (video) not preloaded') | ||
|
||
display_element.childNodes[0].src = video_blob; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this fall back to the old way of doing it when !video_blob
is true
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exploring. May well work if I remove that throw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. I just reintegrated some of the past code.
Josh, maybe you want the below function instead of my var x = x || 'bla'. See this https://stackoverflow.com/questions/5409641/javascript-set-a-variable-if-undefined module.setIfNull = function(val, def_val) { |
I've just pushed some changes :) |
@@ -97,20 +97,33 @@ jsPsych.plugins.video = (function() { | |||
video_html += trial.prompt; | |||
} | |||
|
|||
display_element.innerHTML = video_html; | |||
var video_preload_blob = jsPsych.pluginAPI.getVideoBuffer(file_name); | |||
if(!video_preload_blob) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it is possible/desirable to move this conditional inside the getVideoBuffer function? If the function could return something that worked for preloaded and non-preloaded video that could simplify the implementation requirements for plugins that add video.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To do everything within getVideoBuffer, we'd need to pass getVideoBuffer the display Element and a partly formed "<video " node.
But I can simplify it (see below).
var file_name = trial.sources[0];
var video_preload_blob = jsPsych.pluginAPI.getVideoBuffer(file_name);
if(!video_preload_blob) {
if(file_name.indexOf('?') > -1){
file_name = file_name.substring(0, file_name.indexOf('?'));
}
var type = file_name.substr(file_name.lastIndexOf('.') + 1);
type = type.toLowerCase();
video_html+='><source src="' + file_name + '" type="video/'+type+'"></video>';
display_element.innerHTML = video_html;
}
else{
video_html+=">"
display_element.innerHTML = video_html;
display_element.childNodes[0].src = video_preload_blob;
}
display_element.querySelector('#jspsych-video-player').onended = function(){
end_trial();
}
// event handler to set timeout to end trial if video is stopped
display_element.querySelector('#jspsych-video-player').onplay = function(){
if(trial.stop !== null){
if(trial.start == null){
trial.start = 0;
}
jsPsych.pluginAPI.setTimeout(end_trial, (trial.stop-trial.start)*1000);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any thoughts Josh?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struggling a little to understand exactly what's happening, so apologies if this doesn't make sense.
Since you set the src
of the video object to be the output of the call to getVideoBuffer
, couldn't the function just return the appropriate path if the video was not preloaded?
Maybe the answer is no because you need to use <source>
tags. In this case could the getVideoBuffer
function actually return the whole video player object? Maybe by creating a document fragment that can be appended to the DOM inside the plugin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I did it that way because you created the video originally by creating a string specifying the node.
getVideoBuffer returns undefined when no video is prebuffered as getAudioBuffer does it this way.
I worry that Document Fragment usage will lead to backward compatibilty issues over webbrowsers.
var video_html = '<video id="jspsych-video-player"'
if(trial.width) {
video_html += ' width="'+trial.width+'"'
}
if(trial.height) {
video_html += ' height="'+trial.height+'"'
}
if(trial.autoplay){
video_html += " autoplay "
}
if(trial.controls){
video_html +=" controls "
}
//show prompt if there is one
if (trial.prompt !== null) {
video_html += trial.prompt;
}
var file_name = trial.sources[0];
var video_preload_blob = jsPsych.pluginAPI.getVideoBuffer(file_name);
if(!video_preload_blob) {
if(file_name.indexOf('?') > -1){
file_name = file_name.substring(0, file_name.indexOf('?'));
}
var type = file_name.substr(file_name.lastIndexOf('.') + 1);
type = type.toLowerCase();
video_html+='><source src="' + file_name + '" type="video/'+type+'"></video>';
display_element.innerHTML = video_html;
}
else{
video_html+=">"
display_element.innerHTML = video_html;
display_element.childNodes[0].src = video_preload_blob;
}
All tests passing. Afraid no new tests. Writing such tests would be hard.
I removed the necessity to have height and width of video specified too.
Hoping my syntax is ok with you. eg var scoobydoo = scoobydoo || 123
I worry that below, my adding 'opts.preload_video' below may have scrambled people's own studies (that is, if jsPsych.pluginAPI.autoPreload is used by experimenters... hopefully it is just internal).
jsPsych.pluginAPI.autoPreload(timeline, startExperiment, opts.preload_images, opts.preload_audio, opts.preload_video, opts.show_preload_progress_bar);