Greasy Fork is available in English.

Twitter Video Keyboard Shortcuts

Add keyboard shortcuts for controlling Twitter video playback


// ==UserScript==
// @name Twitter Video Keyboard Shortcuts
// @namespace https://example.com/
// @version 1.02
// @description Add keyboard shortcuts for controlling Twitter video playback
// @author Your Name
// @match https://twitter.com/*
// @grant none
// @license MIT
// ==/UserScript==

(function() {
  'use strict';

  // Define the keyboard shortcuts
  const shortcuts = {
    // get keycode in https://css-tricks.com/snippets/javascript/javascript-keycodes/
    97: -1/23.976024, // numpad1 move forward 0.1 seconds
    98: 1/23.976024, // numpad2 move forward 0.1 seconds
    100: -1, // numpad4
    101: 1, // numpad5
    103: "x0.2", // numpad7
    104: "x1", // numpad8
    105: "play", // numpad9
  };

  let speedIndex = 0; // keeps track of the current playback speed index
  const speeds = [0.2, 0.4, 0.6, 0.8, 1];



  // Add a keydown event listener to the document
  document.addEventListener('keydown', (event) => {

    let video = document.querySelectorAll('video');
    const mediaElement = document.querySelectorAll('video, [aria-label="GIF"]');
    if(mediaElement){
      video = mediaElement;
    }
    const hideDiv = document.querySelector('.css-1dbjc4n.r-1p0dtai.r-113qch9.r-105ug2t.r-u8s1d.r-13qz1uu.r-18phcnl');
    // If there is no video element, remove the keydown event listener
    if (video.length === 0) {
      document.removeEventListener('keydown', arguments.callee);
      return;
    }

    // Get the Twitter video element
    if (video.length>0) {

       // get the current playback time
      const shortcutValue = shortcuts[event.keyCode]; // get the playback time or speed for the current key

      if (shortcutValue !== undefined) {
        event.preventDefault(); // prevent the default behavior of the key press
        if(hideDiv){hideDiv.style.display = "none"}
         for(let i=0;i<video.length;i++){

        if (shortcutValue === "x0.2") {
          // change the playback speed
          video[i].playbackRate = speeds[speedIndex];
          video[i].play();
          display_playrate(speeds[speedIndex]);
          speedIndex = (speedIndex+1) % speeds.length;


        }else if(shortcutValue === "x1"){
          video[i].playbackRate = 1;
          video[i].play();
          speedIndex = 0
           display_playrate(1);


        }else if(shortcutValue === "play"){
          video[i].play();

          display_playrate(speeds[speedIndex]);

        }
        else {
          // change the playback time
          video[i].pause(); // pause the video
          video[i].currentTime = Math.max(0, video[i].currentTime + shortcutValue);
        }
      }}
    }

    return false;
  });
})();

function display_playrate(speed){
              // Find the playback speed element using the xpath
      const playbackSpeedElement = document.evaluate(
        '/html/body/div[1]/div/div/div[2]/main/div/div/div/div/div/section/div/div/div[1]/div/div/div[1]/article/div/div/div/div[3]/div[3]/div/div/div/div/div/div/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div[5]/div/div[2]/div/span',
        document,
        null,
        XPathResult.FIRST_ORDERED_NODE_TYPE,
        null
      ).singleNodeValue;

      // Change the text content of the playback speed element
      if (playbackSpeedElement) {
        playbackSpeedElement.textContent = "x"+speed;
      }
          // Change the GIF text content.  Find the playback speed element using the xpath
const playbackSpeedElement2 = document.evaluate(
        '/html/body/div[1]/div/div/div[2]/main/div/div/div/div/div/section/div/div/div[1]/div/div/div[1]/article/div/div/div/div[3]/div[3]/div/div/div/div/div/div/div/div[2]/div/div/div/div[2]/div/div[2]/div/div[2]/div/div[2]/div/span',
        document,
        null,
        XPathResult.FIRST_ORDERED_NODE_TYPE,
        null
      ).singleNodeValue;

      // Change the text content of the playback speed element
      if (playbackSpeedElement2) {
        playbackSpeedElement2.textContent = "x"+speed;
      }
}