您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
easily fast forward video, rotate video, and set playback speed of the video.
当前为
// ==UserScript== // @name Free your hand - Pornhub // @namespace // @version 2.0.0 // @license MPL-2.0 // @description easily fast forward video, rotate video, and set playback speed of the video. // @author c4r, foolool // @match https://*.pornhub.com/view_video.php?viewkey=* // @match https://*.pornhubpremium.com/view_video.php?viewkey=* // @match www.pornhubselect.com/* // @require https://code.jquery.com/jquery-latest.js // @grant GM.setValue // @grant GM.getValue // ==/UserScript== (async () => { 'use strict'; let default_array_next_key = [] let default_array_pre_key = [] let default_array_anticlock = [] let default_array_clock = [] let default_array_speed_up = [] let default_array_speed_down = [] let default_array_speed_list = [0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 4.0] let sensitive = 0.8 /** * program values */ let array_next_key = [] let array_pre_key = [] let array_anticlock = [] let array_clock = [] let array_speed_up = [] let array_speed_down = [] let array_speed_list = [] /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts, that detects and handles AJAXed content. auther : BrockA homepage : https://gist.github.com/BrockA/2625891#file-waitforkeyelements-js Usage example: waitForKeyElements ( "div.comments" , commentCallbackFunction ); //--- Page-specific function to do what we want when the node is found. function commentCallbackFunction (jNode) { jNode.text ("This comment changed by waitForKeyElements()."); } IMPORTANT: This function requires your script to have loaded jQuery. */ function waitForKeyElements( selectorTxt, /* Required: The jQuery selector string that specifies the desired element(s). */ actionFunction, /* Required: The code to run when elements are found. It is passed a jNode to the matched element. */ bWaitOnce, /* Optional: If false, will continue to scan for new elements even after the first match is found. */ iframeSelector /* Optional: If set, identifies the iframe to search. */ ) { var targetNodes, btargetsFound; if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt); else targetNodes = $(iframeSelector).contents() .find(selectorTxt); if (targetNodes && targetNodes.length > 0) { btargetsFound = true; /*--- Found target node(s). Go through each and act if they are new. */ targetNodes.each(function () { var jThis = $(this); var alreadyFound = jThis.data('alreadyFound') || false; if (!alreadyFound) { //--- Call the payload function. var cancelFound = actionFunction(jThis); if (cancelFound) btargetsFound = false; else jThis.data('alreadyFound', true); } }); } else { btargetsFound = false; } //--- Get the timer-control variable for this selector. var controlObj = waitForKeyElements.controlObj || {}; var controlKey = selectorTxt.replace(/[^\w]/g, "_"); var timeControl = controlObj[controlKey]; //--- Now set or clear the timer as appropriate. if (btargetsFound && bWaitOnce && timeControl) { //--- The only condition where we need to clear the timer. clearInterval(timeControl); delete controlObj[controlKey] } else { //--- Set a timer, if needed. if (!timeControl) { timeControl = setInterval(function () { waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector ); }, 300 ); controlObj[controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; } let callbackShortcut = function (mutationList, observer) { } function showMSG(msg, duration) { $('.mhp1138_ccContainer').text(msg) setTimeout(() => { $('.mhp1138_ccContainer').text('') }, duration); } function activeTab() { $('.tab-menu-item.tooltipTrig').removeClass('active') $('.tab-menu-item[data-tab="free-your-hand"]').addClass('active') $('.video-action-tab').removeClass('active') $('.video-action-tab.free-your-hand').addClass('active') } function shortcutItemHTML(name, description, keyLabel, isDefault) { let v = '' let keyLabelLocal = (keyLabel == '' || keyLabel == null) ? 'No' : keyLabel if(isDefault){ v = '<li class="alpha omega">\ <span '+ name + '>\ <button free-your-hand-default name="'+ name + '" style="width:70%">'+ description +'</button>\ <a free-your-hand-default name="'+ name + '" style="width:70%;text-align:center">\ '+ keyLabelLocal +'\ </a>\ </span>\ </li>' }else{ v = '<li class="alpha omega">\ <span '+ name + '>\ <button free-your-hand name="'+ name + '" style="width:70%">'+ description +'</button>\ <a free-your-hand name="'+ name + '" style="width:70%;text-align:center">\ '+keyLabelLocal+'\ </a>\ <input free-your-hand name="'+ name + '" type="text" size="1" maxlength="1" placeholder="' + keyLabelLocal + '" style="display:none;width:20%"></input>\ </span>\ </li>' } return v } function insertKeyHTML(numPlace, name, description, keyLabel, isDefault = true){ $('#id-free-your-hand-shortcut div.display-grid ul.actionTagList:eq('+numPlace+')').append( shortcutItemHTML(name, description, keyLabel, isDefault) ) } function onListen() { $(document).on('click', '#id-free-your-hand-tab-menu', () => { activeTab() }) // set new shortcut : observed keypress $(document).on('keypress', 'input[free-your-hand]', (event) => { if (event.isComposing || event.keyCode === 229) { return; } let e = document.activeElement if ($(e).is('input[free-your-hand]')) { event = event || window.event var keyCode = event.which || event.keyCode; let value = String.fromCharCode(keyCode) // console.log('keypress', e.name, event.which, event.keyCode, e.charCode) let name = e.name $('#id-free-your-hand-shortcut a[name="'+ name +'"]').text(value) $('#id-free-your-hand-shortcut input[name="'+ name +'"]').attr('placeholder', value) $('#id-free-your-hand-shortcut a[name="'+ name +'"]').show() $('#id-free-your-hand-shortcut input[name="'+ name +'"]').hide() // store let data = getLocalData() if (data === undefined) { data = defaultData() } data.shortcut[name] = { label: value, code: keyCode } saveLocalData(data) setShortcutArrayFromLocalStorage() $('video').focus() event.stopImmediatePropagation(); } }) $(document).on('click', '#id-free-your-hand-shortcut a[free-your-hand]', (event) => { let name = $(event.target).attr('name') // console.log('click set shortcut: ', name) $('#id-free-your-hand-shortcut a[name="'+ name +'"]').hide() $('#id-free-your-hand-shortcut input[name="'+ name +'"]').show() $('#id-free-your-hand-shortcut input[name="'+ name +'"]').focus() $('#id-free-your-hand-shortcut input[name="'+ name +'"]').focusout(()=>{ $('#id-free-your-hand-shortcut a[name="'+ name +'"]').show() $('#id-free-your-hand-shortcut input[name="'+ name +'"]').hide() }) }) $(document).on('click', '#id-free-your-hand-shortcut button[free-your-hand]', (event) => { let name = $(event.target).attr('name') console.log('click button: ', name) let nodevideo = $("video:has(source[src])").get(0); // console.log(array_peek_index) let array_peek_index = getMarkPosition(nodevideo.duration) // console.log(array_peek_index) if(name == 'previous'){ preHighPoint(nodevideo, array_peek_index) }else if (name == 'next') { nextHighPoint(nodevideo, array_peek_index) }else if (name == 'anticlockwise') { anticlockwise(nodevideo) }else if (name == 'clockwise') { clockwise(nodevideo) }else if (name == 'speedup') { speedUp(nodevideo) }else if (name == 'speeddn') { speedDown(nodevideo) } }) $(document).on('click', '#id-free-your-hand-shortcut-reset', () => { $('input[free-your-hand]').each((index, element) => { element.placeholder = '' element.value = '' element.code = '' }) let data = getLocalData() if (data === undefined) { data = defaultData() } data["shortcut"] = { next: {}, previous: {}, clockwise: {}, anticlockwise: {}, speedup: {}, speeddn: {} } saveLocalData(data) saveGMData(data) $('#id-free-your-hand-shortcut-reset').text('done!') setTimeout(() => { $('#id-free-your-hand-shortcut-reset').text('reset shortcut') }, 300); setShortcutArrayFromLocalStorage() showShortcut() $('video').focus() }) } $(document).on('click', '#id-free-your-hand-shortcut-official-default', () => { if($('.mhp1138_keyboardShortcuts').hasClass('mhp1138_active')){ $('.mhp1138_keyboardShortcuts').removeClass('mhp1138_active') }else{ $('.mhp1138_keyboardShortcuts').addClass('mhp1138_active') } }) function defaultData() { return { shortcut: { next: {}, previous: {}, clockwise: {}, anticlockwise: {}, speedup: {}, speeddn: {} } } } function saveLocalData(data) { localStorage.setItem('free-your-hand', JSON.stringify(data)) } function getLocalData() { let rawData = localStorage.getItem('free-your-hand') if (rawData == undefined || rawData == '') { return undefined } else { return JSON.parse(rawData) } } async function saveGMData(data) { await GM.setValue('free-your-hand', JSON.stringify(data)) } async function getGMData() { let rawData = await GM.getValue('free-your-hand', JSON.stringify(defaultData()) ) if (rawData == undefined || rawData == '') { return undefined } else { return JSON.parse(rawData) } } function setShortcutArrayFromLocalStorage() { let data = getLocalData() // console.log(data.shortcut.next.code) if (data && data.shortcut.next["code"]) { array_next_key = [data.shortcut.next.code] } else { array_next_key = default_array_next_key } if (data && data.shortcut.previous["code"]) { array_pre_key = [data.shortcut.previous.code] } else { array_pre_key = default_array_pre_key } if (data && data.shortcut.clockwise["code"]) { array_clock = [data.shortcut.clockwise.code] } else { array_clock = default_array_clock } if (data && data.shortcut.anticlockwise["code"]) { array_anticlock = [data.shortcut.anticlockwise.code] } else { array_anticlock = default_array_anticlock } if (data && data.shortcut.speedup["code"]) { array_speed_up = [data.shortcut.speedup.code] } else { array_speed_up = default_array_speed_up } if (data && data.shortcut.speeddn["code"]) { array_speed_down = [data.shortcut.speeddn.code] } else { array_speed_down = default_array_speed_down } array_speed_list = default_array_speed_list } function genCharFromArryCode(array_key_code, connector = ' '){ if(array_key_code.length == 0 ){ return '' }else{ let str = '' array_key_code.forEach( (charCode,index) => { if(index != array_key_code.length){ str += String.fromCharCode(charCode) + connector }else{ str += String.fromCharCode(charCode) } }); return str } } function showShortcut(){ // read local storage let fyhStorage = getLocalData() let strN = genCharFromArryCode(default_array_next_key), strP = genCharFromArryCode(default_array_pre_key), strC = genCharFromArryCode(default_array_anticlock), strAC = genCharFromArryCode(default_array_clock), strSU = genCharFromArryCode(default_array_speed_up), strSD = genCharFromArryCode(default_array_speed_down) if (fyhStorage) { if (fyhStorage.shortcut.next.label) { strN = fyhStorage.shortcut.next.label } if (fyhStorage.shortcut.previous.label) { strP = fyhStorage.shortcut.previous.label } if (fyhStorage.shortcut.clockwise.label) { strC = fyhStorage.shortcut.clockwise.label } if (fyhStorage.shortcut.anticlockwise.label) { strAC = fyhStorage.shortcut.anticlockwise.label } if (fyhStorage.shortcut.speedup.label) { strSU = fyhStorage.shortcut.speedup.label } if (fyhStorage.shortcut.speeddn.label) { strSD = fyhStorage.shortcut.speeddn.label } } $('#id-free-your-hand-shortcut div.display-grid ul.actionTagList').empty() // add specific shortcut : next insertKeyHTML(1, 'next', 'Next', strN, false) // add specific shortcut : previous insertKeyHTML(0, 'previous', 'Previous',strP, false) // add specific shortcut : clockwise insertKeyHTML(1, 'clockwise', 'clockwise', strC, false) // add specific shortcut : anticlockwise insertKeyHTML(0, 'anticlockwise', 'anticlockwise', strAC, false) // // add specific shortcut : speed up insertKeyHTML(1, 'speedup', 'speedup', strSU, false) // // add specific shortcut : speed down insertKeyHTML(0, 'speeddn', 'speeddn', strSD, false) // // add click listener // onListen() } function insertMenu() { if ($('.free-your-hand').length > 0) { return } let menuHTML = '<div class="tab-menu-wrapper-cell free-your-hand">\ <div id="id-free-your-hand-tab-menu" class="tab-menu-item" data-tab="free-your-hand" onclick="" data-title="free-your-hand">\ <i class="main-sprite-dark-2"></i>\ <span>Hand</span>\ </div>\ </div>' let contentHTML = '<div class="video-action-tab free-your-hand">\ <div class="title">Free your hand</div>\ <div class="reset"></div>\ <div class="float-left">\ <div id="id-free-your-hand-shortcut">\ <button id="id-free-your-hand-shortcut-official-default" >official shortcut</button>\ <button id="id-free-your-hand-shortcut-reset" >reset shortcut</button>\ </div>\ </div>\ <div class="float-right">\ <div id="id-free-your-hand-support">\ </div>\ </div>\ <div class="reset"></div>\ </div>' let tableHTML = '<div class="display-grid col-4 gap-row-none sortBy seconds">\ <ul class="actionTagList full-width margin-none"></ul>\ <ul class="actionTagList full-width margin-none"></ul>\ <ul class="actionTagList full-width margin-none"></ul>\ <ul class="actionTagList full-width margin-none"></ul>\ </div>\ ' // // turn off click listener // offListen() // delete free-your-hand element $('.free-your-hand').remove() // append free-your-hand element to tab-menu $('.tab-menu-wrapper-row').prepend(menuHTML) // append free-your-hand element to content $('.video-actions-container > .video-actions-tabs').append(contentHTML) $('#id-free-your-hand-shortcut').append( tableHTML ) $('#id-free-your-hand-shortcut').append( '<div class="reset"></div>' ) showShortcut() } // Returns rotation in degrees when obtaining transform-styles using javascript // author : adamcbrewer // https://gist.github.com/adamcbrewer/4202226 function getRotationDegrees(obj) { var matrix = obj.css("-webkit-transform") || obj.css("-moz-transform") || obj.css("-ms-transform") || obj.css("-o-transform") || obj.css("transform"); if (matrix !== 'none') { var values = matrix.split('(')[1].split(')')[0].split(','); var a = values[0]; var b = values[1]; var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI)); } else { var angle = 0; } return angle; } /** * merge two sorted array * @param {*} left * @param {*} right */ function merge(left, right) { var result = []; while (left.length && right.length) { var item = left[0] >= right[0] ? left.shift() : right.shift(); result.push(item); } return result.concat(left.length ? left : right); } /** * merge sort method * @param {*} array */ function mergeSort(array) { var length = array.length; if (length < 2) { return array; } var m = (length >> 1), left = array.slice(0, m), right = array.slice(m); // split into two sub-array return merge(mergeSort(left), mergeSort(right)); // recurrence } /** * easiest Mean Average method * @param {array} array_y y value with spread with equal interval * @returns array with same length of array_y */ function filter_av(array_y) { let av_n = Math.floor(array_y.length / 100.); if (av_n < 5) { av_n = 5; } if (av_n % 2 == 0) { av_n = av_n + 1; } let array_r = new Array(array_y.length); for (let i = 0; i < array_y.length; i++) { if (i < (av_n - 1) / 2) { array_r[i] = array_y[i]; } else if (array_y.length - i <= (av_n - 1) / 2) { array_r[i] = array_y[i]; } else { array_r[i] = 0; for (let j = 0; j < av_n; j++) { array_r[i] = array_r[i] + array_y[i + j - (av_n - 1) / 2]; } array_r[i] = array_r[i] / av_n; } } return array_r; } /** * find the maximum peak in array_y * @param {*} array_y */ function find_peak(array_y) { let array_sort = array_y; mergeSort(array_sort); let average = array_sort[ Math.max(0, Math.min(Math.floor(array_sort.length * sensitive), array_sort.length - 1)) ]; let peek = new Array(); if (array_y[1] < array_y[0] && array_y[0] > average) { peek.push(0); } for (let i = 1; i < array_y.length - 1; i++) { if (array_y[i - 1] < array_y[i] && array_y[i + 1] <= array_y[i] && array_y[i] > average) { // console.log(peek.length, i,peek[peek.length-1], array_y[i]); // if(peek.length == 0 || (i - peek[peek.length-1] > array_y.length/40) || (array_y[i] > array_y[peek[peek.length-1]]) ){ peek.push(i); // } } } if (array_y[array_y.length - 2] < array_y[array_y.length - 1] && array_y[array_y.length - 1] > average) { peek.push(array_y.length - 1); } // remove excess let peek_del = new Array(); for (let i = 0; i < peek.length; i++) { let toSave = true for (let j = 0; j < peek.length; j++) { // The shortest red dot spacing is 40 equal parts for the video duration, the highest in the 40 sec. if (toSave && i != j && Math.abs(peek[j] - peek[i]) < array_y.length / 40 && array_y[peek[i]] <= array_y[peek[j]]) { toSave = false } } if (toSave) { peek_del.push(peek[i]) } } return peek_del; } /** * attach the marker to the progress bar in the page * @param {array} array_y * @param {float} duration */ function mark(array_y, duration) { let objBar = $("div.mhp1138_progressOverflow"); // console.log(objBar); let markP1 = "<div data-tag=\"HighTime\" class=\"mhp1138_actionTag\" style=\"left: "; let markP3 = "%; width: 0.178995%;\"></div>"; for (let i = 0; i < array_y.length; i++) { // console.log(i); $(objBar).append(markP1 + (array_y[i] / duration * 100.).toString() + markP3); } $(objBar).find("div.mhp1138_actionTag").each((index, element) => { if ($(element).attr("data-tag") == "HighTime") { $(element).css("background-color", "red"); } }); } function getMarkPosition(duration, only_white = false) { let array_peek_index = [] if (only_white) { $('.mhp1138_actionTag[data-tag!="HighTime"]').each((index, element) => { array_peek_index.push($(element).attr('style').split('%')[0].slice(('left:').length).trim() / 100. * duration) }) } else { $('.mhp1138_actionTag').each((index, element) => { array_peek_index.push($(element).attr('style').split('%')[0].slice(('left:').length).trim() / 100. * duration) }) } if (array_peek_index.length > 1) { return (mergeSort(array_peek_index)).reverse() } return array_peek_index } function isMarked() { return $('[data-tag="HighTime"]').length > 0 } function loadedPolygon() { return $("polygon").length > 0 && $("polygon").attr("points").split(" ").length > 0 } /** * if video is found in page, this function will be called. * this functions contains : * - get all the view data * - analyse the progress bar * - get the highpoint * - add marker to page */ function actionVideo() { if (isMarked()) { return } if (!loadedPolygon()) { return } /**<============Get view data============> * the raw view data will be stored in `array_point` as a two dimensional matrix * array_point : [[x1,y2],[x2,y2],..] * x : 0 to 1000 * y : 0 - 100 */ let str_point = $("polygon").attr("points"); let str_array_point = str_point.split(" "); let len_point = parseFloat(str_array_point[str_array_point.length - 2].split(",")[0]); //console.log("video :" + len_point); let array_point = new Array(); for (i = 0; i < str_array_point.length - 1; i++) { let point = str_array_point[i].split(","); let x = parseFloat(point[0]); let y = -parseFloat(point[1]) + 100.; // console.log(x,y); array_point.push([x, y]); } /**<============interpolation============> * interpolate the raw data at every second, and store in * array_x : second. range : 0 to the duration (closest even integer) * array_y : interpolated data from array_point. range : 0-100 */ let nodevideo = $("video:has(source[src])").get(0); let len_point_sec = Math.floor(nodevideo.duration); if (len_point_sec % 2 == 0) { len_point_sec = len_point_sec + 1; } let dis = len_point / (len_point_sec - 1); let array_y = new Array(); let array_x = new Array(); for (i = 0; i < len_point_sec; i++) { let x = dis * (i); let y = 0.; let xInRange = false; for (let j = 0; j < array_point.length; j++) { if ((array_point[j])[0] > x) { y = ((array_point[j])[1] - (array_point[j - 1])[1]) / ((array_point[j])[0] - (array_point[j - 1])[0]) * (x - (array_point[j - 1])[0]) + (array_point[j - 1])[1]; break; } } array_y.push(y); array_x.push(x); } // <============smooth y data============> let array_smooth_y = filter_av(array_y); // <============Get the peak corresponding index============> let array_peek_index = find_peak(array_smooth_y); // <============get the corresponding time============> for (let i = 0; i < array_peek_index.length; i++) { array_peek_index[i] = array_peek_index[i] * dis / len_point * nodevideo.duration; } // <============get "jump to" points, white points set by author ============> let array_white_peek_index = getMarkPosition(nodevideo.duration, true) // console.log("array_white_peek_index", array_white_peek_index) // <============delete peeks, which cover the white one (less than 40 sec) ============> array_white_peek_index.forEach(position_white => { array_peek_index = array_peek_index.filter((peek) => { return Math.abs(peek - position_white) > 40 }) }); // <============add markers on the process bar============> mark(array_peek_index, nodevideo.duration); console.log('your hands are free now !!!') showMSG('your hands are free now !!!', 2000) // console.log('peek index : ', array_peek_index) } // <============Start Here============> $(document).ready(function () { console.log("loading your hand assistant..."); getGMData().then((data)=>{ saveLocalData(data) setShortcutArrayFromLocalStorage() onListen() // waiting video appeared waitForKeyElements("video:has(source[src])", function () { if (isNaN($("video:has(source[src])").get(0).duration)) { // console.log("wait load") // console.log($("video:has(source[src])")) // console.log($("video:has(source[src])").get(0).duration) $("video:has(source[src])").on('loadedmetadata', function () { actionVideo() insertMenu() activeTab() }) } else { // console.log("load directly") // console.log($("video:has(source[src])").get(0)) // console.log($("video:has(source[src])").get(0).duration) actionVideo() insertMenu() activeTab() } }, false) }) // wait input changed let observerShortcut = new MutationObserver((mutationList, observer)=>{ mutationList.forEach((mutation) => { // console.log(mutation) if ($(mutation.target).is('a[free-your-hand]') && mutation.addedNodes.length > 0 ) { console.log('shortcut changed') saveGMData(getLocalData()) } }) }) observerShortcut.observe($('body').get(0), { subtree: true, childList: true, characterData: true, attributes: false, attributeOldValue: false, characterDataOldValue: false }) }); // <============keypress function============> function nextHighPoint(nodevideo, array_peek_index){ for (let i = 0; i < array_peek_index.length; i++) { if (array_peek_index[i] > nodevideo.currentTime) { nodevideo.currentTime = array_peek_index[i]; break; } } } function preHighPoint(nodevideo, array_peek_index){ let setDuration = null let currentTime = nodevideo.currentTime for (let i = array_peek_index.length - 1; i >= 0; i--) { // console.log('i : ', i ,array_peek_index[i] , currentTime, array_peek_index[i] < currentTime ) if (array_peek_index[i] < currentTime) { if (i == 0) { if ((currentTime - array_peek_index[i]) < (array_peek_index[i + 1] - array_peek_index[i]) / 3.) { setDuration = 0; break; } else { setDuration = array_peek_index[i]; break; } } else if (i == array_peek_index.length - 1) { if ((currentTime - array_peek_index[i]) < (nodevideo.duration - array_peek_index[i]) / 3.) { setDuration = array_peek_index[i - 1]; break; } else { setDuration = array_peek_index[i]; break; } } else { // console.log('i : ', i , // (currentTime - array_peek_index[i]) , // (array_peek_index[i + 1] - array_peek_index[i]) / 3., // (currentTime - array_peek_index[i]) < (array_peek_index[i + 1] - array_peek_index[i]) / 3.) if ((currentTime - array_peek_index[i]) < (array_peek_index[i + 1] - array_peek_index[i]) / 3.) { setDuration = array_peek_index[i - 1]; break; } else { setDuration = array_peek_index[i]; break; } } } } // console.log('set duration : ', setDuration) if (setDuration != null) { nodevideo.currentTime = setDuration } } function anticlockwise(nodevideo){ // console.log("press H") var angle = getRotationDegrees($(nodevideo)) - 90; // console.log(angle); if (Math.abs(angle) === 90 || Math.abs(angle) === 270) { $(nodevideo).css("transform", "rotate(" + angle + "deg)" + " scale(calc(" + (nodevideo.videoHeight > nodevideo.videoWidth ? nodevideo.videoWidth/nodevideo.videoHeight : nodevideo.videoHeight/nodevideo.videoWidth ) + "))") } else { $(nodevideo).css("transform", "rotate(" + angle + "deg)" + " scale(1)") } showMSG('Rotate '+angle, 2000) } function clockwise(nodevideo){ // console.log("press J") var angle = getRotationDegrees($(nodevideo)) + 90; // console.log(angle); if (Math.abs(angle) === 90 || Math.abs(angle) === 270) { $(nodevideo).css("transform", "rotate(" + angle + "deg)" + " scale(calc(" + (nodevideo.videoHeight > nodevideo.videoWidth ? nodevideo.videoWidth/nodevideo.videoHeight : nodevideo.videoHeight/nodevideo.videoWidth ) + "))") } else { $(nodevideo).css("transform", "rotate(" + angle + "deg)" + " scale(1)") } showMSG('Rotate '+angle, 2000) } function speedUp(nodevideo){ var cSpeed = $(nodevideo).get(0).playbackRate let array_larger = array_speed_list.filter((el)=>{ return el > cSpeed }) if(array_larger.length == 0){ $(nodevideo).get(0).playbackRate = Math.max.apply(Math,array_speed_list); }else{ $(nodevideo).get(0).playbackRate = Math.min.apply(Math,array_larger); } showMSG('Speed x'+$(nodevideo).get(0).playbackRate, 2000) // console.log($(nodevideo).get(0).playbackRate) } function speedDown(nodevideo){ var cSpeed = $(nodevideo).get(0).playbackRate let array_smaller = array_speed_list.filter((el)=>{ return el < cSpeed }) if(array_smaller.length == 0){ $(nodevideo).get(0).playbackRate = Math.min.apply(Math,array_speed_list); }else{ $(nodevideo).get(0).playbackRate = Math.max.apply(Math,array_smaller); } showMSG('Speed x'+$(nodevideo).get(0).playbackRate, 2000) // console.log($(nodevideo).get(0).playbackRate) } // <============listen keyboard============> $(document).keypress(function (event) { if (event.isComposing || event.keyCode === 229) { return; } if ($(document.activeElement).is('input[free-your-hand]')) { return } event = event || window.event var keyCode = event.which || event.keyCode; // console.log('press:', keyCode) let nodevideo = $("video:has(source[src])").get(0); // console.log(array_peek_index) let array_peek_index = getMarkPosition(nodevideo.duration) // console.log(array_peek_index) if (array_next_key.includes(keyCode)) { // next point (N) nextHighPoint(nodevideo, array_peek_index) event.stopImmediatePropagation(); } else if (array_pre_key.includes(keyCode)) { // previous point (B) preHighPoint(nodevideo, array_peek_index) event.stopImmediatePropagation(); // } else if (keyCode >= 48 && keyCode <= 57) { // number key // // console.log("press ", (keyCode - 48)) // nodevideo.currentTime = (keyCode - 48) * nodevideo.duration / 10. // event.stopImmediatePropagation(); // } else if (keyCode >= 96 && keyCode <= 105) { // numpad number key // // console.log("press ", (keyCode - 96)) // nodevideo.currentTime = (keyCode - 96) * nodevideo.duration / 10. // event.stopImmediatePropagation(); } else if (array_anticlock.includes(keyCode)) { // Rotate anticlockwise (H) anticlockwise(nodevideo) event.stopImmediatePropagation(); } else if (array_clock.includes(keyCode)) { // Rotate clockwise (J) clockwise(nodevideo) event.stopImmediatePropagation(); } else if (array_speed_up.includes(keyCode)) { // Speed up (A) speedUp(nodevideo) event.stopImmediatePropagation(); } else if (array_speed_down.includes(keyCode)) { // Speed down (s) speedDown(nodevideo) event.stopImmediatePropagation(); } }); })();