#author("2025-03-05T17:51:44+09:00","default:nemusg.pad","nemusg.pad") #author("2025-08-24T23:11:46+09:00;2025-03-05T17:51:44+09:00","default:nemusg.pad","nemusg.pad") #title(Youtube Draft Edit) * 概要 [#udc587dd] 最終動作確認日は 2025年3月5日です。 - YoutubeStudioの「ドラフト」状態のファイルを「非公開」状態にする作業をしてくれるスクリプトです - Chromeのコンソール画面で使用します。Firefoxでも動きました。 - [[YouTube Studioのドラフト編集を楽にしたい #JavaScript - Qiita:https://qiita.com/fkdfkdfkd/items/a478db193476f489f71f]] -- この方のスクリプトの改変版です。 -- ChatGPT使用 &ref(output/youtube_draft_edit/capture1.png,20%); &ref(output/youtube_draft_edit/capture2.png,20%); * 本家との違い [#b1de05b8] - (本当は限定公開にできるようにしたかったのですが、変更後に表示されるUIが異なるため頓挫しています。一度非公開にさえできればYoutubeStudio側で一括編集が可能です。) - 進捗やエラー処理をコンソールに表示します - `start()` で処理を開始します - `stop()` でいつでも処理を中断できます * 利用手順 [#f4030370] - まず、[[YoutubeStudio:https://studio.youtube.com/channel/]]のコンテンツ画面で変更してもいい動画だけを表示します。(つまり、最大50件が一度に処理できる数です) -- 画面解像度が低いとYouTube側のUIが変わってしまうので動かなそうです。モニターが小さい場合、ブラウザの表示を縮小するとうまく動作する場合があります。 - 「公開状態:ドラフト」でフィルタをかけて「非公開」状態になってもいい動画のみを表示させます。&br;''(注意:公開状態の動画も非公開になります)'' - Google Chromeの開発ツールを表示し、コンソール(Console)画面を出します。 - `>` のあとにスクリプトをペーストして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. * スクリプト [#tddb4b5b] #code_x{{ 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("🎉 全ての処理が完了しました"); }; }} #include(parts/feedback,notitle)