Google Chrome Video Extractor

  • 127 Views
  • Last Post 21 March 2025
Chris posted this 26 January 2025

My Friends,

I want to open source a small project I use from time to time: Video Extractor

This is a Google Chrome Extension, so its simple and easy to install, if you use Google Chrome. Its early days, there is a lot that can be done to extend this tool, and make it better! It does not work with video blobs yet. One day soon maybe I will include Blob Videos.

 

Inside a file: Google Chrome Video Extractor, create the file structure:

 

In the File: background.js

chrome.runtime.onInstalled.addListener(() => {
  console.log('Extension installed');
});

 

In the File: content.js

function extractAllVideos() {
  const videos = document.querySelectorAll('video');
  const videoList = Array.from(videos).map((video, index) => {
    const sourceUrl = video.src || (video.querySelector('source') ? video.querySelector('source').src : '');
    const poster = video.poster || '';
    const width = video.width || video.videoWidth;
    const height = video.height || video.videoHeight;
    const videoName = video.getAttribute('title') || `Video ${index + 1}`;
    const videoTag = videuterHTML;
    return { videoTag: videoTag, videoName: videoName, sourceUrl: sourceUrl, poster: poster, width: width, height: height };
  }).filter(video => video.sourceUrl !== ''); // Filter out videos without source URLs
  return videoList;
}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'extractVideos') {
    const videoInfo = extractAllVideos();
    sendResponse(videoInfo);
  }
});

 

In the File: manifest.json

{
  "manifest_version": 3,
  "name": "Video Extractor",
  "version": "1.0",
  "description": "Extracts video tags and their source URLs, then opens videos in a new tab",
  "permissions": [
    "activeTab",
    "scripting"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ]
}

 

In the File: popup.html

<!DOCTYPE html>
<html>

<head>
  <title>Video Extractor</title>
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
      border-radius: 3px;
      width: 473px;
      background-color: #343a40;
      color: white;
    }

    .T {
      margin-top: 3x;
      padding-left: 20px;
      padding-right: 20px;
      border: #454d55 1px solid;
      border-radius: 7px;
    }

    table {
      border: none;
    }

    thead {
    display: table-header-group;
    vertical-align: middle;
    unicode-bidi: isolate;
    border-color: none;
    }

    .video-list {
      max-height: 400px;
      overflow-y: auto;
    }

    .thumbnail {
      width: 124px;
      height: 70px;
      object-fit: cover;
      border-radius: 3px;
    }

    .scrollbar-dark::-webkit-scrollbar {
      width: 8px;
      background-color: #343a40;
    }

    .scrollbar-dark::-webkit-scrollbar-thumb {
      background-color: #6c757d;
      border-radius: 10px;
    }
  </style>
</head>

<body>
  <h3 class="text-center">Video Extractor</h3>
  <div class="T">
    <table class="table table-dark table-striped">
      <thead>
        <tr>
          <th scope="col">Thumbnail</th>
          <th scope="col">Details</th>
        </tr>
      </thead>
      <tbody id="videoList" class="video-list scrollbar-dark"></tbody>
    </table>
  </div>
  <script src="popup.js"></script>
</body>

</html>

 

In the File: popup.js

chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
  const activeTab = tabs[0];
  chrome.scripting.executeScript({
    target: { tabId: activeTab.id },
    function: extractAllVideosInTab
  }, (results) => {
    if (results && results[0] && results[0].result) {
      const videoList = results[0].result;
      displayVideos(videoList);
    } else {
      alert('No videos found on this page.');
    }
  });
});

function extractAllVideosInTab() {
  const videos = document.querySelectorAll('video');
  const videoList = Array.from(videos).map((video, index) => {
    const sourceUrl = video.src || (video.querySelector('source') ? video.querySelector('source').src : '');
    const poster = video.poster || '';
    const width = video.width || video.videoWidth;
    const height = video.height || video.videoHeight;
    const videoName = video.getAttribute('title') || `Video ${index + 1}`;
    const videoTag = videuterHTML;
    return { videoTag: videoTag, videoName: videoName, sourceUrl: sourceUrl, poster: poster, width: width, height: height };
  }).filter(video => video.sourceUrl !== ''); // Filter out videos without source URLs
  return videoList;
}

function displayVideos(videoList) {
  const videoListElement = document.getElementById('videoList');
  videoListElement.innerHTML = '';
  videoList.forEach(video => {
    const row = document.createElement('tr');

    const thumbnailCell = document.createElement('td');
    const thumbnail = document.createElement('img');
    thumbnail.src = video.poster || 'https://via.placeholder.com/124x70?text=No+Thumbnail';
    thumbnail.className = 'thumbnail';
    thumbnailCell.appendChild(thumbnail);

    const detailsCell = document.createElement('td');
    detailsCell.innerHTML = `
      <strong>${video.videoName}</strong><br>
      <small>Width: ${video.width}px, Height: ${video.height}px</small><br>
      <a href="${video.sourceUrl}" target="_blank" style="color: #17a2b8;">Source URL</a>
    `;

    row.appendChild(thumbnailCell);
    row.appendChild(detailsCell);
    videoListElement.appendChild(row);
  });
}

 

Easy, then once you have this done, all you need to do is add the extension:

Adding a Google Chrome extension is pretty straightforward! Here's a step-by-step guide:

  1. Open Chrome: Make sure you're using the Google Chrome browser.
  2. Go to the Chrome Web Store: You can access it by clicking on this [link](https://support.google.com/chrome_webstore/answer/2664769?hl=en).
  3. Find an Extension: Use the search bar or browse through categories to find the extension you want.
  4. Click "Add to Chrome": Once you've found an extension you like, click the "Add to Chrome" button.
  5. Confirm Installation: A pop-up will appear asking for confirmation. Click "Add Extension" to install it.
  6. Access the Extension: After installation, you'll see the extension's icon next to the address bar. Click on it to start using the extension.

And that's it! You're all set to enjoy your new extension. 😊

 

Once done, you will be able to access Video Extractor like so:

 

Enjoy!

Best Wishes,

   Chris

  • Liked by
  • FringeIdeas
  • Augenblick
Chris posted this 21 March 2025

My Friends,

A small update on this small but very useful project:

Background.js

const videoFormats = [".mp4", ".webm", ".m3u8"];

chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    if (videoFormats.some((format) => details.url.includes(format)) || details.url.startsWith("blob:")) {
      chrome.runtime.sendMessage({ type: "videoDetected", url: details.url });
    }
  },
  { urls: ["<all_urls>"] },
  []
);

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript(
    {
      target: { tabId: tab.id, allFrames: true },
      files: ["content.js"],
    },
    () => {
      console.log("Content script injected into all frames");
    }
  );
});

 

Content.js

const parentPageTitle = document.title;

function extractAllVideos() {
  try {
    const videos = document.querySelectorAll('video');
    Array.from(videos).forEach((video, index) => {
      const src = video.src || (video.querySelector('source') ? video.querySelector('source').src : '');
      const poster = video.poster || 'thumb.ico';
      const width = video.videoWidth || video.width || "Unknown";
      const height = video.videoHeight || video.height || "Unknown";
      const videoName = video.getAttribute('title') || video.getAttribute('alt') || `Video ${index + 1}`;

      if (src) {
        chrome.runtime.sendMessage({
          type: "videoDetected",
          url: src,
          poster: poster,
          name: videoName,
          width: width.toString(),
          height: height.toString(),
          pageTitle: parentPageTitle,
        });
      }
    });
  } catch (error) {
    console.error("Error extracting videos:", error);
  }
}

function detectVideosInIFrames() {
  const iframes = document.querySelectorAll("iframe");

  iframes.forEach((iframe, index) => {
    iframe.addEventListener('load', () => {
      try {
        iframe.contentWindow.postMessage({ type: "extractVideos" }, "*");
      } catch (error) {
        console.error(`Unable to access iframe at index ${index}:`, error);
      }
    });

    try {
      if (!iframe.contentWindow || !iframe.contentDocument || !iframe.contentDocument.body) {
        throw new Error("iframe content is null or inaccessible.");
      }
      console.log(`iframe at index ${index} loaded successfully.`);
    } catch (error) {
      console.error(`Error checking iframe at index ${index}:`, error);
    }
  });
}

window.addEventListener('message', (event) => {
  if (event.data.type === "videoDetectedFromIframe") {
    chrome.runtime.sendMessage({
      type: "videoDetected",
      url: event.data.url,
      poster: event.data.poster,
      name: event.data.name,
      width: event.data.width,
      height: event.data.height,
      pageTitle: event.data.pageTitle,
    });
  }
});

chrome.runtime.onMessage.addListener((message) => {
  if (message.type === "requestPageData") {
    extractAllVideos();
    detectVideosInIFrames();
  }
});

window.addEventListener('load', () => {
  extractAllVideos();
  detectVideosInIFrames();

  const observer = new MutationObserver(() => {
    extractAllVideos();
    detectVideosInIFrames();
  });

  observer.observe(document.body, { childList: true, subtree: true });
});

 

Iframe_Content.js

const parentPageTitle = document.title;

function extractAllVideos(container = document) {
  try {
    const videos = container.querySelectorAll('video');
    Array.from(videos).forEach((video, index) => {
      const src = video.src || (video.querySelector('source') ? video.querySelector('source').src : '');
      const poster = video.poster || 'thumb.ico';
      const width = video.videoWidth || video.width || "Unknown";
      const height = video.videoHeight || video.height || "Unknown";
      const videoName = video.getAttribute('title') || video.getAttribute('alt') || `Video ${index + 1}`;

      if (src) {
        window.parent.postMessage({
          type: "videoDetectedFromIframe",
          url: src,
          poster: poster,
          name: videoName,
          width: width.toString(),
          height: height.toString(),
          pageTitle: parentPageTitle,
        }, "*");
      }
    });
  } catch (error) {
    console.error("Error extracting videos:", error);
  }
}

window.addEventListener('message', (event) => {
  if (event.data.type === "extractVideos") {
    extractAllVideos();
  }
});

window.addEventListener('load', () => {
  extractAllVideos();

  const observer = new MutationObserver(() => {
    extractAllVideos();
  });

  observer.observe(document.body, { childList: true, subtree: true });
});

 

Manifest.json

{
  "manifest_version": 3,
  "name": "Video Extractor",
  "version": "1.0",
  "description": "Extracts videos from web pages",
  "permissions": [
    "activeTab",
    "scripting",
    "tabs",
    "storage",
    "webNavigation",
    "webRequest",
    "webRequestBlocking"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "run_at": "document_end",
      "all_frames": true
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["iframe_content.js"],
      "matches": ["<all_urls>"]
    }
  ]
}

 

Popup.html

<!DOCTYPE html>
<html>

<head>
  <title>Video Extractor</title>
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
      border-radius: 3px;
      width: 673px;
      background-color: #343a40;
      color: white;
    }

    .T {
      top: 2x;
      padding-left: 20px;
      padding-right: 20px;
      border: #454d55 1px solid;
      border-radius: 7px;
    }

    table {
      border: none;
    }

    .thumbnail-cell{
      width: 184px;
    }

    .video-list {
      max-height: 400px;
      overflow-y: auto;
    }

    .thumbnail {
      width: 164px;
      height: 90px;
      object-fit: cover;
      border-radius: 3px;
    }

    .scrollbar-dark::-webkit-scrollbar {
      width: 8px;
      background-color: #343a40;
    }

    .scrollbar-dark::-webkit-scrollbar-thumb {
      background-color: #6c757d;
      border-radius: 10px;
    }
  </style>
</head>

<body>
  <h3 class="text-center">Video Extractor</h3>
  <div class="T">
    <table class="table table-dark table-striped">
      <thead>
        <tr>
          <th scope="col">Thumbnail</th>
          <th scope="col">Details</th>
        </tr>
      </thead>
      <tbody id="videoList" class="video-list scrollbar-dark"></tbody>
    </table>
  </div>
  <script src="popup.js"></script>
</body>

</html>

 

Popup.js

document.addEventListener("DOMContentLoaded", async () => {
  const videoList = document.getElementById("videoList");

  // Get active tab
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

  // Inject and execute content script in all frames
  chrome.scripting.executeScript(
    {
      target: { tabId: tab.id, allFrames: true },
      func: async () => {
        const videos = [];
        const iframes = document.querySelectorAll('iframe');

        for (const iframe of iframes) {
          await new Promise((resolve) => {
            iframe.onload = resolve;
            if (iframe.contentDocument.readyState === 'complete') {
              resolve();
            }
          });

          const iframeVideos = Array.from(iframe.contentDocument.querySelectorAll('video')).map((video) => ({
            src: video.currentSrc || video.src,
            poster: video.poster || "",
            width: video.videoWidth || "Unknown",
            height: video.videoHeight || "Unknown",
            title: video.getAttribute('title') || "Unnamed Video",
          }));
          videos.push(...iframeVideos);
        }

        const mainVideos = Array.from(document.querySelectorAll("video")).map((video) => ({
          src: video.currentSrc || video.src,
          poster: video.poster || "",
          width: video.videoWidth || "Unknown",
          height: video.videoHeight || "Unknown",
          title: document.title || "Unnamed Video",
        }));

        videos.push(...mainVideos);
        return videos;
      },
    },
    (injectionResults) => {
      if (!injectionResults || injectionResults.length === 0) {
        videoList.innerHTML = "<p>No videos found.</p>";
        return;
      }

      // Combine results from all frames
      const videos = injectionResults.flatMap((result) => result.result);

      // Display videos
      if (videos.length === 0) {
        videoList.innerHTML = "<p>No videos found.</p>";
        return;
      }

      videos.forEach((video) => {
        const row = document.createElement("tr");
        row.innerHTML = `
          <td class="thumbnail-cell">
            <img src="${video.poster}" class="thumbnail" alt="Video Thumbnail" />
          </td>
          <td>
            <div>
              <strong>${video.title}</strong>
              <p>Resolution: ${video.width} x ${video.height}</p>
              <a href="${video.src}" target="_blank" class="btn btn-sm btn-primary">Open in New Tab</a>
              <a href="${video.src}" download class="btn btn-sm btn-success">Download</a>
            </div>
          </td>
        `;
        videoList.appendChild(row);
      });
    }
  );
});

 

You need a Thumb Nail and a Icon for the project.

This is a lot better than it was before:

 

Enjoy My Friends...

Best Wishes,

   Chris

We're Light Years Ahead!
Members Online:

No one online at the moment


What is a Scalar:

In physics, scalars are physical quantities that are unaffected by changes to a vector space basis. Scalars are often accompanied by units of measurement, as in "10 cm". Examples of scalar quantities are mass, distance, charge, volume, time, speed, and the magnitude of physical vectors in general.

You need to forget the Non-Sense that some spout with out knowing the actual Definition of the word Scalar! Some people talk absolute Bull Sh*t!

The pressure P in the formula P = pgh, pgh is a scalar that tells you the amount of this squashing force per unit area in a fluid.

A Scalar, having both direction and magnitude, can be anything! The Magnetic Field, a Charge moving, yet some Numb Nuts think it means Magic Science!

Message from God:

Hello my children. This is Yahweh, the one true Lord. You have found creation's secret. Now share it peacefully with the world.

Ref: Message from God written inside the Human Genome

God be in my head, and in my thinking.

God be in my eyes, and in my looking.

God be in my mouth, and in my speaking.

Oh, God be in my heart, and in my understanding.

We love and trust in our Lord, Jesus Christ of Nazareth!

Your Support:

More than anything else, your contributions to this forum are most important! We are trying to actively get all visitors involved, but we do only have a few main contributors, which are very much appreciated! If you would like to see more pages with more detailed experiments and answers, perhaps a contribution of another type maybe possible:

PayPal De-Platformed me!

They REFUSE to tell me why!

We now use Wise!

Donate
Use E-Mail: Chris at aboveunity.com

The content I am sharing is not only unique, but is changing the world as we know it! Please Support Us!

Thank You So Much!

Weeks High Earners:
The great Nikola Tesla:

Ere many generations pass, our machinery will be driven by a power obtainable at any point of the universe. This idea is not novel. Men have been led to it long ago by instinct or reason. It has been expressed in many ways, and in many places, in the history of old and new. We find it in the delightful myth of Antheus, who drives power from the earth; we find it among the subtle speculations of one of your splendid mathematicians, and in many hints and statements of thinkers of the present time. Throughout space there is energy. Is this energy static or kinetic? If static, our hopes are in vain; if kinetic - and this we know it is for certain - then it is a mere question of time when men will succeed in attaching their machinery to the very wheelwork of nature.

Experiments With Alternate Currents Of High Potential And High Frequency (February 1892).

Close