最終動作確認日は 2025年3月5日です。
start() で処理を開始しますstop() でいつでも処理を中断できます> のあとにスクリプトをペーストしてEnterを押します> のあとに start() と入力してEnterを押すと処理が始まりますstop() でいつでも処理を中断できますもし下記メッセージがコンソールで出る場合は、allow pasting と入力してください。(初回のみ)
Warning: Don’t paste code into the DevTools Console that you don’t understand or haven’t reviewed yourself. This could allow attackers to steal your identity or take control of your computer. Please type ‘allow pasting’ below and hit Enter to allow pasting.
let stopExecution = false;
const stop = () => {
stopExecution = true;
console.log("⏹️ 処理を停止しました");
};
editDraft = async () => {
return new Promise((resolve, reject) => {
if (stopExecution) return reject("処理が停止されました");
try {
console.log("▶ 編集モードに入ります");
document.querySelector("#row-container > div:nth-child(8) > ytcp-video-list-cell-actions > div > ytcp-button.edit-draft-button.style-scope.ytcp-video-list-cell-actions").click();
setTimeout(() => {
console.log("✅ 編集モードに入りました");
resolve();
}, 3000);
} catch (error) {
console.error("❌ editDraft エラー:", error);
reject(error);
}
});
};
activateNotChild = async () => {
return new Promise((resolve, reject) => {
if (stopExecution) return reject("処理が停止されました");
try {
console.log("▶ 子供向けではない設定を選択");
document.querySelector("#audience > ytkc-made-for-kids-select > div.made-for-kids-rating-container.style-scope.ytkc-made-for-kids-select > tp-yt-paper-radio-group > tp-yt-paper-radio-button:nth-child(2)").click();
setTimeout(() => {
console.log("✅ 子供向けではない設定にしました");
resolve();
}, 3000);
} catch (error) {
console.error("❌ activateNotChild エラー:", error);
reject(error);
}
});
};
activateLastStep = async () => {
return new Promise((resolve, reject) => {
if (stopExecution) return reject("処理が停止されました");
try {
console.log("▶ 公開設定ステップに進みます");
document.querySelector("#step-title-3").click();
setTimeout(() => {
console.log("✅ 公開設定ステップに移動しました");
resolve();
}, 3000);
} catch (error) {
console.error("❌ activateLastStep エラー:", error);
reject(error);
}
});
};
activatePrivate = async () => {
return new Promise((resolve, reject) => {
if (stopExecution) return reject("処理が停止されました");
try {
console.log("▶ 動画を「非公開」に設定します");
document.querySelector("#private-radio-button").click();
setTimeout(() => {
console.log("✅ 動画を「非公開」に設定しました");
resolve();
}, 3000);
} catch (error) {
console.error("❌ activatePrivate エラー:", error);
reject(error);
}
});
};
doneEdit = async () => {
return new Promise((resolve, reject) => {
if (stopExecution) return reject("処理が停止されました");
try {
console.log("▶ 編集内容を保存します");
document.getElementById("done-button").click();
setTimeout(() => {
console.log("✅ 編集内容を保存しました");
resolve();
}, 10000);
} catch (error) {
console.error("❌ doneEdit エラー:", error);
reject(error);
}
});
};
publish = async () => {
try {
await editDraft();
await activateNotChild();
await activateLastStep();
await activatePrivate();
await doneEdit();
console.log("✅ 1件の動画を処理しました\n");
} catch (error) {
console.error("❌ publish 処理中にエラーが発生しました:", error);
}
};
start = async () => {
stopExecution = false;
console.log("🚀 全動画の処理を開始します");
for (let i = 0; i < 50; i++) {
if (stopExecution) {
console.log("⏹️ 処理がユーザーによって停止されました");
break;
}
try {
const button = document.querySelector("#row-container > div:nth-child(8) > ytcp-video-list-cell-actions > div > ytcp-button.edit-draft-button.style-scope.ytcp-video-list-cell-actions");
if (!button) {
console.log("✅ 処理する動画がなくなりました");
break;
}
console.log(`▶ ${i + 1}件目の動画を処理します`);
await publish();
} catch (error) {
console.error(`❌ ${i + 1}件目の処理中にエラーが発生しました:`, error);
}
}
console.log("🎉 全ての処理が完了しました");
};