mirror of
				https://github.com/SoPat712/videospeed.git
				synced 2025-10-30 18:34:02 -04:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			v1.1.1
			...
			3fed3b425e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3fed3b425e | ||
|   | d89853b4d2 | ||
|   | d94ab958d5 | ||
|   | 1277750716 | ||
|   | 247a46d430 | ||
|   | 703658335c | ||
|   | b2ed0fcb41 | ||
|   | 3dfee251ec | ||
|   | 8e0183d8af | ||
|   | 73827b5ee0 | ||
|   | b07e7cb394 | ||
|   | c3166cf347 | ||
|   | 77a25c4f1e | ||
|   | 3fee61d2b6 | ||
|   | b7684aad09 | 
| @@ -1,3 +1,7 @@ | |||||||
|  | [](https://addons.mozilla.org/en-US/firefox/addon/video-speed-controller-v1/) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # The science of accelerated playback | # The science of accelerated playback | ||||||
|  |  | ||||||
| **TL;DR: faster playback translates to better engagement and retention.** | **TL;DR: faster playback translates to better engagement and retention.** | ||||||
| @@ -74,10 +78,10 @@ You can try manually disabling Flash from the browser. | |||||||
| [`igrigorik/videospeed`](https://github.com/igrigorik/videospeed) repository | [`igrigorik/videospeed`](https://github.com/igrigorik/videospeed) repository | ||||||
| is a port of [`igrigorik`](https://github.com/igrigorik)'s videospeed Chrome  | is a port of [`igrigorik`](https://github.com/igrigorik)'s videospeed Chrome  | ||||||
| add-on for Firefox. This fork modifies the Chrome add-on code so that it works  | add-on for Firefox. This fork modifies the Chrome add-on code so that it works  | ||||||
| in Firefox. This repo is the code behind the [Firefox Extension](https://addons.mozilla.org/en-us/firefox/addon/videospeed/) | in Firefox. This repo is the code behind the [Firefox Extension](https://addons.mozilla.org/en-US/firefox/addon/video-speed-controller-v1/) | ||||||
| whereas the [`igrigorik/videospeed`](https://github.com/igrigorik/videospeed) | whereas the [`igrigorik/videospeed`](https://github.com/igrigorik/videospeed) | ||||||
| repository contains the code behind the [Chrome Extension](https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk). | repository contains the code behind the [Chrome Extension](https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk). | ||||||
|  |  | ||||||
| ### License | ### License | ||||||
|  |  | ||||||
| (MIT License) - Copyright (c) 2014 Ilya Grigorik | (MIT License) - Copyright (c) 2025 Josh Patra | ||||||
|   | |||||||
							
								
								
									
										118
									
								
								build.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								build.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | |||||||
|  | import glob | ||||||
|  | import os | ||||||
|  | import re | ||||||
|  | import shutil | ||||||
|  | import tempfile | ||||||
|  | import zipfile | ||||||
|  |  | ||||||
|  | SCRIPT_NAME = os.path.basename(__file__) | ||||||
|  | TARGET_FILE = "manifest.json" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def zip_folder(output_name, folder, exclude_files, exclude_dirs): | ||||||
|  |     with zipfile.ZipFile(output_name, "w", zipfile.ZIP_DEFLATED) as zipf: | ||||||
|  |         for root, dirs, files in os.walk(folder): | ||||||
|  |             dirs[:] = [ | ||||||
|  |                 d | ||||||
|  |                 for d in dirs | ||||||
|  |                 if os.path.relpath(os.path.join(root, d), folder) not in exclude_dirs | ||||||
|  |             ] | ||||||
|  |             for file in files: | ||||||
|  |                 rel_path = os.path.relpath(os.path.join(root, file), folder) | ||||||
|  |                 if ( | ||||||
|  |                     file in exclude_files | ||||||
|  |                     or rel_path in exclude_files | ||||||
|  |                     or any(rel_path.startswith(ed + os.sep) for ed in exclude_dirs) | ||||||
|  |                 ): | ||||||
|  |                     continue | ||||||
|  |                 zipf.write(os.path.join(root, file), arcname=rel_path) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def update_version_line(file_path, new_version): | ||||||
|  |     with open(file_path, "r", encoding="utf-8") as f: | ||||||
|  |         lines = f.readlines() | ||||||
|  |  | ||||||
|  |     updated = False | ||||||
|  |     for i, line in enumerate(lines): | ||||||
|  |         match = re.match(r'\s*"version":\s*"([^"]+)"', line) | ||||||
|  |         if match: | ||||||
|  |             old_version = match.group(1) | ||||||
|  |             lines[i] = re.sub( | ||||||
|  |                 r'"version":\s*".+?"', f'"version": "{new_version}"', line | ||||||
|  |             ) | ||||||
|  |             updated = True | ||||||
|  |             print( | ||||||
|  |                 f"🛠️ Changed version in {file_path} from {old_version} ➜ {new_version}" | ||||||
|  |             ) | ||||||
|  |             break | ||||||
|  |  | ||||||
|  |     if updated: | ||||||
|  |         with open(file_path, "w", encoding="utf-8") as f: | ||||||
|  |             f.writelines(lines) | ||||||
|  |     else: | ||||||
|  |         print(f"⚠️ No version line found in {file_path}.") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     # Step 0: Remove all existing .xpi files upfront | ||||||
|  |     xpi_files = glob.glob("*.xpi") | ||||||
|  |     for f in xpi_files: | ||||||
|  |         try: | ||||||
|  |             os.remove(f) | ||||||
|  |             print(f"🗑️ Removed existing archive: {f}") | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"⚠️ Failed to remove {f}: {e}") | ||||||
|  |  | ||||||
|  |     base_version = input("Enter the new base version (e.g., 2.0.1): ").strip() | ||||||
|  |     if not base_version: | ||||||
|  |         print("❌ No version entered. Exiting.") | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     firefox_version = f"{base_version}.0" | ||||||
|  |     current_dir = os.getcwd() | ||||||
|  |     manifest_path = os.path.join(current_dir, TARGET_FILE) | ||||||
|  |  | ||||||
|  |     # Step 1: Update manifest.json on disk to base_version | ||||||
|  |     if os.path.exists(manifest_path): | ||||||
|  |         update_version_line(manifest_path, base_version) | ||||||
|  |     else: | ||||||
|  |         print(f"❌ {TARGET_FILE} not found. Aborting.") | ||||||
|  |         return | ||||||
|  |  | ||||||
|  |     # Step 2: Create videospeed-github.xpi (exclude script, .git, AND videospeed-github.xpi itself) | ||||||
|  |     exclude_files = [SCRIPT_NAME, "videospeed-github.xpi"] | ||||||
|  |     exclude_dirs = [".git"] | ||||||
|  |     zip_folder("videospeed-github.xpi", current_dir, exclude_files, exclude_dirs) | ||||||
|  |     print("✅ Created videospeed-github.xpi") | ||||||
|  |  | ||||||
|  |     # Step 3: Re-scan for .xpi files after GitHub archive creation, exclude them for Firefox zip | ||||||
|  |     current_xpi_files = set(glob.glob("*.xpi")) | ||||||
|  |     exclude_temp_files = current_xpi_files.union({SCRIPT_NAME}) | ||||||
|  |     exclude_temp_dirs = set(exclude_dirs) | ||||||
|  |  | ||||||
|  |     # Step 4: Create videospeed-firefox.xpi from temp folder with version bumped to .0 | ||||||
|  |     with tempfile.TemporaryDirectory() as temp_dir: | ||||||
|  |         for item in os.listdir(current_dir): | ||||||
|  |             if item in exclude_temp_files or item in exclude_temp_dirs: | ||||||
|  |                 continue | ||||||
|  |             src = os.path.join(current_dir, item) | ||||||
|  |             dst = os.path.join(temp_dir, item) | ||||||
|  |             if os.path.isdir(src): | ||||||
|  |                 shutil.copytree(src, dst) | ||||||
|  |             else: | ||||||
|  |                 shutil.copy2(src, dst) | ||||||
|  |  | ||||||
|  |         temp_manifest = os.path.join(temp_dir, TARGET_FILE) | ||||||
|  |         if os.path.exists(temp_manifest): | ||||||
|  |             update_version_line(temp_manifest, firefox_version) | ||||||
|  |         else: | ||||||
|  |             print(f"⚠️ {TARGET_FILE} not found in temp folder.") | ||||||
|  |  | ||||||
|  |         zip_folder( | ||||||
|  |             "videospeed-firefox.xpi", temp_dir, exclude_files=[], exclude_dirs=[] | ||||||
|  |         ) | ||||||
|  |         print("✅ Created videospeed-firefox.xpi") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   "name": "Video Speed Controller", |   "name": "Video Speed Controller", | ||||||
|   "short_name": "videospeed", |   "short_name": "videospeed", | ||||||
|   "version": "1.1.1", |   "version": "1.5.1", | ||||||
|   "manifest_version": 2, |   "manifest_version": 2, | ||||||
|   "description": "Speed up, slow down, advance and rewind HTML5 audio/video with shortcuts", |   "description": "Speed up, slow down, advance and rewind HTML5 audio/video with shortcuts", | ||||||
|   "homepage_url": "https://github.com/SoPat712/videospeed", |   "homepage_url": "https://github.com/SoPat712/videospeed", | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| <!DOCTYPE html> | <!doctype html> | ||||||
| <html> | <html> | ||||||
|   <head> |   <head> | ||||||
|     <title>Video Speed Controller: Popup</title> |     <title>Video Speed Controller: Popup</title> | ||||||
| @@ -6,6 +6,8 @@ | |||||||
|     <script src="popup.js"></script> |     <script src="popup.js"></script> | ||||||
|   </head> |   </head> | ||||||
|   <body> |   <body> | ||||||
|  |     <button id="refresh">Re-scan Page for Videos</button> | ||||||
|  |     <hr /> | ||||||
|     <button id="enable" class="hide">Enable</button> |     <button id="enable" class="hide">Enable</button> | ||||||
|     <button id="disable">Disable</button> |     <button id="disable">Disable</button> | ||||||
|     <span id="status" class="hide"></span> |     <span id="status" class="hide"></span> | ||||||
|   | |||||||
							
								
								
									
										31
									
								
								popup.js
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								popup.js
									
									
									
									
									
								
							| @@ -19,6 +19,31 @@ document.addEventListener("DOMContentLoaded", function () { | |||||||
|     toggleEnabled(false, settingsSavedReloadMessage); |     toggleEnabled(false, settingsSavedReloadMessage); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|  |   // --- REVISED: "Re-scan" button functionality --- | ||||||
|  |   document.querySelector("#refresh").addEventListener("click", function () { | ||||||
|  |     setStatusMessage("Re-scanning page..."); | ||||||
|  |     chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { | ||||||
|  |       if (tabs[0] && tabs[0].id) { | ||||||
|  |         // Send a message to the content script, asking it to re-initialize. | ||||||
|  |         chrome.tabs.sendMessage( | ||||||
|  |           tabs[0].id, | ||||||
|  |           { action: "rescan_page" }, | ||||||
|  |           function (response) { | ||||||
|  |             if (chrome.runtime.lastError) { | ||||||
|  |               // This error is expected on pages where content scripts cannot run. | ||||||
|  |               setStatusMessage("Cannot run on this page."); | ||||||
|  |             } else if (response && response.status === "complete") { | ||||||
|  |               setStatusMessage("Scan complete. Closing..."); | ||||||
|  |               setTimeout(() => window.close(), 500); // Close popup on success. | ||||||
|  |             } else { | ||||||
|  |               setStatusMessage("Scan failed. Please reload the page."); | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   chrome.storage.sync.get({ enabled: true }, function (storage) { |   chrome.storage.sync.get({ enabled: true }, function (storage) { | ||||||
|     toggleEnabledUI(storage.enabled); |     toggleEnabledUI(storage.enabled); | ||||||
|   }); |   }); | ||||||
| @@ -42,9 +67,9 @@ document.addEventListener("DOMContentLoaded", function () { | |||||||
|     const suffix = `${enabled ? "" : "_disabled"}.png`; |     const suffix = `${enabled ? "" : "_disabled"}.png`; | ||||||
|     chrome.browserAction.setIcon({ |     chrome.browserAction.setIcon({ | ||||||
|       path: { |       path: { | ||||||
|         "19": "icons/icon19" + suffix, |         19: "icons/icon19" + suffix, | ||||||
|         "38": "icons/icon38" + suffix, |         38: "icons/icon38" + suffix, | ||||||
|         "48": "icons/icon48" + suffix |         48: "icons/icon48" + suffix | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								videospeed.xpi
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								videospeed.xpi
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user