Я пытаюсь автоматически добавлять рекламные паузы в свои видеоролики на YouTube, выполняя в консоли браузера небольшой скрипт (написанный на Javascript).
Мой подход следующий:
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;
}Текущий статус следующий:
Так что похоже, что скрипты добавляют паузы, а также заполняют метки времени.
Проблема в том, что поле ввода отметки времени каким-то образом неправильно «срабатывает». Рекламные маркеры почему-то не добавляются. Они неправильно распознаются как новые рекламные паузы. Глянь сюда:
В норме должны быть такие маркеры:
Таким образом, рекламные паузы действительно не добавляются.
Поэтому я попытался немного улучшить функцию fillBreaksTimeStamps() и попробовал следующее:
adBreakInput.focus();
adBreakInput.value = relatedBreakTimeStamp;
adBreakInput.dispatchEvent(new Event("change"));
Но также запуск .focus() или отправка события изменения не помогают.
Какие-либо предложения?
Вместо этого я бы порекомендовал вам сначала попробовать отправить события (см. статью MDN «Создание и запуск событий»). Если это не сработает, лучше просто имитировать ввод пользователя с помощью чего-то вроде AutoHotKey.
@Damzaky Если вы хотите поддержать, давайте напишем в личку. Я мог бы предложить поделиться своим экраном.
не могу обещать вам решить эту проблему, но давайте попробуем
@Damzaky, где с тобой связаться? У тебя есть инстаграм, дискорд такой?
@Damzaky не получил ни одного письма



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


во-первых, есть некоторые вещи, которые нельзя имитировать, например свойство Event.isTrusted, по которому можно определить, был ли это ввод пользователя или ввод, добавленный программно. Я думаю, что на YouTube могут быть установлены некоторые границы, чтобы предотвратить любые злонамеренные действия. есть много ресурсов, которые могут помочь:
Как имитировать щелчок мыши с помощью JavaScript?
Можно ли программно имитировать события нажатия клавиш?
Как вызвать событие в JavaScript?
Возможно, вы найдете там свое решение.
Лично мне проще просто создать скрипт autohotkey, который позволяет нажимать любую кнопку в правильном порядке. (вы можете либо жестко запрограммировать позиции мыши, либо просто указать ahk, чтобы найти изображение на экране, например, кнопку.) вот код прототипа, который может решить вашу проблему с js:
//modified code from https://stackoverflow.com/questions/6157929/how-to-simulate-a-mouse-click-using-javascript
//added a function that makes pointer event coordinates to be at the exact coordinates of the clicked element
var defaultOptions = {
pointerX: 0,
pointerY: 0,
button: 0,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
bubbles: true,
cancelable: true
}
function extend(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
}
var eventMatchers = {
'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/
}
//function that simulates typing of a string
function typeString(element, str){
for (var i = 0; i < str.length; i++){
var keyCode = str.charCodeAt(i);
simulateKeyboard(element, "keydown", {keyCode: keyCode});
simulateKeyboard(element, "keypress", {keyCode: keyCode});
simulateKeyboard(element, "keyup", {keyCode: keyCode});
element.value += str[i];
}
}
//in order to automatically add ad breaks to the video, we can use it like this:
simulate(document.querySelector("#add-ad-break"), "mousedown");
simulate(document.querySelector("#add-ad-break"), "click");
simulate(document.querySelector("#add-ad-break"), "mouseup");
//you can play around a bit and see if it works
typeString(document.querySelector("#search"), "hello world");
//now send enter or tab in order for youtube to recognize the input
simulateKeyboard(document.querySelector("#search"), "keydown", {keyCode: 13});
function simulate(element, eventName, extraoptions) {
var options = extend(defaultOptions, extraoptions || {});
var oEvent, eventType = null;
//get position of element and set pointer event coordinates to be at the exact coordinates of the clicked element
var rect = element.getBoundingClientRect();
options.pointerX = rect.left + rect.width/2;
options.pointerY = rect.top + rect.height/2;
for (var name in eventMatchers) {
if (eventMatchers[name].test(eventName)) { eventType = name; break; }
}
if (!eventType)
throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');
if (document.createEvent) {
oEvent = document.createEvent(eventType);
if (eventType == 'HTMLEvents') {
oEvent.initEvent(eventName, options.bubbles, options.cancelable);
}
else {
oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
}
element.dispatchEvent(oEvent);
}
else {
options.clientX = options.pointerX;
options.clientY = options.pointerY;
var evt = document.createEventObject();
oEvent = extend(evt, options);
element.fireEvent('on' + eventName, oEvent);
}
return element;
}
function simulateKeyboard(element, eventName, extraoptions) {
var options = extend(defaultOptions, extraoptions || {});
var oEvent, eventType = null;
if (document.createEvent) {
oEvent = document.createEvent("KeyboardEvent");
oEvent.initKeyboardEvent(eventName, options.bubbles, options.cancelable, document.defaultView, options.key, options.location, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.repeat, options.locale);
element.dispatchEvent(oEvent);
}
else {
var evt = document.createEventObject();
oEvent = extend(evt, options);
element.fireEvent('on' + eventName, oEvent);
}
return element;
}<input type=text id=search>
<button onclick = "console.info('click')" id=add-ad-break>onclick</button>если это поможет или вам нужен сценарий ahk, напишите комментарий.
Поскольку у меня нет монетизированной учетной записи YouTube, это довольно сложно проверить. Я думаю, что вы на правильном пути в своем сценарии, если это входное значение на самом деле является тем, которое вызывает «рекламные паузы» внизу. Проблема, вероятно, в том, как вы обновляете входное значение, вам, вероятно, нужно найти способ, которым ввод текста вызывает добавление разрывов:
Одним из методов, которые я использовал раньше, было использование document.execCommand:
textInput.focus();
document.execCommand('insertText', false, '00:10:00');
Вы также можете попробовать что-то вроде изменения значения, а затем вызвать событие onChange после изменения его значения с помощью .value, execCommand или других вещей:
textInput.value = '00:10:00';
// one of these OR both of them
textInput.dispatchEvent(new Event('input', { bubbles: true }));
textInput.dispatchEvent(new Event('change'));
Но на самом деле это не гарантирует, потому что я не могу протестировать это на своем канале YouTube, поэтому вам действительно придется попробовать их по одному или даже объединить их все.
Я думаю, что также стоит проверить, какие прослушиватели событий привязаны к вводу текста с помощью getEventListeners(element), например. это прослушиватели событий, которые мы можем увидеть, если проверим панель поиска на домашней странице Википедии:
getEventListeners($0);
Результаты:
{
"input": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "input"
},
{
"useCapture": false,
"passive": false,
"once": false,
"type": "input"
}
],
"compositionstart": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "compositionstart"
}
],
"compositionend": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "compositionend"
}
],
"change": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "change"
},
{
"useCapture": false,
"passive": false,
"once": false,
"type": "change"
}
],
"focus": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "focus"
}
],
"blur": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "blur"
}
],
"keydown": [
{
"useCapture": false,
"passive": false,
"once": false,
"type": "keydown"
}
]
}
Затем вы можете попытаться вызвать эти события.
Если это не сработало, мы также можем попытаться проверить, какие события запускаются, если мы выполняем обычный ввод вручную (без JavaScript). Сначала мы можем выбрать элемент, который вам нужен, с помощью элемента проверки и поискать входные данные (или вы можете найти способ получить входные данные элемента, например, с помощью document.querySelector или чего-то еще). Найдя его, выберите его в инструментах разработчика, затем введите следующую строку:
monitorEvents($0); // if you use the select method, $0 will be the element that you selected in the inspect element
// OR
monitorEvents(document.querySelector('input');
Затем нажмите Enter.
Например, это отслеживаемые события, когда я ввожу «ключ» в панель поиска в Википедии:
Найдя эти события, вы можете попытаться воспроизвести их по порядку, а также при необходимости объединить их с вышеуказанными методами.
Честно говоря, сделать это без тестирования довольно сложно, потому что, к сожалению, у меня нет монетизированной учетной записи YouTube. Я твердо верю, что это вполне возможно с помощью консольных сценариев, нам просто нужно найти способ его запустить. Я попытаюсь создать для этого монетизированную учетную запись YouTube, хотя это может занять много времени, но я обновлю этот ответ, как только получу рабочий сценарий, пожелайте мне удачи.
Хотя это еще не работающее решение, я очень ценю вашу помощь через TeamViewer, а также ваши общие усилия и участие в решении проблемы.
довольно сложно ответить, так как, я думаю, не так много разработчиков, которые монетизируют канал