New:Socket for Asana Is Now Available.Learn more
Get Started

Screenshot for YouTube™ | 4K Frame & Thumbnail Cap

Package Overview
Versions
2
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

youtube-frame-extractor@example.com - firefox Package Compare versions

Comparing version
1.2.1
to
1.2.2
+1
-1
manifest.json
{
"manifest_version": 2,
"name": "YouTube Screenshot Tool",
"version": "1.2.1",
"version": "1.2.2",
"description": "Extract high-quality frames from YouTube videos without UI elements",

@@ -6,0 +6,0 @@ "default_locale": "en",

@@ -61,3 +61,3 @@ // YouTube Screenshot Tool - Popup Script

toolsLabel: "Tools & Settings",
openThumbnailTool: "Open Thumbnail Tool",
openThumbnailTool: "Open Thumbnail",
shareMessage: "I'm loving this YouTube Screenshot Tool! It helps me extract high-quality frames. Try it: " + STORE_URL,

@@ -83,3 +83,3 @@ copied: "Copied! ✅"

toolsLabel: "الأدوات والإعدادات",
openThumbnailTool: "فتح أداة الصور المصغرة",
openThumbnailTool: "فتح الصورة المصغرة",
shareMessage: "أداة رائعة لالتقاط الصور من يوتيوب بجودة عالية! جربها: " + STORE_URL,

@@ -132,4 +132,4 @@ copied: "تم النسخ! ✅"

const tabs = await browserAPI.tabs.query({ active: true, currentWindow: true });
if (tabs.length > 0 && tabs[0].url && tabs[0].url.includes('youtube.com/watch')) {
videoUrlDisplay.textContent = tabs[0].url; // Changed to textContent for span
if (tabs.length > 0 && tabs[0].url && (tabs[0].url.includes('youtube.com/watch') || tabs[0].url.includes('youtu.be/'))) {
videoUrlDisplay.textContent = tabs[0].url;
openThumbnailToolBtn.disabled = false;

@@ -143,3 +143,3 @@ openThumbnailToolBtn.classList.remove('disabled');

// Remove old listeners to avoid duplicates (though DOMContentLoaded runs once)
// Remove old listeners to avoid duplicates
const newBtn = openThumbnailToolBtn.cloneNode(true);

@@ -150,6 +150,10 @@ openThumbnailToolBtn.parentNode.replaceChild(newBtn, openThumbnailToolBtn);

const url = videoUrlDisplay.textContent;
if (url && url.includes('youtube.com')) {
// Open external tool with the video URL as a parameter
const thumbUrl = `https://thumz.vercel.app/?video=${encodeURIComponent(url)}`;
const videoId = extractVideoId(url);
if (videoId) {
// Open the maximum resolution thumbnail directly
const thumbUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
browserAPI.tabs.create({ url: thumbUrl });
} else {
showStatus('Could not extract video ID', 'error');
}

@@ -163,2 +167,9 @@ });

// Helper: Extract Video ID
function extractVideoId(url) {
const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
const match = url.match(regExp);
return (match && match[2].length === 11) ? match[2] : null;
}
// Update shortcut display

@@ -186,3 +197,22 @@ async function updateShortcutDisplay() {

changeShortcutBtn.addEventListener('click', () => {
browserAPI.tabs.create({ url: 'chrome://extensions/shortcuts' });
if (navigator.userAgent.toLowerCase().includes('firefox')) {
const currentLang = document.querySelector('.language-btn.active').dataset.lang || 'en';
const messages = {
en: "To change shortcuts in Firefox: Go to Add-ons (Ctrl+Shift+A) > Gear Icon > Manage Extension Shortcuts",
ar: "لتغيير الاختصارات في فايرفوكس: اذهب إلى الإضافات (Ctrl+Shift+A) > أيقونة الترس > إدارة اختصارات الإضافات"
};
// Show message with longer duration for readability
const statusElement = document.getElementById('statusMessage');
if (statusElement) {
statusElement.textContent = messages[currentLang];
statusElement.className = 'status-message info';
statusElement.style.display = 'block';
setTimeout(() => {
statusElement.style.display = 'none';
}, 8000); // 8 seconds to read
}
} else {
browserAPI.tabs.create({ url: 'chrome://extensions/shortcuts' });
}
});

@@ -189,0 +219,0 @@ }

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thumz - YouTube Thumbnail Tool</title>
<style>
:root {
--primary-color: #2196F3;
--primary-hover: #1976D2;
--bg-color: #f5f7fa;
--card-bg: #ffffff;
--text-color: #333333;
--border-color: #e0e0e0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
width: 100%;
max-width: 600px;
padding: 20px;
}
.card {
background-color: var(--card-bg);
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 30px;
text-align: center;
}
h1 {
margin-top: 0;
color: var(--primary-color);
font-size: 24px;
margin-bottom: 20px;
}
.input-group {
margin-bottom: 20px;
text-align: left;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
font-size: 14px;
}
input[type="text"] {
width: 100%;
padding: 12px;
border: 1px solid var(--border-color);
border-radius: 8px;
font-size: 16px;
box-sizing: border-box;
transition: border-color 0.3s;
}
input[type="text"]:focus {
border-color: var(--primary-color);
outline: none;
}
.btn {
background-color: var(--primary-color);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: background-color 0.3s;
width: 100%;
}
.btn:hover {
background-color: var(--primary-hover);
}
.preview-area {
margin-top: 30px;
border-top: 1px solid var(--border-color);
padding-top: 20px;
display: none;
}
.preview-placeholder {
background-color: #eee;
height: 200px;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
color: #888;
margin-bottom: 15px;
}
.preview-img {
max-width: 100%;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.status-msg {
margin-top: 10px;
font-size: 14px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<h1>Thumz Downloader</h1>
<div class="input-group">
<label for="videoUrl">YouTube Video URL / ID</label>
<input type="text" id="videoUrl" placeholder="Enter YouTube URL or ID...">
</div>
<button id="generateBtn" class="btn">Generate Thumbnail</button>
<div id="previewArea" class="preview-area">
<h3>Preview</h3>
<div id="imageContainer">
<div class="preview-placeholder">
<span>Image Preview Will Appear Here</span>
</div>
</div>
<p class="status-msg">
Processing on external server...
</p>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const videoInput = document.getElementById('videoUrl');
const generateBtn = document.getElementById('generateBtn');
const previewArea = document.getElementById('previewArea');
const imageContainer = document.getElementById('imageContainer');
// 1. Read 'video' query parameter
const urlParams = new URLSearchParams(window.location.search);
const videoParam = urlParams.get('video');
if (videoParam) {
videoInput.value = videoParam;
// Auto-click generate if URL is present
// setTimeout(() => generateBtn.click(), 500);
}
// 2. Handle Generate Button
generateBtn.addEventListener('click', () => {
const val = videoInput.value.trim();
if (!val) {
alert('Please enter a video URL or ID');
return;
}
generateThumbnail(val);
});
// 3. Generation Logic
function generateThumbnail(videoValue) {
previewArea.style.display = 'block';
// Extract ID
let videoId = videoValue;
const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
const match = videoValue.match(regExp);
if (match && match[7].length == 11) {
videoId = match[7];
}
console.log('Processing video ID:', videoId);
// Display High Res Thumbnail directly from YouTube (Client-side)
// This is safe on a standard web page (not extension popup)
const maxResUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
imageContainer.innerHTML = `
<img src="${maxResUrl}" class="preview-img" alt="Thumbnail">
<div style="margin-top: 15px;">
<a href="${maxResUrl}" download="thumbnail.jpg" target="_blank" class="btn" style="display: inline-block; text-decoration: none; width: auto;">Download HD Image</a>
</div>
`;
}
});
</script>
</body>
</html>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet