# M3U Playlist Format Documentation ## File Location `sample_playlist.m3u` - Example playlist showing XStream VOD format --- ## M3U Format Structure ### Header ``` #EXTM3U ``` - Required first line identifying the file as an M3U playlist ### Entry Format Each VOD item consists of two lines: **Line 1: Metadata (EXTINF)** ``` #EXTINF:-1 tvg-id="ID" tvg-name="NAME" tvg-logo="URL" group-title="CATEGORY",Display Title ``` **Line 2: Stream URL** ``` https://server.com/movie/username/password/12345.mp4 ``` --- ## Metadata Attributes ### tvg-id - **Purpose**: Unique identifier for the video - **Example**: `"movie001"` - **Maps to**: `VODItem.id` - **Used for**: Identifying specific content, tracking playback ### tvg-name - **Purpose**: Clean video title (without year/metadata) - **Example**: `"The Matrix"` - **Maps to**: `VODItem.name` (if no comma-separated name exists) - **Used for**: Display, search ### tvg-logo - **Purpose**: Poster/thumbnail image URL - **Example**: `"https://image.tmdb.org/t/p/w500/matrix.jpg"` - **Maps to**: `VODItem.iconURL` - **Used for**: Grid display, detail view ### group-title - **Purpose**: Category/genre classification - **Example**: `"Action Movies"`, `"Sci-Fi"`, `"Drama"` - **Maps to**: `VODItem.categoryID` - **Used for**: Category filtering, menu organization ### Display Title (after comma) - **Purpose**: Full display name with year/additional info - **Example**: `"The Matrix (1999)"` - **Maps to**: `VODItem.name` (preferred over tvg-name) - **Used for**: Primary display text --- ## Current Categories in Sample Based on the sample playlist, we have these categories: 1. **Action Movies** (3 items) - The Matrix, Inception, The Dark Knight 2. **Sci-Fi** (3 items) - Interstellar, Blade Runner 2049, Arrival 3. **Drama** (3 items) - The Shawshank Redemption, The Godfather, Forrest Gump 4. **Comedy** (3 items) - Superbad, The Hangover, Anchorman 5. **Horror** (3 items) - The Conjuring, Get Out, A Quiet Place 6. **Family & Kids** (3 items) - Toy Story, Finding Nemo, The Lion King 7. **Thriller** (2 items) - Parasite, Gone Girl **Total: 7 categories, 20 movies** --- ## How Data is Parsed ### M3UParser.swift Logic ```swift 1. Read line: #EXTINF:-1 tvg-id="movie001" tvg-name="The Matrix" tvg-logo="..." group-title="Action Movies",The Matrix (1999) 2. Extract attributes: - tvg-id → "movie001" - tvg-name → "The Matrix" - tvg-logo → "https://..." - group-title → "Action Movies" 3. Extract display name (after comma): - "The Matrix (1999)" 4. Read next line (stream URL): - "https://widen.velvetfort.com/movie/..." 5. Create VODItem: VODItem( id: "movie001", name: "The Matrix (1999)", // Preferred over tvg-name streamURL: "https://...", iconURL: "https://...", categoryID: "Action Movies" ) ``` --- ## Menu Organization Options ### Option 1: Category-Based Navigation (Current) **Main View**: Grid of all VOD items **Filter Bar**: Horizontal scrolling category buttons - All - Action Movies - Sci-Fi - Drama - Comedy - Horror - Family & Kids - Thriller **Pros**: - Simple, flat navigation - Easy to browse all content - Quick category filtering **Cons**: - Large libraries can be overwhelming - No hierarchy --- ### Option 2: Category Tabs **TabView with categories as tabs**: - Tab 1: All - Tab 2: Action Movies - Tab 3: Sci-Fi - Tab 4: Drama - etc. **Pros**: - Clear separation - Native tvOS navigation **Cons**: - Limited to ~5-7 tabs before UI becomes crowded - Not scalable for many categories --- ### Option 3: Hierarchical Menu **Main Menu**: - Browse All - Categories ▸ - Action Movies ▸ - Sci-Fi ▸ - Drama ▸ - etc. - Recently Added - Continue Watching **Pros**: - Scalable to many categories - Can add other browse methods - Professional feel **Cons**: - More navigation depth - Requires more views --- ### Option 4: Hybrid Approach (Recommended) **Main View**: VODLibraryView (current implementation) - Header with category filter (horizontal scroll) - Grid of filtered content - "All" shows everything **Additional Features**: - Search button - Sort options (A-Z, Recently Added, etc.) - Quick access to "Continue Watching" at top **Implementation**: ```swift VODLibraryView: - All content by default - Category pills at top (ScrollView horizontal) - When category selected, filter grid - Smooth animations between states ``` This is what is currently implemented. --- ## Data Structures ### Current Implementation ```swift // Individual item struct VODItem { let id: String // tvg-id let name: String // Display title (after comma) let streamURL: String // Stream URL let iconURL: String? // tvg-logo let categoryID: String? // group-title // Additional fields available for future use: let description: String? let duration: String? let rating: String? let added: String? } // Category struct Category { let id: String // Same as name for now let name: String // group-title value } // Container struct Playlist { let vodItems: [VODItem] let categories: [Category] let lastUpdated: Date } ``` ### Accessing Data ```swift // Get all items in a category playlist.vodItems(forCategory: "Action Movies") // Get categorized dictionary let categorized = playlist.categorizedVODItems // Returns: ["Action Movies": [VODItem], "Sci-Fi": [VODItem], ...] // Current filtering (in VODLibraryViewModel) func filteredVODItems(from playlist: Playlist?) -> [VODItem] { var items = playlist.vodItems if let selectedCategory = selectedCategory { items = items.filter { $0.categoryID == selectedCategory } } if !searchText.isEmpty { items = items.filter { $0.name.contains(searchText) } } return items } ``` --- ## Extending the Format Your XStream provider may include additional attributes: ### Common Extended Attributes ``` #EXTINF:-1 tvg-id="ID" tvg-name="NAME" tvg-logo="URL" group-title="CATEGORY" tvg-duration="7200" // Duration in seconds tvg-rating="8.7" // IMDB rating tvg-year="1999" // Release year tvg-country="USA" // Country tvg-language="English" // Language tvg-genre="Action|Sci-Fi" // Multiple genres ,Display Title ``` ### To Support Additional Fields Update `VODItem.swift`: ```swift struct VODItem { // ... existing fields ... let duration: String? // Parse from tvg-duration let rating: String? // Parse from tvg-rating let year: String? // Parse from tvg-year let country: String? // Parse from tvg-country let language: String? // Parse from tvg-language let genres: [String]? // Parse from tvg-genre (split by |) } ``` Update `M3UParser.swift` to extract these attributes. --- ## Recommendations for Menu Organization Based on typical VOD libraries: ### For Small Libraries (<100 items) - Use current implementation (filter bar at top) - Simple and effective ### For Medium Libraries (100-500 items) - Add search functionality - Add sort options (A-Z, Year, Rating) - Keep category filter ### For Large Libraries (500+ items) - Hierarchical navigation - Featured/Recommended section - Recently Added section - Advanced filters (Year, Genre, Rating) - Robust search with suggestions --- ## Current UI Implementation Location: `VODLibraryView.swift` ### Header Section ```swift - Title: "VOD Library" - Refresh button - Logout button - Item count: "X videos" - Category filter (horizontal scroll) - All (default) - Category buttons (generated from playlist.categories) ``` ### Grid Section ```swift - LazyVGrid (4 columns) - VODCardView for each item - Poster image - Title - Category label - Focus effects ``` ### State Management ```swift VODLibraryViewModel: - selectedCategory: String? // nil = "All" - searchText: String // For future search - filteredVODItems() returns filtered array ``` --- ## Future Enhancements 1. **Search**: Add search bar, filter by name 2. **Sort**: Alphabetical, by year, by rating 3. **Favorites**: Star items, separate favorites view 4. **Continue Watching**: Track playback position 5. **Collections**: Featured, New Releases, Top Rated 6. **Multiple Genres**: Some items may fit multiple categories 7. **Metadata Display**: Show rating, year, duration on cards --- ## Testing Your Actual Playlist Once you connect to your real XStream server: 1. **Authenticate** with the app 2. **Check Xcode console** for parsed playlist data 3. **Verify categories** extracted correctly 4. **Check metadata** (logos, titles, etc.) 5. **Test filtering** by selecting different categories 6. **Verify stream URLs** are correct format If your actual playlist format differs from this sample, the M3UParser may need adjustments. --- ## Summary **Current State**: - Functional category-based filtering - Grid display with focus effects - Horizontal category selection **Format**: - Standard M3U with XStream attributes - Extracts: id, name, logo, category, stream URL **Next Steps**: - Test with your actual XStream playlist - Adjust parser if format differs - Consider additional features based on content volume