🏠 Home 

Coursera EXT - Custom video speed

Coursera Extension -- enables setting custom video speed in 10% increments by pressing [ and ] keys.


Install this script?
// ==UserScript==
// @name            Coursera EXT - Custom video speed
// @description     Coursera Extension -- enables setting custom video speed in 10% increments by pressing [ and ] keys.
// @namespace       http://sepczuk.com/
// @version         0.32
// @include         https://*.coursera.org/*/lecture/view*
// @match           https://*.coursera.org/*/lecture/view*
// @copyright       2012-2013, Damian Sepczuk, damian at sepczuk period delme com
// ==/UserScript==
function mainWrapper(){
var debug = false;
var US_SHORT_NAME = 'CourseraEXT';
var US_VERSION = 0.32;
function debugLog(msg) {
if (!debug) return;
console.log(US_SHORT_NAME + ": " + msg);
}
/*!
* jQuery Cookie Plugin
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2011, Klaus Hartl
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://www.opensource.org/licenses/mit-license.php
* http://www.opensource.org/licenses/GPL-2.0
*/
(function($) {
$.cookie = function(key, value, options) {
// key and at least value given, set cookie...
if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
options = $.extend({}, options);
if (value === null || value === undefined) {
options.expires = -1;
}
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setDate(t.getDate() + days);
}
value = String(value);
return (document.cookie = [
encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path    ? '; path=' + options.path : '',
options.domain  ? '; domain=' + options.domain : '',
options.secure  ? '; secure' : ''
].join(''));
}
// key and possibly options given, get cookie...
options = value || {};
var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
var pairs = document.cookie.split('; ');
for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
}
return null;
};
})(jQuery);
function roundToNthDigit(v, n) {
return parseFloat((v).toFixed(n));
}
function getRoundedVideoSpeed() {
return roundToNthDigit(QL_player.get_speed(), 2);
}
function updateInterface() {
$('.course-lecture-view-speed-label').text(getRoundedVideoSpeed() + 'x');
}
function main(){
debugLog("Running main!");
if (window.QL_player === undefined) {
var retryAfterTImeout = 300;
debugLog("QL_player window not found. Setting timeout to " + retryAfterTImeout + "ms.");
setTimeout(main, retryAfterTImeout);
return;
}
//debugLog("QL_player window not found!");
// ======================== <modify standard code>
// get rid of bounds!
debugLog("Registering new increase_speed function... ");
QL_player.increase_speed = function(deltaSpeed){
var currentSpeed = getRoundedVideoSpeed();
var newSpeed = roundToNthDigit(currentSpeed + deltaSpeed, 2);
debugLog("QL_player.increase_speed: current speed = " + currentSpeed + "; delta = " + deltaSpeed + "; new rounded speed = " + newSpeed + ". Setting...");
QL_player.set_speed(newSpeed);
debugLog("QL_player.increase_speed: DEBUG check of current speed. Current EXACT speed = " + QL_player.get_speed());
}
debugLog("Registering new increase_speed function... DONE.");
// change the way, video speed is saved
debugLog("Overriding update_speed_preference function... ");
var old_update_speed_preference = update_speed_preference;
update_speed_preference = function(){
debugLog("update_speed_preference: invoking old function...");
old_update_speed_preference();
debugLog("update_speed_preference: DONE.");
debugLog("update_speed_preference: Saving new speed in a cookie customVideoSpeed___ByFireBiker.");
$.cookie('customVideoSpeed___ByFireBiker', getRoundedVideoSpeed(), {expires: 24*7*30*365*10, secure: true});
}
debugLog("Overriding update_speed_preference function... DONE.");
// ======================== </modify standard code>
// set video speed to previously cookied one (if available)
var cookiedSpeed = $.cookie('customVideoSpeed___ByFireBiker');
debugLog("Video speed from customVideoSpeed___ByFireBiker cookie: " + cookiedSpeed);
if (null !== cookiedSpeed ) {
debugLog("Not null, so update speed!");
QL_player.set_speed(cookiedSpeed);
updateInterface();
}
// Add full-screen bubble
var mediaStatusBubble = $('<div id="player_state" aria-live="assertive" role="alert" style="display: block; position: absolute; top: 10px; right: 10px; z-index: 10000; padding: 10px 20px; background-color: #eee; display: none; border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px;">Player state</div>').appendTo('#lecture_view_dialog');
var isShowingMediaBubble = false;
var mediaBubbleTimeout = null;
function showMediaStatusBubble(t) {
debugLog("showMediaStatusBubble: showing the bubble!");
if (isShowingMediaBubble) clearTimeout(mediaBubbleTimeout);
else mediaStatusBubble.fadeIn(300);
isShowingMediaBubble = true;
mediaStatusBubble.html(t);
mediaBubbleTimeout = setTimeout(function(){mediaStatusBubble.fadeOut(200); isShowingMediaBubble = false;}, 800);
}
// Define speed actions
var decSpeed = function(e){
debugLog("decSpeed");
var newRate = getRoundedVideoSpeed() - 0.1;
if(newRate > 0) {
QL_player.set_speed(newRate);
}
};
var incSpeed = function(e){
debugLog("incSpeed");
var newRate = getRoundedVideoSpeed() + 0.1;
QL_player.set_speed(newRate);
};
// Add keyboard shortcuts
LBRACKET_KEY = 219;
RBRACKET_KEY = 221;
NUM0_KEY = 96;
ALNUM_0 = 48;
QL_player.mediaelement_handle.options.keyActions.push({keys: [LBRACKET_KEY], action: function(player, media){decSpeed();}});
QL_player.mediaelement_handle.options.keyActions.push({keys: [RBRACKET_KEY], action: function(player, media){incSpeed();}});
QL_player.mediaelement_handle.options.keyActions.push({keys: [NUM0_KEY, ALNUM_0], action: function(player, media){QL_player.set_speed(1);}});
// Add entries to the legend ([?]-key)
$('.course-lecture-view-shortcuts-block li').eq(7).append('<li><strong>[:</strong> Decrease speed by 10%</li>\n' +
'<li><strong>]:</strong> Increase speed by 10%</li>\n' +
'<li><strong>Num0:</strong> Set speed to 100%</li>\n');
// Respond to speed change (from any source!) by updating user interface
QL_player.mediaelement_media.addEventListener('ratechange', function(){
debugLog("Speed change detected! Update the interface.");
updateInterface();
debugLog("... and store the new speed.");
update_speed();
debugLog("Show bubble if full screen.");
// Show bubble only on full-screen. When in window mode, there's a button showing current speed.
if (QL_player.mediaelement_handle.isFullScreen) {
debugLog("YES, full screen! Showing bubble.");
var s = QL_player.mediaelement_media.playbackRate.toFixed(2);
showMediaStatusBubble("Video speed: &#215;" + s);
}
});
};
main();
};
if (!document.xmlVersion) {
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ mainWrapper +')();'));
document.documentElement.appendChild(script);
}