3

I have a single web page with an embedded Vimeo video.

I am using javascript and froogaloop for the listening functions and have got it to work. On finish the web page is redirected and I have coded it so that the player cannot be skipped forward.

The Vimeo video I am using is password protected so the first thing that it prompts for when the page/video loads is the password. When I enter the password it starts at the beginning of the video but the ready event does not work (or pick up that there is even a video there). I have two buttons under the video, play and pause. These do not work, but I can play the video via the play icon actually on the video. So the video will play but not with the froogaloop functionality.

    var vimeoPlayers = document.querySelectorAll('iframe'),
                player;

            for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
                player = vimeoPlayers[i];
                $f(player).addEvent('ready', ready);

            }
                    <dd><button class="play">Play</button></dd>
                    <dd><button class="pause">Pause</button></dd>

If I refresh the page it will detect the player and video. All the functionality of froogaloop then works.

I need to have the video password protected. Is there another way to detect the Vimeo video or can anyone think of a fix?

Full javascript code:

        (function(){

            // Listen for the ready event for any vimeo video players on the page
            var vimeoPlayers = document.querySelectorAll('iframe'),
                player;

            for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
                player = vimeoPlayers[i];
                $f(player).addEvent('ready', ready);

            }

            /**

             * Utility function for adding an event. Handles the inconsistencies
             * between the W3C method for adding events (addEventListener) and
             * IE's (attachEvent).
             */
            function addEvent(element, eventName, callback) {
                if (element.addEventListener) {
                    element.addEventListener(eventName, callback, false);
                }
                else {
                    element.attachEvent('on' + eventName, callback);
                }
            }

            /**
             * Called once a vimeo player is loaded and ready to receive
             * commands. You can add events and make api calls only after this
             * function has been called.
             */
            function ready(player_id) {
                // Keep a reference to Froogaloop for this player
                var container = document.getElementById(player_id).parentElement.parentElement,
                    froogaloop = $f(player_id),
                    apiConsole = container.querySelector('.console .output');

                /**
                 * Prepends log messages to the example console for you to see.
                 */
                function apiLog(message) {
                    apiConsole.innerHTML = message + '\n' + apiConsole.innerHTML;
                }

                /**
                 * Sets up the actions for the buttons that will perform simple
                 * api calls to Froogaloop (play, pause, etc.). These api methods
                 * are actions performed on the player that take no parameters and
                 * return no values.
                 */
                function setupSimpleButtons() {
                    var buttons = container.querySelector('div dl.simple'),
                        playBtn = buttons.querySelector('.play'),
                        pauseBtn = buttons.querySelector('.pause'),
                        unloadBtn = buttons.querySelector('.unload');

                    // Call play when play button clicked
                    addEvent(playBtn, 'click', function() {
                        froogaloop.api('play');
                    }, false);

                    // Call pause when pause button clicked
                    addEvent(pauseBtn, 'click', function() {
                        froogaloop.api('pause');
                    }, false);

                    // Call unload when unload button clicked
                    addEvent(unloadBtn, 'click', function() {
                        froogaloop.api('unload');
                    }, false);
                }

                /**
                 * Sets up the actions for the buttons that will modify certain
                 * things about the player and the video in it. These methods
                 * take a parameter, such as a color value when setting a color.
                 */
                function setupModifierButtons() {
                    var buttons = container.querySelector('div dl.modifiers'),
                        seekBtn = buttons.querySelector('.seek'),
                        volumeBtn = buttons.querySelector('.volume'),
                        loopBtn = buttons.querySelector('.loop'),
                        colorBtn = buttons.querySelector('.color'),
                        randomColorBtn = buttons.querySelector('.randomColor'),
                        loadVideoBtn = buttons.querySelector('.load');

                    // Call seekTo when seek button clicked
                    addEvent(seekBtn, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        // Grab the value in the input field
                        var seekVal = this.querySelector('input').value;

                        // Call the api via froogaloop
                        froogaloop.api('seekTo', seekVal);
                    }, false);

                    // Call setVolume when volume button clicked
                    addEvent(volumeBtn, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        // Grab the value in the input field
                        var volumeVal = this.querySelector('input').value;

                        // Call the api via froogaloop
                        froogaloop.api('setVolume', volumeVal);
                    }, false);

                    // Call setLoop when loop button clicked
                    addEvent(loopBtn, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        // Grab the value in the input field
                        var loopVal = this.querySelector('input').value;

                        //Call the api via froogaloop
                        froogaloop.api('setLoop', loopVal);
                    }, false);

                    // Call setColor when color button clicked
                    addEvent(colorBtn, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        // Grab the value in the input field
                        var colorVal = this.querySelector('input').value;

                        // Call the api via froogaloop
                        froogaloop.api('setColor', colorVal);
                    }, false);

                    // Call setColor with a random color when random color button clicked
                    addEvent(randomColorBtn, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        // Generate a random color
                        var colorVal = Math.floor(Math.random() * 16777215).toString(16);

                        // Call the api via froogaloop
                        froogaloop.api('setColor', colorVal);
                    }, false);

                    addEvent(loadVideoBtn, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        var videoVal = this.querySelector('input').value;

                        // Call the api via froogaloop
                        froogaloop.api('loadVideo', videoVal);
                    }, false);
                }

                /**
                 * Sets up actions for buttons that will ask the player for something,
                 * such as the current time or duration. These methods require a
                 * callback function which will be called with any data as the first
                 * parameter in that function.
                 */
                function setupGetterButtons() {
                    var buttons = container.querySelector('div dl.getters'),
                        timeBtn = buttons.querySelector('.time'),
                        durationBtn = buttons.querySelector('.duration'),
                        colorBtn = buttons.querySelector('.color'),
                        urlBtn = buttons.querySelector('.url'),
                        embedBtn = buttons.querySelector('.embed'),
                        pausedBtn = buttons.querySelector('.paused'),
                        getVolumeBtn = buttons.querySelector('.getVolume'),
                        widthBtn = buttons.querySelector('.width'),
                        heightBtn = buttons.querySelector('.height');

                    // Get the current time and log it to the API console when time button clicked
                    addEvent(timeBtn, 'click', function(e) {
                        froogaloop.api('getCurrentTime', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('getCurrentTime : ' + value);
                        });
                    }, false);

                    // Get the duration and log it to the API console when time button clicked
                    addEvent(durationBtn, 'click', function(e) {
                        froogaloop.api('getDuration', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('getDuration : ' + value);
                        });
                    }, false);

                    // Get the embed color and log it to the API console when time button clicked
                    addEvent(colorBtn, 'click', function(e) {
                        froogaloop.api('getColor', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('getColor : ' + value);
                        });
                    }, false);

                    // Get the video url and log it to the API console when time button clicked
                    addEvent(urlBtn, 'click', function(e) {
                        froogaloop.api('getVideoUrl', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('getVideoUrl : ' + value);
                        });
                    }, false);

                    // Get the embed code and log it to the API console when time button clicked
                    addEvent(embedBtn, 'click', function(e) {
                        froogaloop.api('getVideoEmbedCode', function (value, player_id) {
                            // Use html entities for less-than and greater-than signs
                            value = value.replace(/</g, '&lt;').replace(/>/g, '&gt;');

                            // Log out the value in the API Console
                            apiLog('getVideoEmbedCode : ' + value);
                        });
                    }, false);

                    // Get the paused state and log it to the API console when time button clicked
                    addEvent(pausedBtn, 'click', function(e) {
                        froogaloop.api('paused', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('paused : ' + value);
                        });
                    }, false);

                    // Get the paused state and log it to the API console when time button clicked
                    addEvent(getVolumeBtn, 'click', function(e) {
                        froogaloop.api('getVolume', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('volume : ' + value);
                        });
                    }, false);

                    // Get the paused state and log it to the API console when time button clicked
                    addEvent(widthBtn, 'click', function(e) {
                        froogaloop.api('getVideoWidth', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('getVideoWidth : ' + value);
                        });
                    }, false);

                    // Get the paused state and log it to the API console when time button clicked
                    addEvent(heightBtn, 'click', function(e) {
                        froogaloop.api('getVideoHeight', function (value, player_id) {
                            // Log out the value in the API Console
                            apiLog('getVideoHeight : ' + value);
                        });
                    }, false);
                }

                /**
                 * Adds listeners for the events that are checked. Adding an event
                 * through Froogaloop requires the event name and the callback method
                 * that is called once the event fires.
                 */
                function setupEventListeners() {
                    var checkboxes = container.querySelector('.listeners'),
                        loadProgressChk = checkboxes.querySelector('.loadProgress'),
                        playProgressChk = checkboxes.querySelector('.playProgress'),
                        playChk = checkboxes.querySelector('.play'),
                        pauseChk = checkboxes.querySelector('.pause'),
                        finishChk = checkboxes.querySelector('.finish'),
                        seekChk = checkboxes.querySelector('.seek'),
                        current = 0, // added david variable to keep time of video
                        cuechangeChk = checkboxes.querySelector('.cuechange');

                    function onLoadProgress() {
                        if (loadProgressChk.checked) {
                            froogaloop.addEvent('loadProgress', function(data) {
                                apiLog('loadProgress event : ' + data.percent + ' : ' + data.bytesLoaded + ' : ' + data.bytesTotal + ' : ' + data.duration);
                                current = data.seconds; // keeps track of video time to be used for seek
                            });
                        }
                        else {
                            froogaloop.removeEvent('loadProgress');
                        }
                    }

                    function onPlayProgress() {
                        if (playProgressChk.checked) {
                            froogaloop.addEvent('playProgress', function(data) {
                                apiLog('playProgress event : ' + data.seconds + ' : ' + data.percent + ' : ' + data.duration);
                            });
                        }
                        else {
                            froogaloop.removeEvent('playProgress');
                        }
                    }

                    function onPlay() {
                        if (playChk.checked) {
                            froogaloop.addEvent('play', function(data) {
                                apiLog('play event');
                            });
                        }
                        else {
                            froogaloop.removeEvent('play');
                        }
                    }

                    function onPause() {
                        if (pauseChk.checked) {
                            froogaloop.addEvent('pause', function(data) {
                                apiLog('pause event');
                            });
                        }
                        else {
                            froogaloop.removeEvent('pause');
                        }
                    }

                    function onFinish() {
                        if (finishChk.checked) {

                            froogaloop.addEvent('finish', function(data) {
                                apiLog('finish');
                                // added david when video finishes redirect to nbext section
                            window.location.href = "http://";
                            });

                        }
                        else {
                            froogaloop.removeEvent('finish');
                        }
                    }

                    function onSeek() {
                        if (seekChk.checked) {
                            froogaloop.addEvent('seek', function(data) {
                                apiLog('seek event : ' + data.seconds + ' : ' + data.percent + ' : ' + data.duration);
                                    // added by david if seek forward then reload the video        
                                     //   if  (data.seconds > current) {
                      //                                 froogaloop.api('unload'); 
                      //                                         }
                                                   });
                        }
                        else {
                            froogaloop.removeEvent('seek');
                        }
                    }

                    function onCueChange() {
                        if (cuechangeChk.checked) {
                            froogaloop.addEvent('cuechange', function(data) {
                                apiLog('cuechange event : ' + data.language + ' : ' + data.text);
                            });
                        }
                        else {
                            froogaloop.removeEvent('cuechange');
                        }
                    }

                    // Listens for the checkboxes to change
                    addEvent(loadProgressChk, 'change', onLoadProgress, false);
                    addEvent(playProgressChk, 'change', onPlayProgress, false);
                    addEvent(playChk, 'change', onPlay, false);
                    addEvent(pauseChk, 'change', onPause, false);
                    addEvent(finishChk, 'change', onFinish, false);
                    addEvent(seekChk, 'change', onSeek, false);
                    addEvent(cuechangeChk, 'change', onCueChange, false);

                    // Calls the change event if the option is checked
                    // (this makes sure the checked events get attached on page load as well as on changed)
                    onLoadProgress();
                    onPlayProgress();
                    onPlay();
                    onPause();
                    onFinish();
                    onSeek();
                    onCueChange();
                }

                /**
                 * Sets up actions for adding a new clip window to the page.
                 */
                function setupAddClip() {
                    var button = container.querySelector('.addClip'),
                        newContainer;

                    addEvent(button, 'click', function(e) {
                        // Don't do anything if clicking on anything but the button (such as the input field)
                        if (e.target != this) {
                            return false;
                        }

                        // Gets the index of the current player by simply grabbing the number after the underscore
                        var currentIndex = parseInt(player_id.split('_')[1]),
                            clipId = button.querySelector('input').value;

                        newContainer = resetContainer(container.cloneNode(true), currentIndex+1, clipId);

                        container.parentNode.appendChild(newContainer);
                        $f(newContainer.querySelector('iframe')).addEvent('ready', ready);
                    });

                    /**
                     * Resets the duplicate container's information, clearing out anything
                     * that doesn't pertain to the new clip. It also sets the iframe to
                     * use the new clip's id as its url.
                     */
                    function resetContainer(element, index, clipId) {
                        var newHeading = element.querySelector('h2'),
                            newIframe = element.querySelector('iframe'),
                            newCheckBoxes = element.querySelectorAll('.listeners input[type="checkbox"]'),
                            newApiConsole = element.querySelector('.console .output'),
                            newAddBtn = element.querySelector('.addClip');

                        // Set the heading text
                        newHeading.innerText = 'Vimeo Player ' + index;

                        // Set the correct source of the new clip id
                        newIframe.src = 'http://player.vimeo.com/video/' + clipId + '?api=1&player_id=player_' + index;
                        newIframe.id = 'player_' + index;

                        // Reset all the checkboxes for listeners to be checked on
                        for (var i = 0, length = newCheckBoxes.length, checkbox; i < length; i++) {
                            checkbox = newCheckBoxes[i];
                            checkbox.setAttribute('checked', 'checked');
                        }

                        // Clear out the API console
                        newApiConsole.innerHTML = '';

                        // Update the clip ID of the add clip button
                        newAddBtn.querySelector('input').setAttribute('value', clipId);

                        return element;
                    }
                }

                setupSimpleButtons();
                setupModifierButtons();
                setupGetterButtons();
                setupEventListeners();
                setupAddClip();

                // Setup clear console button
                var clearBtn = container.querySelector('.console button');
                addEvent(clearBtn, 'click', function(e) {
                    apiConsole.innerHTML = '';
                }, false);

                apiLog(player_id + ' ready!');
            }   

        })();
Andrew Myers
  • 2,754
  • 5
  • 32
  • 40
  • When the page is refreshed, are you not required to enter a password again? – Andrew Myers Feb 24 '16 at 23:52
  • Probably did not explain it well. Once the password is entered and then you refresh the page the code works. I tried to find a way to mimic this but was unable to. – David Smith Feb 26 '16 at 11:07
  • So I'm guessing that the page loads and tries to load froogaloop, but the password is required--which keeps froogaloop from loading. Then when reloaded, no password is required and froogaloop load normally. Does that sound right to you? – Andrew Myers Feb 26 '16 at 16:16
  • That's exactly it. I tried to place a 'unload()' somewhere as this will kick start froogaloop, but Vimoe's password screen seems to hide behind everything, You can not detect the password being entered or the 'watch video' button being clicked on. – David Smith Feb 29 '16 at 11:21
  • Well, the Vimeo Player API works by [passing messages](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) to and from the iframe that holds the actual Vimeo video. Froogaloop is just a wrapper around that. **If messages do not get passed** after the password is accepted then you're stuck with, um, very _creative_ solutions. **If they do get passed** then there may be a simple solution yet. Can you find a way to check on that? – Andrew Myers Mar 01 '16 at 15:13
  • Could you put up a reduced test case with just the buttons and the password protected embed (a test video would be fine)? I just realized I could answer a lot of my questions myself if I had a working model to play with. [CodePen](http://codepen.io), [jsFiddle](http://jsfiddle.net), and [JS Bin](http://jsbin.com) are all free options. – Andrew Myers Mar 01 '16 at 15:20
  • https://jsfiddle.net/David_NSDA/bfvovv12/1/#&togetherjs=69zygd4StI – David Smith Mar 02 '16 at 18:11
  • I don't believe it but it seem to work with this example! – David Smith Mar 02 '16 at 18:11
  • Sorry password is hippo – David Smith Mar 02 '16 at 18:14
  • I did a quick (and ineffective) diff of the JavaScript, but didn't see any major changes. Did you actually change something? Vimeo sometimes updates things without announcing; do you think that's why it's working now? – Andrew Myers Mar 02 '16 at 18:29
  • Hi,Just got this message from Vimeo this morning! “ Hi David, sorry for the delay. We recently fixed an issue with playback on password protected videos, are you still having any trouble? So we are all good - Thank you for your time on this issue! – David Smith Mar 03 '16 at 11:06
  • This is weird----it works on JSFiddle but not on the web site - still same issue...... – David Smith Mar 03 '16 at 18:25
  • What other scripts and elements do you have on the page? It sounds like something isn't loading properly or being blocked and when you refresh it's fine. I would inspect how the password check is done by Vimeo as I suspect the Vimeo side JS script or whatever it is, removes any objects that could allow someone to circumvent the password. – Trevor Mar 05 '18 at 00:39
  • You could always add a page or custom dialog that prompts the user for the password, if its valid then redirects them to the video so that the scripts are loaded properly but that's a lot of pass-through for my liking (I have other issues: I am trying to create a custom user manager but use my own access token so always authenticated) – Trevor Mar 05 '18 at 00:41

0 Answers0