Update index.html
Browse files- index.html +67 -17
index.html
CHANGED
@@ -1615,6 +1615,7 @@ header.addEventListener('click', () => {
|
|
1615 |
</div>
|
1616 |
<div class="main-controls">
|
1617 |
<button class="control-button" id="play-pause-btn" disabled>▶</button>
|
|
|
1618 |
<div class="time-display" id="time-display">00:00.00 / 00:00.00</div>
|
1619 |
<div class="volume-control">
|
1620 |
<button class="volume-button" id="volume-btn" disabled>🔊</button>
|
@@ -1624,6 +1625,7 @@ header.addEventListener('click', () => {
|
|
1624 |
<span class="speed-value" id="speed-value">1.00x</span>
|
1625 |
<input type="range" class="speed-slider" id="speed-slider" min="0.01" max="5" step="0.01" value="1" disabled>
|
1626 |
</div>
|
|
|
1627 |
<button class="control-button fullscreen-button" id="fullscreen-btn" disabled>⛶</button>
|
1628 |
</div>
|
1629 |
</div>
|
@@ -1835,6 +1837,8 @@ header.addEventListener('click', () => {
|
|
1835 |
const tempoSpeedValue = document.getElementById('tempo-speed-value');
|
1836 |
const videoControls = document.querySelector('.video-controls');
|
1837 |
const applyTimeBtn = document.getElementById('apply-time-btn');
|
|
|
|
|
1838 |
|
1839 |
// 音声オブジェクトを作成
|
1840 |
const audioElements = {};
|
@@ -1903,8 +1907,46 @@ header.addEventListener('click', () => {
|
|
1903 |
pauseMedia();
|
1904 |
}
|
1905 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1906 |
|
1907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1908 |
if (isCheckingSync) return;
|
1909 |
isCheckingSync = true;
|
1910 |
if (syncCheckInterval) clearInterval(syncCheckInterval);
|
@@ -2111,22 +2153,28 @@ header.addEventListener('click', () => {
|
|
2111 |
|
2112 |
combineButton.disabled = false;
|
2113 |
|
2114 |
-
|
2115 |
-
|
2116 |
-
|
2117 |
-
|
2118 |
-
|
2119 |
-
|
2120 |
-
|
2121 |
-
|
2122 |
-
|
2123 |
-
|
2124 |
-
|
2125 |
-
|
2126 |
-
|
2127 |
-
|
2128 |
-
|
2129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2130 |
|
2131 |
|
2132 |
// 動画終了時に自動的にPiPを閉じる(次回再開のため)
|
@@ -2247,6 +2295,8 @@ header.addEventListener('click', () => {
|
|
2247 |
setEndTimeBtn.disabled = false;
|
2248 |
playbackSpeedSlider.disabled = false;
|
2249 |
applyTimeBtn.disabled = false;
|
|
|
|
|
2250 |
}
|
2251 |
|
2252 |
// プレビュー再生
|
|
|
1615 |
</div>
|
1616 |
<div class="main-controls">
|
1617 |
<button class="control-button" id="play-pause-btn" disabled>▶</button>
|
1618 |
+
<button class="control-button" id="reset-btn" disabled title="最初から再生">↺</button>
|
1619 |
<div class="time-display" id="time-display">00:00.00 / 00:00.00</div>
|
1620 |
<div class="volume-control">
|
1621 |
<button class="volume-button" id="volume-btn" disabled>🔊</button>
|
|
|
1625 |
<span class="speed-value" id="speed-value">1.00x</span>
|
1626 |
<input type="range" class="speed-slider" id="speed-slider" min="0.01" max="5" step="0.01" value="1" disabled>
|
1627 |
</div>
|
1628 |
+
<button class="control-button" id="pip-btn" disabled title="ピクチャーインピクチャー">⇲</button>
|
1629 |
<button class="control-button fullscreen-button" id="fullscreen-btn" disabled>⛶</button>
|
1630 |
</div>
|
1631 |
</div>
|
|
|
1837 |
const tempoSpeedValue = document.getElementById('tempo-speed-value');
|
1838 |
const videoControls = document.querySelector('.video-controls');
|
1839 |
const applyTimeBtn = document.getElementById('apply-time-btn');
|
1840 |
+
const pipBtn = document.getElementById('pip-btn');
|
1841 |
+
const resetBtn = document.getElementById('reset-btn');
|
1842 |
|
1843 |
// 音声オブジェクトを作成
|
1844 |
const audioElements = {};
|
|
|
1907 |
pauseMedia();
|
1908 |
}
|
1909 |
});
|
1910 |
+
function updatePipButton() {
|
1911 |
+
if (document.pictureInPictureElement) {
|
1912 |
+
pipBtn.textContent = '↸';
|
1913 |
+
pipBtn.title = 'ピクチャーインピクチャーを終了';
|
1914 |
+
} else {
|
1915 |
+
pipBtn.textContent = '⇲';
|
1916 |
+
pipBtn.title = 'ピクチャーインピクチャーで再生';
|
1917 |
+
}
|
1918 |
+
}
|
1919 |
+
|
1920 |
+
pipBtn.addEventListener('click', async () => {
|
1921 |
+
try {
|
1922 |
+
if (document.pictureInPictureElement) {
|
1923 |
+
await document.exitPictureInPicture();
|
1924 |
+
} else {
|
1925 |
+
await video.requestPictureInPicture();
|
1926 |
+
}
|
1927 |
+
updatePipButton();
|
1928 |
+
} catch (err) {
|
1929 |
+
console.error('PiP操作エラー:', err);
|
1930 |
+
}
|
1931 |
+
});
|
1932 |
+
video.addEventListener('enterpictureinpicture', updatePipButton);
|
1933 |
+
video.addEventListener('leavepictureinpicture', updatePipButton);
|
1934 |
|
1935 |
+
// リセットボタンクリック処理
|
1936 |
+
resetBtn.addEventListener('click', () => {
|
1937 |
+
const startTime = parseFloat(startTimeInput.value) || 0;
|
1938 |
+
seekMedia(startTime);
|
1939 |
+
if (isPlaying) {
|
1940 |
+
playMedia();
|
1941 |
+
}
|
1942 |
+
});
|
1943 |
+
|
1944 |
+
// 初期化時にPiPボタンの状態を設定
|
1945 |
+
updatePipButton();
|
1946 |
+
|
1947 |
+
|
1948 |
+
|
1949 |
+
function startSyncCheck() {
|
1950 |
if (isCheckingSync) return;
|
1951 |
isCheckingSync = true;
|
1952 |
if (syncCheckInterval) clearInterval(syncCheckInterval);
|
|
|
2153 |
|
2154 |
combineButton.disabled = false;
|
2155 |
|
2156 |
+
document.addEventListener('visibilitychange', async () => {
|
2157 |
+
if (document.hidden) {
|
2158 |
+
isInBackgroundTab = true;
|
2159 |
+
// 動画のみ停止
|
2160 |
+
video.pause();
|
2161 |
+
// 音声とメトロノームは継続
|
2162 |
+
if (combinedAudioElement && !combinedAudioElement.paused) {
|
2163 |
+
await combinedAudioElement.play();
|
2164 |
+
}
|
2165 |
+
if (tl.isActive()) {
|
2166 |
+
tl.play();
|
2167 |
+
}
|
2168 |
+
} else {
|
2169 |
+
isInBackgroundTab = false;
|
2170 |
+
if (combinedAudioElement && !combinedAudioElement.paused) {
|
2171 |
+
video.currentTime = combinedAudioElement.currentTime;
|
2172 |
+
if (isPlaying) {
|
2173 |
+
await video.play();
|
2174 |
+
}
|
2175 |
+
}
|
2176 |
+
}
|
2177 |
+
});
|
2178 |
|
2179 |
|
2180 |
// 動画終了時に自動的にPiPを閉じる(次回再開のため)
|
|
|
2295 |
setEndTimeBtn.disabled = false;
|
2296 |
playbackSpeedSlider.disabled = false;
|
2297 |
applyTimeBtn.disabled = false;
|
2298 |
+
resetBtn.disabled = false; // 追加
|
2299 |
+
pipBtn.disabled = false; // 追加
|
2300 |
}
|
2301 |
|
2302 |
// プレビュー再生
|