Programmatically add youtube ad breaks to own video via script (in JS)

I try to automatically add some ad breaks to my own YouTube videos by executing a small script in the browser console (written in Javascript).

YouTube ad breaks

My approach is the following one:

const videoLengthInSeconds = 615;
const breakInterval = 15;
const desiredAmountOfBreaks = Math.round(videoLengthInSeconds / breakInterval);

const breakTimeStamps = Array(desiredAmountOfBreaks)
  .fill(0)
  .map((_, i) => {
    return (
      ("0" + ~~(i / 4) + ":0" + 60 * ((i / 4) % 1)).replace(/\d(\d\d)/g, "$1") +
      ":00"
    );
  })
  .slice(1);

function start() {
  breakTimeStamps.forEach(() => {
    document.querySelector("#add-ad-break").click();
  });
  doPolling();
}

let stopPolling = false;

function doPolling() {
  setTimeout(function() {
    if (!stopPolling) {
      const allAdsInDom = document.querySelectorAll(
        ".ytve-ad-breaks-editor-options-panel .ad-break-row"
      );

      if (allAdsInDom.length === desiredAmountOfBreaks - 1) {
        stopPolling = true;
        fillBreaksTimeStamps();
      }
      doPolling();
    }
  }, 2000);
}

function fillBreaksTimeStamps() {
  getAllAdsInDom().forEach((adsItem, i) => {
    const adBreakInput = adsItem.querySelector("#content-container input");
    const relatedBreakTimeStamp = breakTimeStamps[i];
    adBreakInput.value = relatedBreakTimeStamp;
  });
}

function getAllAdsInDom() {
  const allAds = Array.from(
    document.querySelectorAll(
      ".ytve-ad-breaks-editor-options-panel .ad-break-row"
    )
  );
  return allAds;
}

The current status is the following:
Current status after code execution

So it seems that the scripts adds the breaks and also fills out the time stamps.

The problem is: The time stamp input field is somehow not correctly “triggered”.
The ad markers are not added somehow. They are not correctly recognized as new ad breaks. See here:

Add breaks - somehow no markers

Normally there should be these markers:

markers

So no ad breaks are really added.

Therefor I tried to improve the function fillBreaksTimeStamps() a bit and tried this:

adBreakInput.focus();
adBreakInput.value = relatedBreakTimeStamp;
adBreakInput.dispatchEvent(new Event("change"));

But also triggering the .focus() or dispatching the change event does not help.

Any suggestions?

What about the input event?

I am guessing if you backspace a zero and replace it after your script runs it will trigger what you want.

Leave a Comment