diff --git a/server.js b/server.js
index 42d34eb..b78bcb5 100644
--- a/server.js
+++ b/server.js
@@ -1,19 +1,48 @@
const express = require('express');
+const fs = require('fs');
const path = require('path');
const app = express();
const PORT = 3000;
-// Middleware для обслуживания статических файлов из папки "src" и корня приложения
-app.use('/src', express.static(path.join(__dirname, 'src')));
+// Путь к видеофайлу
+const videoPath = path.join(__dirname, 'movie.mp4'); // Замените 'movie.mp4' на ваш фильм
+const serverStartTime = Date.now(); // Время запуска сервера
+
+// Маршрут для главной страницы
app.use('/', express.static(path.join(__dirname, '')));
-// Главная страница
-app.get('/', (req, res) => {
- res.sendFile(path.join(__dirname, 'index.html'));
+// Маршрут для видео
+app.get('/video', (req, res) => {
+ const range = req.headers.range;
+ if (!range) {
+ return res.status(400).send('Requires Range header');
+ }
+
+ const videoSize = fs.statSync(videoPath).size;
+ const CHUNK_SIZE = 10 ** 6; // 1MB
+ const start = Number(range.replace(/\D/g, ''));
+ const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
+
+ const videoStream = fs.createReadStream(videoPath, { start, end });
+
+ res.writeHead(206, {
+ 'Content-Range': `bytes ${start}-${end}/${videoSize}`,
+ 'Accept-Ranges': 'bytes',
+ 'Content-Length': end - start + 1,
+ 'Content-Type': 'video/mp4',
+ });
+
+ videoStream.pipe(res);
+});
+
+// API для получения текущего времени воспроизведения
+app.get('/current-time', (req, res) => {
+ const elapsedTime = (Date.now() - serverStartTime) / 1000; // Время с момента запуска сервера в секундах
+ res.json({ currentTime: elapsedTime });
});
// Запуск сервера
app.listen(PORT, '0.0.0.0', () => {
- console.log(`Server is running on http://0.0.0.0:${PORT}`);
+ console.log(`Server is running on http://localhost:${PORT}`);
});
diff --git a/src/main.js b/src/main.js
index 22ed758..40a3ca9 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,84 +1,110 @@
-document.addEventListener('DOMContentLoaded', () => {
- const video = document.getElementById('video');
- const playPauseBtn = document.getElementById('playPauseBtn');
- const muteBtn = document.getElementById('muteBtn');
- const fullscreenBtn = document.getElementById('fullscreenBtn');
- const progressBar = document.querySelector('.progress-bar');
- const volumeSlider = document.querySelector('.volume-slider');
- const videoContainer = document.querySelector('.video-frame');
-
- // Play/Pause
- function togglePlay() {
- if (video.paused) {
- video.play();
- playPauseBtn.innerHTML = '';
- } else {
- video.pause();
- playPauseBtn.innerHTML = '';
+document.addEventListener('DOMContentLoaded', async () => {
+ const video = document.getElementById('video');
+ const playPauseBtn = document.getElementById('playPauseBtn');
+ const muteBtn = document.getElementById('muteBtn');
+ const fullscreenBtn = document.getElementById('fullscreenBtn');
+ const progressBar = document.querySelector('.progress-bar');
+ const volumeSlider = document.querySelector('.volume-slider');
+ const videoContainer = document.querySelector('.video-frame');
+
+ // Получение текущего времени воспроизведения с сервера
+ async function fetchCurrentTime() {
+ try {
+ const response = await fetch('/current-time');
+ if (!response.ok) {
+ throw new Error('Failed to fetch current time');
}
+ const data = await response.json();
+ return data.currentTime; // Сервер возвращает время в секундах
+ } catch (error) {
+ console.error('Error fetching current time:', error);
+ return 0; // Если ошибка, начать воспроизведение с начала
}
-
- // Update progress bar
- function updateProgress() {
- const progress = (video.currentTime / video.duration) * 100;
- progressBar.value = progress;
+ }
+
+ // Синхронизация времени видео с сервером
+ async function syncVideo() {
+ const currentTime = await fetchCurrentTime(); // Получаем время от сервера
+ video.currentTime = currentTime; // Устанавливаем текущее время видео
+ }
+
+ // Событие, когда метаданные видео загружены
+ video.addEventListener('loadedmetadata', async () => {
+ await syncVideo(); // Синхронизация видео с сервера
+ video.play(); // Запускаем видео
+ });
+
+ // Play/Pause
+ function togglePlay() {
+ if (video.paused) {
+ video.play();
+ playPauseBtn.innerHTML = '';
+ } else {
+ video.pause();
+ playPauseBtn.innerHTML = '';
}
-
- // Set video time based on progress bar
- function setVideoProgress() {
- video.currentTime = (progressBar.value * video.duration) / 100;
+ }
+
+ // Обновление прогресса
+ function updateProgress() {
+ const progress = (video.currentTime / video.duration) * 100;
+ progressBar.value = progress;
+ }
+
+ // Установка времени видео через прогресс-бар
+ function setVideoProgress() {
+ video.currentTime = (progressBar.value * video.duration) / 100;
+ }
+
+ // Громкость
+ function updateVolume() {
+ video.volume = volumeSlider.value;
+ updateVolumeIcon();
+ }
+
+ function toggleMute() {
+ video.muted = !video.muted;
+ updateVolumeIcon();
+ }
+
+ function updateVolumeIcon() {
+ const icon = muteBtn.querySelector('i');
+ if (video.muted || video.volume === 0) {
+ icon.className = 'fas fa-volume-mute';
+ volumeSlider.value = 0;
+ } else {
+ icon.className = 'fas fa-volume-up';
+ volumeSlider.value = video.volume;
}
-
- // Volume controls
- function updateVolume() {
- video.volume = volumeSlider.value;
- updateVolumeIcon();
+ }
+
+ // Fullscreen
+ function toggleFullscreen() {
+ if (!document.fullscreenElement) {
+ videoContainer.requestFullscreen();
+ fullscreenBtn.innerHTML = '';
+ } else {
+ document.exitFullscreen();
+ fullscreenBtn.innerHTML = '';
}
-
- function toggleMute() {
- video.muted = !video.muted;
- updateVolumeIcon();
+ }
+
+ // Слушатели событий
+ playPauseBtn.addEventListener('click', togglePlay);
+ video.addEventListener('click', togglePlay);
+ video.addEventListener('timeupdate', updateProgress);
+ progressBar.addEventListener('change', setVideoProgress);
+ muteBtn.addEventListener('click', toggleMute);
+ volumeSlider.addEventListener('input', updateVolume);
+ fullscreenBtn.addEventListener('click', toggleFullscreen);
+
+ // Поддержка клавиш на клавиатуре
+ document.addEventListener('keydown', (e) => {
+ if (e.code === 'Space') {
+ e.preventDefault();
+ togglePlay();
}
-
- function updateVolumeIcon() {
- const icon = muteBtn.querySelector('i');
- if (video.muted || video.volume === 0) {
- icon.className = 'fas fa-volume-mute';
- volumeSlider.value = 0;
- } else {
- icon.className = 'fas fa-volume-up';
- volumeSlider.value = video.volume;
- }
- }
-
- // Fullscreen
- function toggleFullscreen() {
- if (!document.fullscreenElement) {
- videoContainer.requestFullscreen();
- fullscreenBtn.innerHTML = '';
- } else {
- document.exitFullscreen();
- fullscreenBtn.innerHTML = '';
- }
- }
-
- // Event listeners
- playPauseBtn.addEventListener('click', togglePlay);
- video.addEventListener('click', togglePlay);
- video.addEventListener('timeupdate', updateProgress);
- progressBar.addEventListener('change', setVideoProgress);
- muteBtn.addEventListener('click', toggleMute);
- volumeSlider.addEventListener('input', updateVolume);
- fullscreenBtn.addEventListener('click', toggleFullscreen);
-
- // Keyboard controls
- document.addEventListener('keydown', (e) => {
- if (e.code === 'Space') {
- e.preventDefault();
- togglePlay();
- }
- });
-
- // Log ready state
- console.log('Video player initialized');
- });
\ No newline at end of file
+ });
+
+ console.log('Video player initialized and synced with the server.');
+});