Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dltmtt committed Aug 24, 2024
0 parents commit b9fc327
Show file tree
Hide file tree
Showing 18 changed files with 1,833 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
node_modules
.vercel
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Player for local videos

This video player is a PWA that allows you to watch local videos in your browser. It supports the following features:

- Light/dark theme (following system preferences)
- Continue watching from where you left off[^1]
- [Keyboard shortcuts](#keyboard-shortcuts)
- Global Media Controls integration
- Register as a handler for video files

[^1]: The video state is saved in the browser's local storage. If you clear your browser's data, the state will be lost. Saved state will be deleted upon video completion or for videos last played more than 30 days before.

## Screenshots

![Selection screen (light)](/images/screenshots/selection_screen_light.png)
![Selection screen (dark)](/images/screenshots/selection_screen_dark.png)
![Video screen (light)](/images/screenshots/video_screen_light.png)
![Video screen (dark)](/images/screenshots/video_screen_dark.png)

## Usage

To open a video, drag and drop it onto the app or click on the `Choose file` button.
If another video is opened, its state will be saved and the dragged video will replace the current one.

Alternatively, install the PWA, right click on the video you want to open, select `Open With` and choose this app.
You can also register this app as the default handler for video files by right clicking on a video file, selecting `Get Info`, scrolling down to `Open with`, selecting this app and clicking on `Change All...`.

> Note: In order for Picture-in-Picture (PiP) to work, Chrome must be opened (launching only this PWA won't work). I guess it's a bug in Chrome..
### Keyboard shortcuts

The following keyboard shortcuts are supported:

| Key | Action |
| :----------------------------------------------------: | --------------------- |
| <kbd>Space</kbd><br><kbd>K</kbd> | Toggle play/pause |
| <kbd>S</kbd> | Slow down by 0.1x |
| <kbd>D</kbd> | Speed up by 0.1x |
| <kbd>Z</kbd><br><kbd>&larr;</kbd><br><kbd>&darr;</kbd> | Rewind 10 seconds |
| <kbd>X</kbd><br><kbd>&rarr;</kbd><br><kbd>&uarr;</kbd> | Forward 10 seconds |
| <kbd>R</kbd> | Reset default speed |
| <kbd>T</kbd> | Toggle time/remaining |
| <kbd>A</kbd> | Set speed to 1.8x |
| <kbd>C</kbd> | Toggle video zoom |
| <kbd>P</kbd> | Toggle PiP |
| <kbd>F</kbd><br><kbd>Enter</kbd> | Toggle fullscreen |
66 changes: 66 additions & 0 deletions app.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"categories": ["productivity"],
"description": "Player for local videos with keyboard shortcuts.",
"display": "standalone",
"file_handlers": [
{
"accept": {
"video/3gpp": [".3gp"],
"video/3gpp2": [".3g2"],
"video/avi": [".avi"],
"video/mp2t": [".ts"],
"video/mp4": [".mp4"],
"video/mpeg": [".mpeg"],
"video/ogg": [".ogv"],
"video/webm": [".webm"]
},
"action": "/?utm_source=pwa"
}
],
"icons": [
{
"sizes": "any",
"src": "icons/icon.svg",
"type": "image/svg+xml",
"purpose": "any maskable"
}
],
"id": "/?utm_source=pwa",
"name": "Video player",
"orientation": "landscape",
"screenshots": [
{
"form_factor": "wide",
"label": "Selection screen (light)",
"platform": "macos",
"sizes": "2316x1780",
"src": "images/screenshots/selection_screen_light.png",
"type": "image/png"
},
{
"form_factor": "wide",
"label": "Selection screen (dark)",
"platform": "macos",
"sizes": "2316x1780",
"src": "images/screenshots/selection_screen_dark.png",
"type": "image/png"
},
{
"form_factor": "wide",
"label": "Video screen (light)",
"platform": "macos",
"sizes": "2316x1780",
"src": "images/screenshots/video_screen_light.png",
"type": "image/png"
},
{
"form_factor": "wide",
"label": "Video screen (dark)",
"platform": "macos",
"sizes": "2316x1780",
"src": "images/screenshots/video_screen_dark.png",
"type": "image/png"
}
],
"start_url": "/?utm_source=pwa"
}
Binary file added icons/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions icons/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshots/selection_screen_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshots/selection_screen_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshots/video_screen_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshots/video_screen_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 120 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<!doctype html>
<html lang="en">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta
name="description"
content="Player for local videos with keyboard shortcuts."
/>
<meta name="color-scheme" content="light dark" />

<title>Player for local videos</title>

<link rel="icon" href="icons/icon.svg" type="image/svg+xml" sizes="any" />
<link
rel="alternate icon"
href="icons/icon-192.png"
type="image/png"
sizes="192x192"
/>
<link
rel="apple-touch-icon"
href="icons/icon-192.png"
type="image/png"
sizes="192x192"
/>
<link rel="stylesheet" href="styles/main.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:wght,FILL@275,0..1&family=JetBrains+Mono"
rel="stylesheet"
/>
<link rel="manifest" href="app.webmanifest" />

<script src="scripts/script.js" defer></script>

<div class="droppable" id="drag-panel">
<span id="message">Drag and drop a video</span>
<button type="button" id="file-picker">Choose file</button>
</div>
<div id="drop-overlay" hidden></div>

<div class="droppable" id="player" hidden>
<video id="video"></video>

<div id="controls" aria-controls="video">
<input
type="range"
aria-label="Video bar"
value="0"
step="any"
tabindex="-1"
id="video-bar"
/>

<button
type="button"
aria-label="Toggle play/pause"
class="material-symbols-rounded"
id="play-btn"
>
play_arrow
</button>
<button
type="button"
aria-label="Rewind 10 seconds"
class="material-symbols-rounded"
id="replay-btn"
>
replay_10
</button>
<button
type="button"
aria-label="Forward 10 seconds"
class="material-symbols-rounded"
id="forward-btn"
>
forward_10
</button>

<button
type="button"
aria-label="Toggle time elapsed/remaining"
id="time-indicator-toggle"
>
<time role="timer" id="time-indicator" data-state="elapsed">00:00</time>
<time role="timer" id="duration"></time>
</button>
<div aria-label="Video name" id="file-name-container">
<span id="file-name"></span>
</div>

<input
type="number"
aria-label="Speed controls"
value="1.00"
min="0.1"
max="16"
step="0.1"
id="speed-controls"
/>
<button
type="button"
aria-label="Toggle zoom"
class="material-symbols-rounded"
id="zoom-btn"
>
zoom_out_map
</button>
<button
type="button"
aria-label="Toggle fullscreen"
class="material-symbols-rounded"
id="fullscreen-btn"
>
fullscreen
</button>
</div>
</div>
</html>
28 changes: 28 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"devDependencies": {
"prettier": "3.3.3"
}
}
Loading

0 comments on commit b9fc327

Please sign in to comment.