Skip to content

Instantly share code, notes, and snippets.

@yukulele
Last active March 29, 2025 10:40
Show Gist options
  • Save yukulele/805c382f371852e8f25efd7b2ec5876a to your computer and use it in GitHub Desktop.
Save yukulele/805c382f371852e8f25efd7b2ec5876a to your computer and use it in GitHub Desktop.

Twitter native video player

Replace the user-unfriendly Twitter reader with the browser's native reader.

This allows you to:

  • move the player with the left/right keyboard keys
  • change the volume with the up/down keyboard keys
  • Switch to full screen with double-click
  • access the video's contextual menu
  • change the playback speed (via the contextual menu)
  • share the playback speed between videos

install: https://gist.github.com/yukulele/805c382f371852e8f25efd7b2ec5876a/raw/twitter-native-video-player.user.js

// ==UserScript==
// @name Twitter native video player
// @namespace https://gist.github.com/yukulele/805c382f371852e8f25efd7b2ec5876a
// @match https://twitter.com/*
// @match https://mobile.twitter.com/*
// @grant none
// @version 1.0.2
// @author yukulele
// @homepage https://gist.github.com/yukulele/805c382f371852e8f25efd7b2ec5876a
// @description Replace the user-unfriendly Twitter reader with the browser's native reader. This allows you to: move the player with the left/right keyboard keys , change the volume with the up/down keyboard keys, Switch to full screen with double-click, access the video's contextual menu, change the playback speed (via the contextual menu), share the playback speed between videos
// @downloadURL https://gist.github.com/yukulele/805c382f371852e8f25efd7b2ec5876a/raw/twitter-native-video-player.user.js
// @updateURL https://gist.github.com/yukulele/805c382f371852e8f25efd7b2ec5876a/raw/twitter-native-video-player.user.js
// @supportURL https://gist.github.com/yukulele/805c382f371852e8f25efd7b2ec5876a#comments
// @inject-into auto
// ==/UserScript==
function nativePlayer(video) {
video.playbackRate = window.localStorage.playbackRate || 1
video.addEventListener('ratechange', () => window.localStorage.playbackRate = video.playbackRate)
video.addEventListener('mouseenter', () => video.controls = true)
video.addEventListener('mouseleave', () => video.controls = false)
video.style.zIndex = 1
}
const mutationObserver = new MutationObserver(mutationsList => {
for (var mutation of mutationsList) {
if (mutation.type !== 'childList') return
for (const node of mutation.addedNodes) {
if (!(node instanceof HTMLElement)) continue
for (const video of node.querySelectorAll('video')) nativePlayer(video)
}
}
})
mutationObserver.observe(document.documentElement, {
childList: true,
subtree: true,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment