Tsa/enhance tv#741
Open
apollotsantos wants to merge 18 commits into
Open
Conversation
added 13 commits
April 22, 2026 20:27
…or Mobile and Auto configurations
… add Xtream source type support and related UI strings
…ng, and string deduplication to optimize memory usage
…search functionality; remove Xtream-related configurations and UI strings
…art of other pull request)
Contributor
Author
|
This will prevent issues like #702 (comment), where list size is a problem |
| int totalLines = 0; | ||
| // Pool to deduplicate repeating short strings (group names, catchup-source, tvg-id, etc.). | ||
| // Drastically cuts heap usage on large Xtream playlists where these fields repeat heavily. | ||
| Map<String, String> stringPool = new HashMap<>(4096); |
Owner
There was a problem hiding this comment.
Why not just using String.intern()?
There was a problem hiding this comment.
Pull request overview
This PR targets usability and reliability issues when loading very large IPTV M3U playlists in the TV addon, and adds a way to search for channels without scrolling through many categories.
Changes:
- Adds a TV navbar “Search” action that uses
SearchFolderto search channels across categories. - Adjusts the IPTV response-timeout preference UI and applies a more forgiving timeout default.
- Adds additional logging and user feedback during M3U loading/parsing to help diagnose slow loads and invalid playlist content.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/tv/src/main/res/values/strings.xml | Adds strings for timeout hint and TV search messaging. |
| modules/tv/src/main/java/me/aap/fermata/addon/tv/m3u/TvM3uFileSystemProvider.java | Tightens timeout preference bounds and clamps low values to a higher default. |
| modules/tv/src/main/java/me/aap/fermata/addon/tv/TvFragment.java | Adds a navbar search entry and executes a cross-category search via SearchFolder. |
| fermata/src/main/res/values/ids.xml | Adds a new nav_search id for the navbar menu. |
| fermata/src/main/java/me/aap/fermata/vfs/m3u/M3uFileSystem.java | Adds logging around M3U loading/download and cache file usage. |
| fermata/src/main/java/me/aap/fermata/media/lib/M3uItem.java | Adds parsing diagnostics, progress logs, string pooling, and user toasts for large playlists. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Andrey Pavlenko <andrey.a.pavlenko@gmail.com>
Co-authored-by: Andrey Pavlenko <andrey.a.pavlenko@gmail.com>
Co-authored-by: Andrey Pavlenko <andrey.a.pavlenko@gmail.com>
…back; update TV fragment for better search functionality and adjust response timeout settings.
| } | ||
|
|
||
| return new InputStreamReader(in, (cs == null) ? "UTF-8" : cs); | ||
| return new InputStreamReader(in, (cs == null) ? UTF_8 : java.nio.charset.Charset.forName(cs)); |
Comment on lines
+83
to
+84
| peekM3uHead(m3uFile); | ||
|
|
Comment on lines
269
to
275
| } else if ((name == null) || l.startsWith("#")) { | ||
| if (name == null && !l.startsWith("#") && !l.isEmpty()) { | ||
| skippedNoName++; | ||
| if (skippedNoName <= 3) Log.d("Skipped playlist entry with no name"); | ||
| } | ||
| continue; | ||
| } |
Comment on lines
+277
to
+285
| totalLines++; | ||
| VirtualResource file = vfs.resolve(l, dir).get(null); | ||
|
|
||
| if (totalLines <= 3) { | ||
| Log.d("Resolved playlist URL #", totalLines, ": ", (file != null ? "OK" : "NULL")); | ||
| } else if ((totalLines % 25000) == 0) { | ||
| Log.i("M3U parse progress: ", totalLines, " entries (", | ||
| groups.size(), " groups, ", tracks.size(), " ungrouped tracks)"); | ||
| } |
| BrowsableItem parent = parentSupplier.apply(emptyList()); | ||
| if (parent == null) return completedNull(); | ||
| String id = SCHEME + q + '@' + parent.getId(); | ||
| String id = SCHEME + ((name == null) ? "" : name + ':') + q + '@' + parent.getId(); |
| return ((cur == null) || !items.contains(cur)) ? searchParent : cur.getParent(); | ||
| }; | ||
|
|
||
| SearchFolder.search(q, getString(R.string.tv_search_title), ps).main(a.getHandler()).onSuccess(f -> { |
Comment on lines
+221
to
+223
| int timeout = ps.getIntPref(RESP_TIMEOUT); | ||
| if (timeout < 0) timeout = 30; | ||
| f.setResponseTimeout(timeout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Better handling of large IPTV playlists + search across categories
I've been using a provider whose M3U has ~500k entries, and the TV addon is pretty rough at that scale: the UI freezes for a minute on load with no feedback, memory usage is silly, and once it's loaded there's no realistic way to find a channel by scrolling through hundreds of categories. This PR is a handful of small changes to fix that.