Summary
On systems where Kodi 21.3 is built against FFmpeg 8.x (e.g. CoreELEC avdvplus R9, and other forks following current CoreELEC), all HLS playback from TheCrew fails at the demuxer stage with:
```
ffmpeg[...]: [hls] URL https://.../p1775426897142998435_2266.txt is not in allowed_segment_extensions,
consider updating hls.c and submitting a patch to ffmpeg-devel, if this should be added
[hls] parse_playlist error Invalid data found when processing input [https://.../caxi]
OpenDemuxStream - Error creating demuxer
```
This affects live channels, sports, and any TheCrew source that serves HLS manifests whose segments have a `.txt` extension.
Root cause
FFmpeg 8 enforces a strict `allowed_segment_extensions` allow-list in `libavformat/hls.c`. The default is:
```
3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,
mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,vtt,wav,webvtt,cmfv,cmfa
```
Segments with a `.txt` extension are rejected. FFmpeg upstream will not add it (intentional security behaviour). FFmpeg 8.1 keeps the same list, so future CoreELEC releases do not fix this either.
On Windows Kodi 21.2 and similar builds still on FFmpeg 7.x the same streams play fine — so this is a regression visible only once a user's Kodi build moves to FFmpeg 8.
Fix
Route HLS playback through `inputstream.adaptive` instead of Kodi's built-in FFmpeg HLS demuxer. `inputstream.adaptive` has its own HLS parser and never consults the FFmpeg allow-list.
File: `script.module.thecrew/lib/resources/lib/indexers/lists.py`
Function: `player().play()` (around line 1122 in 0.4.x-era builds)
Patch
Before:
```python
item = control.item(path=url)
try: item.setArt({'icon': icon})
except: pass
item.setInfo(type='Video', infoLabels = meta)
control.player.play(url, item)
control.resolve(int(sys.argv[1]), True, item)
```
After:
```python
item = control.item(path=url)
try: item.setArt({'icon': icon})
except: pass
item.setInfo(type='Video', infoLabels = meta)
Force inputstream.adaptive for HLS URLs — FFmpeg 8 rejects .txt segments
if any(x in url.lower() for x in ['.m3u8', '.m3u', 'load-playlist']):
_hdrs = url.split('|', 1)[1] if '|' in url else ''
item.setProperty('inputstream', 'inputstream.adaptive')
item.setProperty('inputstream.adaptive.manifest_type', 'hls')
if _hdrs:
item.setProperty('inputstream.adaptive.manifest_headers', _hdrs)
item.setProperty('inputstream.adaptive.stream_headers', _hdrs)
item.setMimeType('application/vnd.apple.mpegurl')
item.setContentLookup(False)
control.player.play(url, item)
control.resolve(int(sys.argv[1]), True, item)
```
Three non-obvious details worth noting for any future PR
- Channel/live playback goes through `lists.py`, not `modules/player.py`. `modules/player.py` already has a similar `inputstream.adaptive` block but it's on a different code path and isn't reached by the channel/`action=play` flow.
- Properties must be set before `control.player.play(url, item)`. In the `action=play` plugin flow `sys.argv[1]` is `-1`, so `setResolvedUrl` silently fails — `player.play()` is what actually starts playback, and the `inputstream` property must be on the listitem before that call.
- Sub-playlist headers must be propagated. The top-level manifest fetch works with Kodi's `|Header=value` URL-suffix syntax, but inputstream.adaptive's sub-requests go out without those headers and hit HTTP 403 on the inner playlists. Passing the header string via `inputstream.adaptive.manifest_headers` + `inputstream.adaptive.stream_headers` fixes it. This is why a naive one-line property set (just `inputstream = inputstream.adaptive`) still breaks with HTTP 403 after the manifest parses.
Note on `modules/player.py`
The sibling file `script.module.thecrew/lib/resources/lib/modules/player.py` has an analogous block (around line 81-85). In current zips that block has an indentation inconsistency (mixed tab + spaces on the `if any(x in url.lower()...` line) which causes `TabError` on Python 3 module import — the whole module fails to load, so the existing `inputstream.adaptive` setup silently doesn't apply there either. Worth fixing in the same pass (use spaces only for that line).
Verification
With Kodi debug logging on, a successful playback now shows:
```
AddOnLog: inputstream.adaptive: Open()
AddOnLog: inputstream.adaptive: Manifest successfully parsed (Periods: 1, Streams in first period: 2, Type: live)
AddOnLog: inputstream.adaptive: OpenStream(1001)
```
And no `ffmpeg[...]: [hls] URL ... is not in allowed_segment_extensions` lines.
Environment where this was reproduced
- Device: Homatics Box R4 Plus (Amlogic S905X4)
- OS: CoreELEC avdvplus R9 (FFmpeg 8.0.1)
- Kodi: 21.3 Omega
- inputstream.adaptive: 21.5.18.1
- TheCrew repository: 0.3.x / `script.module.thecrew` current version
Cross-referenced at avdvplus/Builds#118 where the same issue was reported against the CoreELEC build; concluded the fix belongs here in TheCrew rather than in the FFmpeg layer.
Happy to supply a full diff / patched zip if that's easier to integrate than a prose patch.
Summary
On systems where Kodi 21.3 is built against FFmpeg 8.x (e.g. CoreELEC avdvplus R9, and other forks following current CoreELEC), all HLS playback from TheCrew fails at the demuxer stage with:
```
ffmpeg[...]: [hls] URL https://.../p1775426897142998435_2266.txt is not in allowed_segment_extensions,
consider updating hls.c and submitting a patch to ffmpeg-devel, if this should be added
[hls] parse_playlist error Invalid data found when processing input [https://.../caxi]
OpenDemuxStream - Error creating demuxer
```
This affects live channels, sports, and any TheCrew source that serves HLS manifests whose segments have a `.txt` extension.
Root cause
FFmpeg 8 enforces a strict `allowed_segment_extensions` allow-list in `libavformat/hls.c`. The default is:
```
3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,
mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,vtt,wav,webvtt,cmfv,cmfa
```
Segments with a `.txt` extension are rejected. FFmpeg upstream will not add it (intentional security behaviour). FFmpeg 8.1 keeps the same list, so future CoreELEC releases do not fix this either.
On Windows Kodi 21.2 and similar builds still on FFmpeg 7.x the same streams play fine — so this is a regression visible only once a user's Kodi build moves to FFmpeg 8.
Fix
Route HLS playback through `inputstream.adaptive` instead of Kodi's built-in FFmpeg HLS demuxer. `inputstream.adaptive` has its own HLS parser and never consults the FFmpeg allow-list.
File: `script.module.thecrew/lib/resources/lib/indexers/lists.py`
Function: `player().play()` (around line 1122 in 0.4.x-era builds)
Patch
Before:
```python
item = control.item(path=url)
try: item.setArt({'icon': icon})
except: pass
item.setInfo(type='Video', infoLabels = meta)
control.player.play(url, item)
control.resolve(int(sys.argv[1]), True, item)
```
After:
```python
item = control.item(path=url)
try: item.setArt({'icon': icon})
except: pass
item.setInfo(type='Video', infoLabels = meta)
Force inputstream.adaptive for HLS URLs — FFmpeg 8 rejects .txt segments
if any(x in url.lower() for x in ['.m3u8', '.m3u', 'load-playlist']):
_hdrs = url.split('|', 1)[1] if '|' in url else ''
item.setProperty('inputstream', 'inputstream.adaptive')
item.setProperty('inputstream.adaptive.manifest_type', 'hls')
if _hdrs:
item.setProperty('inputstream.adaptive.manifest_headers', _hdrs)
item.setProperty('inputstream.adaptive.stream_headers', _hdrs)
item.setMimeType('application/vnd.apple.mpegurl')
item.setContentLookup(False)
control.player.play(url, item)
control.resolve(int(sys.argv[1]), True, item)
```
Three non-obvious details worth noting for any future PR
Note on `modules/player.py`
The sibling file `script.module.thecrew/lib/resources/lib/modules/player.py` has an analogous block (around line 81-85). In current zips that block has an indentation inconsistency (mixed tab + spaces on the `if any(x in url.lower()...` line) which causes `TabError` on Python 3 module import — the whole module fails to load, so the existing `inputstream.adaptive` setup silently doesn't apply there either. Worth fixing in the same pass (use spaces only for that line).
Verification
With Kodi debug logging on, a successful playback now shows:
```
AddOnLog: inputstream.adaptive: Open()
AddOnLog: inputstream.adaptive: Manifest successfully parsed (Periods: 1, Streams in first period: 2, Type: live)
AddOnLog: inputstream.adaptive: OpenStream(1001)
```
And no `ffmpeg[...]: [hls] URL ... is not in allowed_segment_extensions` lines.
Environment where this was reproduced
Cross-referenced at avdvplus/Builds#118 where the same issue was reported against the CoreELEC build; concluded the fix belongs here in TheCrew rather than in the FFmpeg layer.
Happy to supply a full diff / patched zip if that's easier to integrate than a prose patch.