ダウンロード準備中...
初期設定(後から変更可能)
プロキシサーバーを利用する
外部APIへの通信時にCORSプロキシを経由します(推奨)
デフォルトストリーム
動画再生時の初期プレイヤーを選択します
ホームにトレンド動画を表示
ダークモード
動画を読み込み中...
ショート動画を読み込み中...
チャンネル名
@channel
登録者数 -- • 動画 --件

タイトル

投稿者
登録者数 --
--- 回視聴 • --- 高評価
概要欄を読み込んでいます...
続きを読む
0 件のコメント
次の動画

視聴履歴

設定
プロキシ
ストリーム
トレンド
ダークモード
登録チャンネル管理
// =================== ショートUI ヘルパー関数 =================== function toggleShortLike(btn) { const icon = btn.querySelector('.icon'); const span = btn.querySelector('.short-like-count'); const isLiked = btn.dataset.liked === '1'; btn.dataset.liked = isLiked ? '0' : '1'; icon.style.color = isLiked ? '' : '#ff0000'; if (span) { const cur = parseInt(span.textContent.replace(/[^0-9]/g,'')) || 0; const newVal = isLiked ? Math.max(0, cur - 1) : cur + 1; span.textContent = newVal >= 10000 ? (newVal/1000).toFixed(0)+'K' : newVal.toLocaleString(); } } function toggleShortDislike(btn) { const icon = btn.querySelector('.icon'); const isDisliked = btn.dataset.disliked === '1'; btn.dataset.disliked = isDisliked ? '0' : '1'; icon.style.color = isDisliked ? '' : '#aaa'; } function shareShort(videoId) { const url = `${location.origin}/shorts/${videoId}`; if (navigator.share) { navigator.share({ url, title: 'ショート動画' }).catch(() => {}); } else if (navigator.clipboard) { navigator.clipboard.writeText(url).then(() => alert('リンクをコピーしました!')).catch(() => alert(url)); } else { alert(url); } } async function openShortComments(videoId, title) { const panel = document.getElementById(`short-comments-panel-${videoId}`); if (!panel) return; panel.style.display = 'block'; const content = document.getElementById(`short-comments-content-${videoId}`); if (content.dataset.loaded === '1') return; content.innerHTML = '
コメントを読み込み中...
'; content.dataset.loaded = '1'; const apis = [ `https://inv.nadeko.net/api/v1/comments/${videoId}`, `https://inv.vern.cc/api/v1/comments/${videoId}`, ...INVIDIOUS_INSTANCES.slice(0,4).map(i => `${i}/api/v1/comments/${videoId}`) ]; let comments = []; for (const url of apis) { try { const res = await fetch(url, { signal: AbortSignal.timeout(6000) }); if (!res.ok) continue; const data = await res.json(); if (data.comments && data.comments.length > 0) { comments = data.comments; break; } } catch(e) {} } if (comments.length === 0) { content.innerHTML = '
コメントを読み込めませんでした。
'; return; } content.innerHTML = comments.slice(0, 15).map(c => `
${c.author || '名無し'}
${(c.content||'').replace(/\n/g,'
')}
`).join(''); } function closeShortComments(videoId) { const panel = document.getElementById(`short-comments-panel-${videoId}`); if (panel) panel.style.display = 'none'; } function toggleSubscribeFromShort(channelName, thumb, btn) { let subs = getSubscriptions(); if (isSubscribed(channelName)) { subs = subs.filter(s => s.name !== channelName); btn.textContent = '登録'; btn.classList.remove('subscribed'); } else { subs.unshift({ name: channelName, thumb, isLive: false }); btn.textContent = '登録済み'; btn.classList.add('subscribed'); } saveSubscriptions(subs); renderSidebarSubscriptions(); }