Skip to content

feat: add live TV zapping interface - #3216

Open
Wiojelt wants to merge 7 commits into
recloudstream:masterfrom
Wiojelt:feature/live-tv-zapping
Open

Wiojelt wants to merge 7 commits into
recloudstream:masterfrom
Wiojelt:feature/live-tv-zapping

Conversation

@Wiojelt

@Wiojelt Wiojelt commented Sep 24, 2026 •

Copy link
Copy Markdown

Summary

  • Adds category-local channel zapping for live streams opened from Home.
  • Reuses CloudStream's existing in-player episode selector for the channel list.
  • Uses LiveZappingGenerator to keep zapping logic separate from the core player.
  • Preserves normal player navigation while supporting TV remote channel switching.

Validation

  • :app:assembleStableDebug — passed
  • :app:testStableDebugUnitTest — passed
  • Manually tested live channel switching, channel-list navigation, touch controls, and Android TV DPAD/focus navigation.

AI assistance was used during implementation and iteration. The resulting code was manually reviewed and tested before this pull request.

@fire-light42 fire-light42 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea which would be very useful for livestream viewers.

However, this pull request contains two big issues:

1. The code is over-engineered

It only uses its own logic instead of integrating with the app. ZappingContext, ZappingSession, ZappingSessionStore, etc is way too much and way to complicated. The UI is also fully customized.

I would suggest re-using the in-video episodes popup to select other livestreams. This reduces the complexity and aligns with what users already expect. I also suggest offloading the zapping logic to a custom VideoGenerator. This removes complex logic within an already complex player.

2. Views are not in XML

If you need a custom view then please create XML files instead of creating the view programmatically.

scaleType = ImageView.ScaleType.CENTER_CROP
setBackgroundColor(context.colorFromAttribute(R.attr.boxItemBackground))
}
val scrim = View(context).apply {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All throughout the pull request you create layouts programmatically. This gives a working result, but is very difficult to inspect, maintain and review. Please use XML (or Compose) to inflate the view, and only use Kotlin to fill the view (i.e. change visibility, set texts, set images...).

* Gives specialised players a chance to consume TV channel-style DPAD input while the
* controls are hidden. Normal player navigation remains unchanged when this returns false.
*/
protected open fun handleLiveChannelKey(keyCode: Int): Boolean = false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation fully hooks the up and down buttons on TV which makes normal navigation in livestreams impossible.

val currentIndex: Int,
) {
init {
require(channels.isNotEmpty()) { "ZappingContext requires at least one channel" }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will lead to app crashes. Use debugAssert instead.

if (!enabled) toggleZappingList(false)
}

private fun isZappingEnabled(): Boolean {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use AppSettings(context).player.zappingEnabled instead

@Wiojelt

Wiojelt commented Sep 25, 2026

Copy link
Copy Markdown
Author

Thanks for the review. I've reworked the implementation around LiveZappingGenerator and the existing in-player episode selector, and removed the custom zapping session/store/UI implementation.

I've also adjusted the TV navigation so the normal player focus behavior is preserved, while channel switching is only handled when the player controls are hidden. The latest version has been manually tested with touch controls and Android TV DPAD/focus navigation, and both the build and unit tests pass.

Could you please take another look when you have time?

One small question: we're currently using test builds with our community for this feature. If the PR is accepted, roughly when would it become available to regular CloudStream users?

@fire-light42

Copy link
Copy Markdown
Collaborator

If the PR is accepted, roughly when would it become available to regular CloudStream users?

When it is merged all pre-release users will get access to it within 15 minutes. CloudStream users on stable will gain access to it within a month or two.

@Ofhlea

Ofhlea commented Oct 4, 2026

Copy link
Copy Markdown

Sabırla bekliyoruz

@Solid1907

Copy link
Copy Markdown

It will be very usefull idea wish dev will add this feature

@alis-labs

Copy link
Copy Markdown

This is exactly the kind of behavior I’d love to see for live TV.

While watching a live stream, it should be possible to switch directly to the previous/next channel with a single Up/Down press on the TV remote — similar to CH+/CH− on a traditional TV — without leaving the player or opening the channel list first.

That kind of quick channel zapping would make live TV in CloudStream feel much more natural.

@iskader

iskader commented Oct 5, 2026

Copy link
Copy Markdown

We're waiting, Master.

@atesveyselvates-arch

Copy link
Copy Markdown

özelliği bekliyoruz hocam teşekkürler

@Wiojelt

Wiojelt commented Oct 6, 2026

Copy link
Copy Markdown
Author

If the PR is accepted, roughly when would it become available to regular CloudStream users?

When it is merged all pre-release users will get access to it within 15 minutes. CloudStream users on stable will gain access to it within a month or two.

@fire-light42 maybe this one got forgotten? 😅

@Raygen06

Raygen06 commented Oct 7, 2026

Copy link
Copy Markdown

Bekliyoruz teşekkürler hocam

@Enderx1977

Copy link
Copy Markdown

Harika bir özellik olacak bekliyoruz

@masterlvnt-glitch

Copy link
Copy Markdown

Sağda oynatma listesi özelliği istiyoruz 😉

@fire-light42

Copy link
Copy Markdown
Collaborator

I have not forgotten about this pull request, I have simply been busy recently. It will be merged 👍

@sydney07

sydney07 commented Oct 9, 2026

Copy link
Copy Markdown

Özet

  • Evden açılan canlı yayınlar için kategori-yerel kanal zapping ekler.
  • Kanal listesi için CloudStream'in mevcut oyuncu içi bölüm seçicisini yeniden kullanır.
  • Kullanır LiveZappingGenerator zapping mantığını çekirdek oyuncudan ayrı tutmak için.
  • TV uzak kanal geçişini desteklerken normal oyuncu navigasyonunu korur.

Doğrulama

  • :uygulama: AssembleStableDebug — geçti
  • :app:testStableDebugUnitTest — geçti
  • Manuel olarak test edilmiş canlı kanal değiştirme, kanal listesi navigasyonu, dokunmatik kontroller ve Android TV DPAD/odak navigasyonu.

Uygulama ve yineleme sırasında yapay zeka yardımı kullanıldı. Ortaya çıkan kod, bu çekme talebinden önce manuel olarak incelendi ve test edildi.

Özet

  • Evden açılan canlı yayınlar için kategori-yerel kanal zapping ekler.
  • Kanal listesi için CloudStream'in mevcut oyuncu içi bölüm seçicisini yeniden kullanır.
  • Kullanır LiveZappingGenerator zapping mantığını çekirdek oyuncudan ayrı tutmak için.
  • TV uzak kanal geçişini desteklerken normal oyuncu navigasyonunu korur.

Doğrulama

  • :uygulama: AssembleStableDebug — geçti
  • :app:testStableDebugUnitTest — geçti
  • Manuel olarak test edilmiş canlı kanal değiştirme, kanal listesi navigasyonu, dokunmatik kontroller ve Android TV DPAD/odak navigasyonu.

Uygulama ve yineleme sırasında yapay zeka yardımı kullanıldı. Ortaya çıkan kod, bu çekme talebinden önce manuel olarak incelendi ve test edildi.

I wonder when this feature will arrive; we are eagerly awaiting it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.