Skip to content

Commit 092bfbd

Browse files
Add initial HTML structure for video player
1 parent 71a444e commit 092bfbd

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed

index.html

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
<!DOCTYPE html>
2+
<!--
3+
Ultra Pro Local Video Player
4+
Developer: Vishal Kumar Basson
5+
License: GNU General Public License v3.0
6+
Open Source Project
7+
-->
8+
<html lang="en">
9+
<head>
10+
<meta charset="UTF-8" />
11+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
12+
<title>Ultra Pro Local Video Player</title>
13+
<link href="https://vjs.zencdn.net/8.10.0/video-js.css" rel="stylesheet" />
14+
<meta name="theme-color" content="#0f172a" />
15+
16+
<style>
17+
* { box-sizing: border-box; margin: 0; padding: 0; }
18+
19+
body {
20+
font-family: 'Segoe UI', sans-serif;
21+
background: linear-gradient(135deg,#0f172a,#1e293b,#111827);
22+
color: white;
23+
min-height: 100vh;
24+
display: flex;
25+
flex-direction: column;
26+
align-items: center;
27+
}
28+
29+
header {
30+
padding: 25px;
31+
font-size: 28px;
32+
font-weight: bold;
33+
background: linear-gradient(90deg,#38bdf8,#818cf8);
34+
-webkit-background-clip: text;
35+
-webkit-text-fill-color: transparent;
36+
letter-spacing: 1px;
37+
text-align: center;
38+
}
39+
40+
.upload-area {
41+
border: 2px dashed #38bdf8;
42+
padding: 50px;
43+
margin: 20px;
44+
text-align: center;
45+
border-radius: 20px;
46+
cursor: pointer;
47+
transition: 0.4s;
48+
width: 90%;
49+
max-width: 900px;
50+
backdrop-filter: blur(20px);
51+
background: rgba(255,255,255,0.05);
52+
}
53+
54+
.upload-area:hover {
55+
background: rgba(56,189,248,0.15);
56+
transform: scale(1.03);
57+
}
58+
59+
.player-container {
60+
width: 95%;
61+
max-width: 1100px;
62+
border-radius: 20px;
63+
overflow: hidden;
64+
box-shadow: 0 0 40px rgba(0,0,0,0.7);
65+
margin-top: 20px;
66+
}
67+
68+
.controls-extra {
69+
margin: 20px;
70+
display: flex;
71+
flex-wrap: wrap;
72+
justify-content: center;
73+
gap: 10px;
74+
}
75+
76+
button, input {
77+
padding: 10px 14px;
78+
border-radius: 12px;
79+
border: none;
80+
font-size: 14px;
81+
}
82+
83+
button {
84+
background: linear-gradient(90deg,#38bdf8,#818cf8);
85+
color: white;
86+
cursor: pointer;
87+
transition: 0.3s;
88+
}
89+
90+
button:hover {
91+
transform: translateY(-3px);
92+
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
93+
}
94+
95+
.info-section {
96+
width: 90%;
97+
max-width: 1000px;
98+
background: rgba(255,255,255,0.05);
99+
margin: 30px;
100+
padding: 25px;
101+
border-radius: 15px;
102+
line-height: 1.7;
103+
}
104+
105+
.info-section h2 {
106+
margin-bottom: 15px;
107+
color: #38bdf8;
108+
}
109+
110+
footer {
111+
margin-top: auto;
112+
padding: 20px;
113+
text-align: center;
114+
font-size: 14px;
115+
opacity: 0.8;
116+
}
117+
</style>
118+
</head>
119+
<body>
120+
121+
<header>🎬 Ultra Pro Local Video Player</header>
122+
123+
<div class="upload-area" id="dropZone">
124+
Drag & Drop Video Here or Click to Upload
125+
<input type="file" id="videoInput" accept="video/*" hidden />
126+
</div>
127+
128+
<div class="player-container">
129+
<video id="myVideo" class="video-js vjs-default-skin" controls preload="auto"></video>
130+
</div>
131+
132+
<div class="controls-extra">
133+
<button onclick="changeSpeed(0.5)">0.5x</button>
134+
<button onclick="changeSpeed(1)">1x</button>
135+
<button onclick="changeSpeed(1.5)">1.5x</button>
136+
<button onclick="changeSpeed(2)">2x</button>
137+
<button onclick="skip(-10)">⏪ 10s</button>
138+
<button onclick="skip(10)">10s ⏩</button>
139+
<button onclick="togglePiP()">📺 PiP</button>
140+
<button onclick="takeScreenshot()">📸 Screenshot</button>
141+
<input type="file" id="subtitleInput" accept=".vtt,.srt" />
142+
</div>
143+
144+
<div class="info-section">
145+
<h2>📘 How To Use</h2>
146+
<p>1. Click or drag & drop your video file into the upload area.</p>
147+
<p>2. Use playback controls or keyboard shortcuts (Space = Play/Pause, ← → = Seek).</p>
148+
<p>3. Upload subtitle file (.srt or .vtt) using subtitle button.</p>
149+
<p>4. Use speed buttons to adjust playback speed.</p>
150+
<p>5. Screenshot button captures current frame.</p>
151+
<p>6. No data is uploaded. Everything runs locally in your browser.</p>
152+
</div>
153+
154+
<footer>
155+
Developed by Vishal Kumar Basson | Open Source under GNU GPL v3.0 License
156+
</footer>
157+
158+
<script src="https://vjs.zencdn.net/8.10.0/video.min.js"></script>
159+
<script>
160+
const videoElement=document.getElementById("myVideo");
161+
const videoInput=document.getElementById("videoInput");
162+
const dropZone=document.getElementById("dropZone");
163+
const subtitleInput=document.getElementById("subtitleInput");
164+
const player=videojs(videoElement);
165+
166+
dropZone.addEventListener("click",()=>videoInput.click());
167+
dropZone.addEventListener("dragover",e=>{e.preventDefault();dropZone.style.background="rgba(56,189,248,0.25)";});
168+
dropZone.addEventListener("dragleave",()=>dropZone.style.background="rgba(255,255,255,0.05)" );
169+
dropZone.addEventListener("drop",e=>{e.preventDefault();loadVideo(e.dataTransfer.files[0]);});
170+
videoInput.addEventListener("change",e=>loadVideo(e.target.files[0]));
171+
172+
function loadVideo(file){
173+
if(!file)return;
174+
const url=URL.createObjectURL(file);
175+
player.src({type:file.type,src:url});
176+
player.play();
177+
}
178+
179+
function changeSpeed(speed){player.playbackRate(speed);}
180+
function skip(sec){player.currentTime(player.currentTime()+sec);}
181+
async function togglePiP(){
182+
if(document.pictureInPictureElement){await document.exitPictureInPicture();}
183+
else{await videoElement.requestPictureInPicture();}
184+
}
185+
186+
function takeScreenshot(){
187+
const canvas=document.createElement("canvas");
188+
canvas.width=videoElement.videoWidth;
189+
canvas.height=videoElement.videoHeight;
190+
canvas.getContext("2d").drawImage(videoElement,0,0);
191+
const link=document.createElement("a");
192+
link.download="screenshot.png";
193+
link.href=canvas.toDataURL();
194+
link.click();
195+
}
196+
197+
function parseSRT(data){
198+
return data.replace(/(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})/g,
199+
(match,p1,start,end)=>`${p1}\n${start.replace(',','.') } --> ${end.replace(',','.')}`);
200+
}
201+
202+
subtitleInput.addEventListener("change",function(){
203+
const file=this.files[0]; if(!file)return;
204+
const reader=new FileReader();
205+
reader.onload=function(){
206+
let text=reader.result;
207+
if(file.name.endsWith('.srt')) text=parseSRT(text);
208+
const blob=new Blob([text],{type:'text/vtt'});
209+
const url=URL.createObjectURL(blob);
210+
player.addRemoteTextTrack({kind:'subtitles',src:url,srclang:'en',label:'Subtitles',default:true},false);
211+
};
212+
reader.readAsText(file);
213+
});
214+
215+
document.addEventListener("keydown",e=>{
216+
if(e.code==="Space"){e.preventDefault();player.paused()?player.play():player.pause();}
217+
if(e.code==="ArrowRight")skip(10);
218+
if(e.code==="ArrowLeft")skip(-10);
219+
});
220+
</script>
221+
222+
</body>
223+
</html>

0 commit comments

Comments
 (0)