diff --git a/README.md b/README.md index 23b3524..82f1bba 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,15 @@ A Jellyfin plugin for accessing SRF Play (Swiss Radio and Television) video-on-d ## Features -- Access to SRF Play VOD content (video-on-demand only, no DRM-protected content) +- Access to SRF Play VOD content (video-on-demand, no DRM-protected content) +- **Live Sports Streaming** - Watch scheduled sports events (skiing, Formula 1, football, tennis, etc.) - Support for all Swiss broadcasting units (SRF, RTS, RSI, RTR, SWI) - Automatic content expiration handling - Latest and trending content discovery - Quality selection (Auto, SD, HD) -- HLS streaming support +- HLS streaming support with Akamai token authentication - Proxy support for routing traffic through alternate gateways +- Smart caching with reduced TTL for upcoming livestreams ## Project Status @@ -41,16 +43,20 @@ A Jellyfin plugin for accessing SRF Play (Swiss Radio and Television) video-on-d - Quality-based filtering - DRM content filtering - Content expiration checking + - Akamai token authentication + - Upcoming livestream detection - ✅ Metadata Cache Service - Efficient caching with configurable duration - Thread-safe with ReaderWriterLockSlim - IDisposable implementation + - Dynamic TTL for scheduled livestreams - ✅ Content Expiration Service - Automatic expiration checking - Library cleanup of expired content - Statistics and monitoring - ✅ Content Refresh Service - Latest and trending content discovery + - Scheduled sports livestreams - Automatic cache population - Recommendations system @@ -73,18 +79,28 @@ A Jellyfin plugin for accessing SRF Play (Swiss Radio and Television) video-on-d - ✅ Jellyfin provider interfaces implementation - ✅ Plugin initialization and configuration +#### Phase 8: Live Sports Streaming +- ✅ Play v3 API integration for scheduled livestreams +- ✅ Sports events folder in channel +- ✅ Upcoming event detection and display +- ✅ Akamai token authentication for streams +- ✅ Dynamic cache refresh for live events +- ✅ Event scheduling with ValidFrom/ValidTo handling +- ✅ Automatic stream URL resolution when events go live + ### ✅ Build Status **Successfully compiling!** All code analysis warnings resolved. ### 🧪 Testing Status - [ ] Unit tests - [ ] Integration testing with Jellyfin instance -- [ ] End-to-end playback testing +- [ ] End-to-end playback testing for VOD content +- [ ] Live sports streaming validation ### 📝 Next Steps -1. Test the plugin with a live Jellyfin instance -2. Verify content discovery and playback -3. Test expiration handling +1. Test live sports streaming when events are scheduled +2. Verify Akamai token authentication +3. Test with different business units (RTS, RSI, RTR) 4. Add unit tests 5. Performance optimization if needed @@ -94,18 +110,29 @@ A Jellyfin plugin for accessing SRF Play (Swiss Radio and Television) video-on-d ### Key Endpoints -- `GET /mediaComposition/byUrn/{urn}.json` - Get video metadata and playable URLs +**Integration Layer API v2.0:** +- `GET /mediaComposition/byUrn/{urn}` - Get video metadata and playable URLs - `GET /video/{businessUnit}/latest` - Get latest videos - `GET /video/{businessUnit}/trending` - Get trending videos -- `GET /showList/{businessUnit}` - Get all shows (to be implemented) -- `GET /episodeList/{businessUnit}/{showId}` - Get episodes for a show (to be implemented) + +**Play v3 API:** +- `GET /play/v3/api/{bu}/production/livestreams?eventType=SPORT` - Get scheduled sports livestreams +- `GET /play/v3/api/{bu}/production/shows/{id}` - Get show details +- `GET /play/v3/api/{bu}/production/videos-by-show-id?showId={id}` - Get episodes for a show + +**Akamai Token Service:** +- `GET /akahd/token?acl=/{path}/*` - Authenticate stream URLs for playback ### URN Format -- `urn:{bu}:video:{id}` - Video URN -- `urn:{bu}:video:livestream_{channel}` - Livestream URN (not supported due to Widevine DRM) +- `urn:{bu}:video:{id}` - Video URN (VOD content) +- `urn:{bu}:scheduled_livestream:video:{id}` - Scheduled sports livestream URN (supported) +- `urn:{bu}:video:livestream_{channel}` - Live TV channel URN (not supported due to Widevine DRM) -Example: `urn:srf:video:livestream_SRF1` +Examples: +- `urn:srf:video:c4927fcf-4ab4-4bcf-be4e-00e4ee9e6d6b` (VOD) +- `urn:srf:scheduled_livestream:video:7b31c9a6-a96e-4c0e-bfc2-f0d6237f2233` (Sports event) +- `urn:srf:video:c4927fcf-e1a0-0001-7edd-1ef01d441651` (SRF 1 Live - DRM protected) ## Building the Plugin @@ -131,6 +158,10 @@ The compiled plugin will be in `bin/Debug/net8.0/` 2. Copy the compiled DLL to your Jellyfin plugins directory 3. Restart Jellyfin 4. Configure the plugin in Jellyfin Dashboard → Plugins → SRF Play +5. The SRF Play channel will appear in Jellyfin with three main folders: + - **Latest Videos** - Recently published content + - **Trending Videos** - Popular content + - **Live Sports & Events** - Scheduled sports livestreams (skiing, F1, football, etc.) ## Configuration @@ -168,16 +199,22 @@ Jellyfin.Plugin.SRFPlay/ │ │ ├── Chapter.cs │ │ ├── Resource.cs │ │ ├── Show.cs -│ │ └── Episode.cs +│ │ ├── Episode.cs +│ │ └── PlayV3/ # Play v3 API models +│ │ ├── PlayV3TvProgram.cs +│ │ └── PlayV3TvProgramGuideResponse.cs │ └── SRFApiClient.cs # HTTP client for SRF API +├── Channels/ +│ └── SRFPlayChannel.cs # Channel implementation ├── Configuration/ │ ├── PluginConfiguration.cs │ └── configPage.html ├── Services/ -│ ├── StreamUrlResolver.cs # HLS stream resolution +│ ├── StreamUrlResolver.cs # HLS stream resolution & authentication │ ├── MetadataCache.cs # Caching layer │ ├── ContentExpirationService.cs # Expiration management -│ └── ContentRefreshService.cs # Content discovery +│ ├── ContentRefreshService.cs # Content discovery +│ └── CategoryService.cs # Topic/category management ├── Providers/ │ ├── SRFSeriesProvider.cs # Series metadata │ ├── SRFEpisodeProvider.cs # Episode metadata @@ -192,21 +229,24 @@ Jellyfin.Plugin.SRFPlay/ ### Key Components -1. **API Client**: Handles all HTTP requests to SRF Integration Layer -2. **Stream Resolver**: Extracts and selects optimal HLS streams -3. **Configuration**: User-configurable settings via Jellyfin dashboard -4. **Metadata Cache**: Thread-safe caching with configurable expiration -5. **Content Providers**: Jellyfin integration for series, episodes, images, and media -6. **Scheduled Tasks**: Automatic content refresh and expiration management -7. **Service Layer**: Content discovery, expiration handling, and stream resolution +1. **API Client**: Handles all HTTP requests to SRF Integration Layer and Play v3 API +2. **Channel**: SRF Play channel with Latest, Trending, and Live Sports folders +3. **Stream Resolver**: Extracts and selects optimal HLS streams with Akamai authentication +4. **Configuration**: User-configurable settings via Jellyfin dashboard +5. **Metadata Cache**: Thread-safe caching with dynamic TTL for livestreams +6. **Content Providers**: Jellyfin integration for series, episodes, images, and media sources +7. **Scheduled Tasks**: Automatic content refresh and expiration management +8. **Service Layer**: Content discovery, expiration handling, stream resolution, and category management ## Important Notes ### Content Limitations -- **No DRM content**: Only non-DRM protected content is accessible (no Widevine) -- **No live TV channels**: Only VOD content and live streams without DRM +- **No DRM content**: Only non-DRM protected content is accessible (no Widevine/FairPlay) +- **No live TV channels**: Main channels (SRF 1, SRF zwei, SRF info) use DRM and are not supported +- **Sports livestreams supported**: Scheduled sports events (skiing, F1, football, etc.) work without DRM - **Content expiration**: SRF content has validity periods, plugin tracks and removes expired content +- **Upcoming events**: Sports events appear before they start but require channel refresh to play once live - **No subtitles**: Subtitle support not currently implemented ### Extensibility @@ -225,12 +265,15 @@ Currently focused on SRF but easily extensible. ### Current Status All core functionality is implemented and compiling successfully! The plugin includes: -- Complete API integration with SRF Play +- Complete API integration with SRF Play (Integration Layer v2.0 and Play v3) +- **Live sports streaming** with scheduled event detection +- Channel with Latest, Trending, and Live Sports folders - Metadata providers for series and episodes - Image fetching and caching -- HLS stream playback +- HLS stream playback with Akamai token authentication - Automatic content expiration handling - Scheduled tasks for content refresh +- Smart caching with dynamic TTL for upcoming livestreams ### Testing @@ -256,8 +299,13 @@ This plugin is in active development. Contributions welcome! See LICENSE file for details. +## Acknowledgments + +This plugin was developed with inspiration from the excellent [Kodi SRG SSR addon](https://github.com/goggle/script.module.srgssr) by [@goggle](https://github.com/goggle). The Kodi addon served as a fantastic reference for understanding the SRG SSR API structure, authentication mechanisms, and handling of scheduled livestreams. + ## References - [SRF Play](https://www.srf.ch/play) - [Jellyfin Plugin Documentation](https://jellyfin.org/docs/general/server/plugins/) - [SRG SSR Integration Layer API](https://il.srgssr.ch/) +- [Kodi SRG SSR Addon](https://github.com/goggle/script.module.srgssr) - Reference implementation