<!--============== FINAL CLEAN VERSION (NO SUBTITLES, NO MANUAL TITLES) =================-->
<style>
.video-item { margin-bottom: 18px; }
.meta-title { margin-top:8px; font-style:italic; font-size:1.05rem; font-weight:bold; }
.meta-translation { color:#444; margin-bottom:6px; font-size:0.95rem; }
.comment-section { margin-top:10px; }
.comment-input { width:100%; min-height:65px; }
.comment-output { margin-top:8px; background:#f5f5f5; padding:6px; min-height:22px; border-radius:4px; }
</style>
<div id="video-list">
<!--ITEM 1-->
<div class="video-item" data-id="1" data-src="https://youtube.com/shorts/9WVxOv5J2m0">
<br /><br />
<!--VIDEO-->
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/9WVxOv5J2m0" width="100%"></iframe>
<!--AUTO METADATA TITLE-->
<div class="auto-meta"></div>
<!--COMMENTS-->
<div class="comment-section">
<h4>Leave a Comment:</h4>
<textarea class="comment-input"></textarea><br />
<button class="comment-submit">Submit</button>
<div class="comment-output"></div>
</div>
<hr />
</div>
<!--ITEM 2-->
<div class="video-item" data-id="3" data-src="https://youtube.com/shorts/-w182IGAt84">
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/-w182IGAt84" width="100%"></iframe>
<div class="auto-meta"></div>
<div class="comment-section">
<h4>Leave a Comment:</h4>
<textarea class="comment-input"></textarea><br />
<button class="comment-submit">Submit</button>
<div class="comment-output"></div>
</div>
<hr />
</div>
<!--ITEM 3-->
<div class="video-item" data-id="16" data-src="https://youtube.com/shorts/F2j9mWgxV0o">
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/F2j9mWgxV0o" width="100%"></iframe>
<div class="auto-meta"></div>
<div class="comment-section">
<h4>Leave a Comment:</h4>
<textarea class="comment-input"></textarea><br />
<button class="comment-submit">Submit</button>
<div class="comment-output"></div>
</div>
<hr />
</div>
<!--ITEM 4-->
<div class="video-item" data-id="22" data-src="https://youtube.com/shorts/oqtJYTjAnnE">
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/oqtJYTjAnnE" width="100%"></iframe>
<div class="auto-meta"></div>
<div class="comment-section">
<h4>Leave a Comment:</h4>
<textarea class="comment-input"></textarea><br />
<button class="comment-submit">Submit</button>
<div class="comment-output"></div>
</div>
<hr />
</div>
</div>
<script>
/* ============================
SMART TRANSLATION (Google → Libre → MyMemory)
============================ */
const GOOGLE_TRANSLATE_ENDPOINT =
"https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=en&dt=t&q=";
const LIBRETRANSLATE_ENDPOINT = "https://libretranslate.org/translate";
const MYMEMORY_ENDPOINT = "https://api.mymemory.translated.net/get?q=";
async function translateSmartSingle(text) {
if (!text || !text.trim()) return "";
/* Google unofficial */
try {
let r = await fetch(GOOGLE_TRANSLATE_ENDPOINT + encodeURIComponent(text));
if (r.ok) {
let arr = await r.json();
if (Array.isArray(arr) && arr[0]) {
let out = "";
for (let seg of arr[0]) if (seg[0]) out += seg[0];
if (out.trim()) return out;
}
}
} catch(e){}
/* Libre */
try {
let r = await fetch(LIBRETRANSLATE_ENDPOINT, {
method:"POST",
headers:{ "Content-Type":"application/json" },
body:JSON.stringify({
q:text, source:"auto", target:"en", format:"text"
})
});
if (r.ok) {
let j = await r.json();
if (j.translatedText) return j.translatedText;
}
} catch(e){}
/* MyMemory */
try {
let r = await fetch(MYMEMORY_ENDPOINT + encodeURIComponent(text) + "&langpair=auto|en");
if (r.ok) {
let j = await r.json();
if (j.responseData?.translatedText) return j.responseData.translatedText;
}
} catch(e){}
return "(translation unavailable)";
}
/* ============================
Escape HTML
============================ */
function escapeHtml(s){
return String(s).replace(/[&<>"']/g,
m=>({"&":"&","<":"<",">":">","\"":""","'":"'"}[m]));
}
/* ============================
Extract Video ID
============================ */
function extractVideoId(url){
try {
let m = url.match(/(?:v=|shorts\/|embed\/|\.be\/)([A-Za-z0-9_-]{11})/);
return m ? m[1] : null;
} catch(e){ return null; }
}
/* ============================
Load Metadata Title + Translate
============================ */
async function loadMetadata(item, videoURL){
const box = item.querySelector(".auto-meta");
box.innerHTML = "<p><i>Loading metadata...</i></p>";
try {
let r = await fetch("https://www.youtube.com/oembed?url="+encodeURIComponent(videoURL)+"&format=json");
if (!r.ok) throw 0;
let meta = await r.json();
let original = meta.title || "(no title)";
/* Show original metadata title */
box.innerHTML =
`<p class="meta-title">${escapeHtml(original)}</p>
<p class="meta-translation"><b>English:</b> <i>Translating...</i></p>`;
/* Translate to English */
let translated = await translateSmartSingle(original);
box.querySelector(".meta-translation").innerHTML =
`<b>English:</b> ${escapeHtml(translated)}`;
} catch(e){
box.innerHTML = "<p>(Metadata unavailable)</p>";
}
}
/* ============================
COMMENTS DB (UPDATE MODE)
============================ */
function loadCommentsDB(){
let raw = localStorage.getItem("YT_comments_clean_v2");
return raw ? JSON.parse(raw) : {};
}
function saveCommentsDB(db){
localStorage.setItem("YT_comments_clean_v2", JSON.stringify(db));
}
/* ============================
MAIN INITIALIZATION
============================ */
document.addEventListener("DOMContentLoaded", async function(){
const db = loadCommentsDB();
const items = document.querySelectorAll(".video-item");
for (let item of items){
const url = item.getAttribute("data-src");
const id = item.getAttribute("data-id");
/* Load metadata title */
await loadMetadata(item, url);
/* Comment system */
const textarea = item.querySelector(".comment-input");
const output = item.querySelector(".comment-output");
const submit = item.querySelector(".comment-submit");
if (db[id]) {
textarea.value = db[id];
output.innerHTML = `<p>${escapeHtml(db[id])}</p>`;
}
submit.addEventListener("click", function(){
const txt = textarea.value.trim();
if (!txt) return;
db[id] = txt;
saveCommentsDB(db);
output.innerHTML = `<p>${escapeHtml(txt)}</p>`;
textarea.value = txt;
});
}
});
</script>
<!--============== END CLEAN FINAL VERSION (NO SUBTITLES, NO MANUAL TITLES) =================-->
Comments
Post a Comment