Jump to content

IPTV playback stable with Threadfin and hls-proxy


Recommended Posts

darrenkdean
Posted
13 hours ago, Apotropaic said:

I have my fingers crossed for that too. I have a current working solution using a separate HLS Proxy instance, I extract the strms from the playlist directly inside emby through a plugin.

It would be good if Dispatcharr could identify the VOD content and split it into a separate playlist. I did try and just enable VOD as a channel which works but scaling it up to hundreds of thousands of entries just killed it :(

@darrenkdean- are you seeing streams appear in the Status screen of HLS Proxy, or is this the issue that you aren't seeing them?

There's no reason why you can't continue to use IPTVeditor to curate the playlist, pump it into HLS Proxy (you can have multiple instances of this), pump the output of that into Threadfin for any other channel manipulation you need to do, turn off the Threadfin proxying/buffer setting, feed that into emby. Within HLS proxy you'll be able to view all the active streams and limit them there.

What I don't know is what HLS Proxy will do to your playlist customisations out of IPTVeditor, as in will it keep your tv logo info and channel numbers intact. Channel names and group-titles should remain fine.

I am getting confused in the setup order.  Google is suggesting IPTV Provider -> Threadfin -> HLS Proxy -> Emby

If I read your note above correctly, I need to setup IPTV Provider -> HLS Proxy -> Threadfin -> Emby

Does it matter how I setup the order?  The Google suggestion would be easier if it works, lol, since I already have IPTV Provider -> Threadfin just the way I want it, lol.

Appreciate the guidance on this.

Apotropaic
Posted
6 hours ago, darrenkdean said:

I am getting confused in the setup order.  Google is suggesting IPTV Provider -> Threadfin -> HLS Proxy -> Emby

If I read your note above correctly, I need to setup IPTV Provider -> HLS Proxy -> Threadfin -> Emby

Does it matter how I setup the order?  The Google suggestion would be easier if it works, lol, since I already have IPTV Provider -> Threadfin just the way I want it, lol.

Appreciate the guidance on this.

I feel @bruoris the expert here as he's tried every combination possible :)

There is flexibility in how you do this but each way adds constraints and caveats that you must follow otherwise it won't work.

So how are you importing the channels into Emby? Do you have Threadfin added as a HDHomeRun tuner or are you just importing the playlist? As this is what will drive the best architecture to follow for you.

The key here is you need to change the way channels are imported into Emby by importing the playlist directly from HLS Proxy (don't import from Threadfin or your IPTVeditor directly). HLS Proxy will need to have been fed the playlist from ThreadFin. This is the only way I know to make HLS Proxy work, it isn't a transparent proxy if you're familiar with that term.

Your Threadfin can then stay where it is as it becomes irrelevant once a user wants to access a stream.

  • So play list ingestion is like this - IPTV Provider -> Threadfin -> HLS Proxy -> Emby
  • Where as stream access is - Emby -> HLS Proxy -> IPTV Provider

HLS Proxy works by taking the provider stream such as http://iptvprovider.xxx/live/54hgy38 and changing it to http://192.168.x.x:808x/channel/22db2b71/index.m3u8

The important thing is after HLS Proxy you cannot mess around with the playlist stream URLs, plus if something changes on Threadfin you need to trigger a refresh on HLS Proxy and on Emby, otherwise you'll end up with stale channels.

Posted

You can use threadfin in passthrough mode when provider -> threadfin -> hls-proxy -> emby is the setup and things will go well.  I also tell hls-proxy to not modify/remap the guide so I can feed the provider guide data directly to emby so it can handle guide data mapping directly. 

 

 

Kimballslice1890
Posted
3 minutes ago, bruor said:

You can use threadfin in passthrough mode when provider -> threadfin -> hls-proxy -> emby is the setup and things will go well.  I also tell hls-proxy to not modify/remap the guide so I can feed the provider guide data directly to emby so it can handle guide data mapping directly. 

 

 

I tried this and found provider -> HLS Proxy -> threadfrin/xteve fork in passthrough -> emby as playlist to be the most stable 

JIsenhour247
Posted (edited)

i am using dispatcharr only with these two ffmpeg profiles. one is h265 and one is h264 you can only use one of them i use the h265 version with no issues.

#hevc_nvenc

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -hwaccel cuda -hwaccel_output_format cuda -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v hevc_nvenc -preset fast -tune ull -profile:v main -level 4.1 -rgb_mode 1 -g 25 -bf 1 -rc vbr_hq -cq 26 -rc-lookahead 20 -lookahead_level auto -no-scenecut 1 -temporal-aq 1 -spatial-aq 1 -aq-strength 6 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v hevc_mp4toannexb pipe:1


#h264_nvenc

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -hwaccel cuda -hwaccel_output_format cuda -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v h264_nvenc -preset fast -tune ull -profile:v main -level 4.1 -rgb_mode 1 -g 25 -bf 1 -rc vbr_hq -cq 23 -rc-lookahead 20 -lookahead_level auto -no-scenecut 1 -temporal-aq 1 -spatial-aq 1 -aq-strength 6 -b:v 10000k -maxrate 13000k -bufsize 26000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v h264_mp4toannexb pipe:1

Edited by JIsenhour247
JIsenhour247
Posted (edited)

Here are a few others i have made for other types of graphics cards as well as software. All have two versions h265 & h264

#hevc_nvenc

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -hwaccel cuda -hwaccel_output_format cuda -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v hevc_nvenc -preset fast -tune ull -profile:v main -level 4.1 -rgb_mode 1 -g 25 -bf 1 -rc vbr_hq -cq 26 -rc-lookahead 20 -lookahead_level auto -no-scenecut 1 -temporal-aq 1 -spatial-aq 1 -aq-strength 6 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v hevc_mp4toannexb pipe:1

 

#h264_nvenc

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -hwaccel cuda -hwaccel_output_format cuda -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v h264_nvenc -preset fast -tune ull -profile:v main -level 4.1 -rgb_mode 1 -g 25 -bf 1 -rc vbr_hq -cq 23 -rc-lookahead 20 -lookahead_level auto -no-scenecut 1 -temporal-aq 1 -spatial-aq 1 -aq-strength 6 -b:v 10000k -maxrate 13000k -bufsize 26000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v h264_mp4toannexb pipe:1

 

#AMD Hardware (H.265/HEVC, hevc_amf)

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v hevc_amf -profile:v main -level 4.1 -g 25 -rc vbr_latency -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v hevc_mp4toannexb pipe:1

 

#AMD Hardware (H.264, h264_amf)

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v h264_amf -profile:v main -level 4.1 -g 25 -rc vbr_latency -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity pipe:1

 

#VAAPI (INTEL/AMD) - H.265

-hide_banner -loglevel error -init_hw_device vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device foo -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v hevc_vaapi -profile:v main -level 4.1 -g 25 -qp 26 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v hevc_mp4toannexb pipe:1

 

#VAAPI (Intel/AMD) – H.264

-hide_banner -loglevel error -init_hw_device vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device foo -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v h264_vaapi -profile:v main -level 4.1 -g 25 -qp 23 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity pipe:1

 

#QSV (Intel) - H.265

-hide_banner -loglevel error -init_hw_device qsv=hw -hwaccel qsv -hwaccel_output_format qsv -load_plugin hevc_hw -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v hevc_qsv -preset medium -profile:v main -level 4.1 -g 25 -global_quality 26 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v hevc_mp4toannexb pipe:1

 

#QSV (Intel) – H.264

-hide_banner -loglevel error -init_hw_device qsv=hw -hwaccel qsv -hwaccel_output_format qsv -load_plugin h264_hw -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v h264_qsv -preset medium -profile:v main -level 4.1 -g 25 -global_quality 23 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity pipe:1

 

#Software (HEVC, libx265)

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v libx265 -preset fast -tune zerolatency -profile:v main -level 4.1 -g 25 -x265-params bframes=1:crf=26:rc-lookahead=20:no-scenecut=1:aq-mode=3 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity -bsf:v hevc_mp4toannexb pipe:1

 

#Software (H.264, libx264)

-hide_banner -loglevel error -probesize 500000 -analyzeduration 1000000 -fflags +genpts+discardcorrupt -flags low_delay -avoid_negative_ts make_zero -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 60 -timeout 5000000 -rw_timeout 5000000 -copyts -start_at_zero -threads 0 -thread_queue_size 8192 -i {streamUrl} -map 0:v:0 -map 0:a:0? -map 0:s? -c:v libx264 -preset fast -tune zerolatency -profile:v main -level 4.1 -g 25 -bf 1 -crf 23 -rc-lookahead 20 -no-scenecut 1 -aq-mode 3 -b:v 9000k -maxrate 12000k -bufsize 24000k -c:a aac -b:a 128k -ac 2 -af aresample=async=0 -vsync 1 -f mpegts -muxrate 0 -muxdelay 0.05 -mpegts_flags +initial_discontinuity pipe:1

Edited by JIsenhour247
Posted

What's your thoughts process around transcoding in dispatcharr? 

 

With emby moving toward h265 transcoding in the new version, and emby may need to cut down bitrate anyway for delivery to mobile devices.  Just curious about the pros/cons. 

I'm getting ready to write up a full post on my new stack. 

Also, dispatcharr devs say not to use reconnect options on the ffmpeg process because ffmpeg is a worker and by doing that you are hiding stream connectivity issues from the main app thread.  

My provider is HLS and uses segments longer than 10 seconds which is the hard coded timeout for the main thread in dispatcharr, adding -re before -i resolves false positive errors about the stream being unhealthy in my use case.  

 

CharlesF
Posted

i installed dispatcharr and and getting much slower response times (loading of channels) than using HLS or StreamMaster.

JIsenhour247
Posted (edited)

reconnect flags in Dispatcharr only need to be removed if using failover channels. The profiles will work fine with out them. I transcode in Dispstcharr and with the #hevc_nvenc profile it works amazing my channels load/play in around 6 sec with no looping of segments or drops. My provider is using HLS as well.

Edited by JIsenhour247
JIsenhour247
Posted

Also i have used HLS Proxy in the past mind sharing your config for it? also does HLS Proxy allow hardware encoding such as using a profile to do so?

 

Posted

I was curious why you transcode in the proxy if emby could end up needing to also transcode for playback on the target device, or have you worked out a super compatible format to target that works on all devices? 

Happy to share my config file when I get a sec to dig it up.  But I'd stay away from it since it chokes whenever it hits a provider side error, effectively holding the stream in a dead state as a VOD feed until the client disconnects.  I've never tried to do transcoding with it. 

JIsenhour247
Posted

I let dispatcharr do all of the heavy lifting via hardware accel with the ffmpeg profile and turn off transcoding in emby allowing emby to just serve the stream.

  • 5 weeks later...
Posted

if running HLS Proxy in docker what image are you guys using?

Posted

I can't remember which image I used, but would highly recommend dispatcharr instead since you are already planning to use docker.

Posted
22 minutes ago, bruor said:

I can't remember which image I used, but would highly recommend dispatcharr instead since you are already planning to use docker.

Thanks!  would you recommend that over StreamMaster?

Jdiesel
Posted

Are there any recommendations on how to set this up? I wouldn't mind revisiting this and try to use my IPTV provider in Emby again. I had having lots of issues with freezing and channels failing to start when using Emby so I switch to using TiviMate directly and my issues all went away so I don't think it's my provider.

Apotropaic
Posted
On 12/07/2025 at 18:14, goin3d said:

if running HLS Proxy in docker what image are you guys using?

I’m using ‘hls-proxy-8.4.8.linux-x64’ from what I think is the main hls-proxy site.

I’ve never tried any of the other forks or implementations.

My use case was probably a lot simpler than others here, I had two instances running, one where I was simply passing though HLS to emby, and the other where I was converting mpeg streams to HLS.The account pooling feature is also very powerful.

I would also recommend Dispatchaar instead, it’s actively in development and does most of what HLS Proxy does but has features HLS Proxy doesn’t. I only use HLS Proxy for vod content now, still haven’t found something that works for my setup.

 

Apotropaic
Posted
On 12/07/2025 at 22:11, Jdiesel said:

Are there any recommendations on how to set this up? I wouldn't mind revisiting this and try to use my IPTV provider in Emby again. I had having lots of issues with freezing and channels failing to start when using Emby so I switch to using TiviMate directly and my issues all went away so I don't think it's my provider.

Dispatchaar is the most stable and flexible setup I’ve found so far, plus it’s being actively developed with a new release every few weeks. That may be good or bad depending on how you see it.

The downside is channel startup time, it is slower than the others but I prefer that over the freezing of channels and mess other setups create. The other issue I have is there’s no scalable solution for vod content yet, it’s in their roadmap.

Setting it all up depends on how you want to use it. The more effort you put into organising everything at the start the more time and headache you’ll save later. For me it’s where in import my playlist into. I select which groups I want imported, everything else gets ignored.

Groups you select get put into a stream ‘staging’ area. So from this stream list you have to create channels, these are what are ultimately exposed to emby. The channel name corresponds to the stream name and you can edit the channel name directly. The main standout feature of Dispatchaar is you can add multiple streams to a single channel. The benefit is you make it easier for users who only see one channel and Dispatchaar should switch streams automatically however you can manually do this through the GUI too. You can duplicate channels with different stream orders and put them in different profiles for different emby accounts if you wished…

Pooling of accounts works great, so if you have multiple accounts with the same provider you can set Dispatchaar to use then in sequence, the GUI will show which account is being used for which stream.

EPG integration is great, but not needed. I import my EPG and auto matching or channels is pretty good but you can always override it. This way when you import into emby channel numbers and epg are how you set them.

There’s a lot more it can do with regard to transcoding profiles, streaming profiles, you can even set individual channels to direct play, with different user agents.

Downsides of Dispatchaar.

VOD is a big one for me, I would prefer an easier way to proxy them, for now you have to import each item as a channel, I tried to import a few thousand items and it killed my instance. HLS Proxy is better in this regard as it automatically creates a proxied M3U of your entire playlist which you can manipulate and import into emby using other tools.

GUI - once you log out and log back in the GUI will take a minute or two to repopulate with your configuration. Not sure why this is the case. It just makes wanting a Quick Look at the stats a bit annoying as you have to wait. Plus sometimes the load caused by the playlist import can cause connection issues, but this is likely my weak server I have it running on.

Channel Management - changing channel positions and numbering is a bit clunky. You need to plan ahead and know which channels you want where. Plus you can’t have a gap in the numbering, any new channel you create gets added to the next free channel number. There is a profile feature where channels can be put into different M3U’s but I find it frustrating. 

Granular Controls - there’s not many streaming parameters you can configure when compared to HLS Proxy, but so far I’ve not had to amend anything. My channels play for hours on end without interruption.

  • Agree 1
  • Thanks 1
Deihmos
Posted

Tvheadend is what works for me with either a spawn profile or pipe embedded into the mux. Channel startup and stability is a lot better than what I experienced with dispatcharr. 

CharlesF
Posted
18 hours ago, Deihmos said:

Tvheadend is what works for me with either a spawn profile or pipe embedded into the mux. Channel startup and stability is a lot better than what I experienced with dispatcharr. 

would you mind further explaining this?  I've used streammaster (horrible UI, decent channel load results), HLS Proxy (works fine), and Dispatcr (slowest channel load times), and even none, just an M3U file straight from the provider into Emby, just trying to find the best solution.

  • 3 months later...
Posted

Just adding my experience here too
Used HLS Proxy with Threadfin --  I just found Dispatcharr and deployed it with proxmox -- https://community-scripts.github.io/ProxmoxVE/scripts?id=dispatcharr

Dispatcharr seems like a better option as everything is under one roof and I don't have to keep with with multiple tools or limitations such as requiring windows

I have had no issue and the transition was pretty painless.  Currently, this tool has my recommendation

Posted

For anyone following along, dispatcharr and emby work great for IPTV channels but VOD integration is still a work in progress. 

LiveTV:  Out of the box it works well, but you'll want to grab this companion app to make managing the channel lineup and filling in the gracenote IDs easy.  Additionally, it can connect to emby and make sure that all the necessary built-in Guide Data Sources are created so that emby can scrape TVG info.  Additionally, it can bulk delete channel logos so they can be re-downloaded from gracenote.  It has the ability to manage your channel configuration as well, but I haven't explored it for that. 
https://github.com/egyptiangio/channelidentifiarr

VOD: dispatcharr can handle VOD if you are using an XC provider, but someone in the community has created a .strm file generator that runs as a dispatcharr plugin.  There's a bug in dispatcharr that needs to get fixed before this will work with series (provider refresh causes some issues with episode data), but the plugin is being actively worked on in the meantime. 
https://github.com/cmc0619/vod2strm

Once the series issues are resolved I plan to enhance vod2strm a bit so that it can be configured to generate URLs that integrate with my stream caching proxy as well https://github.com/bruor/streamcache

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...