Jelly-Clipper is an open-source web application that allows Jellyfin users to easily create, share, and manage video clips from their Jellyfin media library
Important
This is my first open source project, and it was very much a hacky "lets try to make it work somehow" thing. So absolutely feel free to contribute and fix all the stuff I did wrong :D
- Simple Clip Creation: Paste a URL and create clips with ease
- Seamless Jellyfin Integration: Works directly with your self-hosted Jellyfin server
- User Authentication: Clips are only accessible for other users of the Jellyfin instance
- Easy Sharing: Generate shareable links for your favorite moments
- User-Friendly(-ish) Interface: Intuitive design inspired by YouTube and Twitch clip functionality
This tool takes a very simple approach:
- Jelly-Clipper checks if it can find the original file from jellyfin locally at the same path
- If it can and if the browser can play it, no download will happen
- If not Jelly-Clipper downloads the original file (potentially transcoded) from jellyfin
- The user can create their clip
- The clip will be saved indefinitely in their profile and is accessible for other members of the jellyfin instance
- The downloaded original files get cleaned up regularly, if they're older than 7 (by default) days, to save storage
Jelly-Clipper is easily hostable with docker compose:
services:
jelly-clipper:
image: ghcr.io/arnolicious/jelly-clipper:latest
container_name: jelly-clipper
ports:
- 3000:3000
volumes:
# Path to the db directory, in which the sqlite db file will live
- <MY_DB_PATH>:/app/db
# Path to the videos directory.
# This will store all the clips permanently and the original files temporarily,
# so it might get a lil big
- <MY_VIDEOS_PATH>:/app/assets/videos
# If jelly-clipper runs on the same server as jellyfin
# you can mount the jellyfin media folder into jelly-clipper in the same exact same way it is mounted in jellyfin
# This allows jelly-clipper to directly access the media, instead of needing to download it
# - /my-media:/media <-- The mounted path must match exactly with the path in jellyfin
restart: unless-stopped
environment:
# Set log level: debug, info, warn, error
# - LOG_LEVEL=warn
# Set own custom cron expression for cleanup schedule (default: "30 2 * * *" - every day at 2:30 AM)
# - CLEANUP_CRON=30 2 * * *
# Set max age for original media to be cleaned up in days (default: 7 days)
# - CLEANUP_MAX_AGE_DAYS=7
# Full URL with Protocol and Port, where the application will live
- JELLY_CLIPPER_ORIGIN=http://localhost:3000
# with a reverse proxy it could be something like:
# - JELLY_CLIPPER_ORIGIN=https://clip.jellyfin.mydomain.test
# Timezone to have the cleanup cron job working as expected
- TZ=Europe/Berlin- SvelteKits
- Svelte 5
- TypeScript
- Bun
- Drizzle ORM
- Effect-TS
- Node.js v20
- Bun
- Jellyfin server for local development
-
Clone the repository:
git clone https://github.com/arnolicious/jelly-clipper.git cd jelly-clipper -
Install dependencies:
bun install
-
Run the development server:
bun dev
Contributions are welcome! Please check out our Contribution Guidelines.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Basic Prototype
- Implement sound (lol)
- Download Progress Indicator
- Clipping UI
- Create browser extension
- Improve mobile responsiveness
Distributed under the MIT License. See LICENSE for more information.
Disclaimer: This project is not officially affiliated with Jellyfin. It is a community-driven project created to enhance the Jellyfin experience.


