Skip to content

keiver/tomotv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

213 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tomo TV - Jellyfin Client for Apple TV

License Platform Tests Download on the App Store

A simple and usable Jellyfin client for Apple TV with seamless multi-audio track switching and advanced subtitle support.

TomoTV with open movies folder

Folder exploration, browse by seasons
Folder exploration
Multi-audio track switching
Multi-audio track switching
Subtitle support
Subtitle support
Up next overlay
Up next overlay
Native Search
Native Search
Help page
Help page

Why TomoTV?

Built from the ground up for Apple TV with a focus on seamless playback. Switch audio tracks mid-video without restarting playback, thanks to custom HLS manifest generation. Codec compatibility is handled automatically so you can focus on watching, not troubleshooting.

Features

  • Multi-Audio Switching — Change audio tracks mid-playback without restarting. Uses a custom Swift module to generate multivariant HLS manifests.
  • Subtitle Support — External (.srt) and embedded tracks with native tvOS picker.
  • Smart Codec Handling — Direct plays H.264/HEVC; auto-transcodes everything else.
  • Native tvOS Search — SwiftUI-powered with proper focus navigation.
  • Demo Mode — Try instantly with Jellyfin's demo server.
  • Playlist Support — Browse and play from your Jellyfin playlists.
  • Secure Storage — device Keychain (secure local storage).
  • Continue Watching — Resume videos from last position.

Installation

Prerequisites

  • Jellyfin Server 10.8+ with transcoding enabled
  • Node.js 18+ and npm
  • Xcode 15+
  • Apple TV or tvOS simulator
  • react-native-tvos configured project

Setup

# Clone the repository
git clone https://github.com/keiver/tomotv.git
cd tomotv

# Install dependencies
npm install

# Configure environment (development only)
cp .env.example .env.local
# Edit .env.local with your Jellyfin server details

# Prebuild for tvOS
npm run prebuild:tv

# Run on tvOS simulator
npm run ios

# Or build for Apple TV device
npx expo run:ios

Jellyfin Server Configuration

  • Quick Connect support
  • Username/password authentication
Quick Connect settings
Quick Connect
Username and password authentication
Username/Password

Video Quality Presets

Tomo TV supports 480p, 540p, 720p, 1080p, and 4K transcoding quality presets. Configure via Settings → Video Quality.

Network Requirements

  • All networks: HTTP and HTTPS connections allowed via NSAllowsArbitraryLoads
  • Remote servers: HTTPS strongly recommended; HTTP exposes credentials in plaintext

Development

npm start            # Start dev server
npm run ios          # Build and run
npm test             # Run tests
npm run lint         # Lint and auto-fix
npm run prebuild:tv  # Rebuild native projects (deletes ios/ folder)

Native code: Always edit files in the native/ folder — the ios/ folder is regenerated by prebuild and any direct edits will be lost.

Architecture

Screens live in app/ using Expo Router's file-based routing with native tvOS tabs. Global state is managed through singleton managers wrapped in React Contexts. Video playback follows a state machine (IDLE → FETCHING → CREATING_STREAM → READY → PLAYING) that handles codec detection, automatic transcoding fallback, and multi-audio track switching via a custom Swift HLS manifest generator in native/ios/.

Tech Stack

  • React Native TVOS — TV-optimized fork of React Native
  • Expo Router 6.0 — File-based routing with native tabs
  • react-native-video 6.19 — Native video playback (AVPlayer)
  • React Native Reanimated 4.1 — GPU-accelerated animations
  • TypeScript 5.9 — Strict type checking
  • Jest 29.7 — Unit and integration tests
  • expo-tvos-search — Native tvOS search UI using SwiftUI

A Note on AI

I use Claude as a development tool for drafting code and documentation. Architecture and decisions are mine, blame me for any shady code.

Contributing

Contributions are welcome! This is a real, production app used by real users.

Development Workflow

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/cool-feature)
  3. Make your changes following the existing code patterns
  4. Add tests for new functionality
  5. Run npm test to ensure all tests pass
  6. Run npm run lint to fix any linting issues
  7. Commit with clear, descriptive messages
  8. Push to your fork and submit a PR

Code Standards

  • TypeScript: Strict mode, no any types without justification
  • Testing: Add tests for new features, maintain >50% coverage
  • Error handling: Try-catch around async operations with structured logging
  • React patterns: Proper cleanup (useEffect, unsubscribe functions)
  • Comments: Only where logic isn't self-evident
  • Performance: No scale animations on grid items; use border-only focus feedback

Known Limitations

  • Codec support: Only H.264 and HEVC direct play; all others require transcoding
  • Platform: tvOS only (Android not supported for now)
  • Network: HTTP allowed on all networks; HTTPS recommended for remote servers (HTTP exposes credentials)
  • Server: Jellyfin only (not compatible with Plex, Emby, etc.)

License

MIT License - see LICENSE file for details.

Acknowledgments

  • Jellyfin Team for the excellent open-source media server
  • Expo Team for React Native TVOS support
  • Blender Foundation for open movie test files (Sintel, Elephants Dream...)
  • IETF for Matroska test files used in development

Links


Built with ❤️ for the Jellyfin community.

About

Jellyfin media client for Apple TV

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors