Add audio/video toggle for HLS streams#4686
Open
leandroalonso wants to merge 9 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an in-player audio/video visibility toggle for HLS streams that contain video, letting users switch Now Playing between the video surface and episode artwork while continuing audio playback. The feature is gated by FeatureFlag.hls and only appears when runtime stream inspection detects video tracks.
Changes:
- Introduces a new
PlayerAction.videoTogglewith localized title/icon and shelf + overflow handling. - Adds
PlaybackManagerstate forvideoRenderingEnabledand helpers to determine availability and whether the video surface should be rendered. - Updates Now Playing UI to show/hide the floating video surface and force an artwork refresh when switching video → audio.
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| podcasts/ShelfLoadState.swift | Extends shelf reload caching to include video toggle availability + rendering state. |
| podcasts/ShelfActionsViewController+Table.swift | Wires overflow menu tap handling for the new .videoToggle action. |
| podcasts/PlayerZoomAnimator.swift | Uses shouldRenderVideo() to decide video vs artwork transition behavior. |
| podcasts/PlayerImages.xcassets/video_on.imageset/video_on.svg | Adds “video on” shelf icon (SVG). |
| podcasts/PlayerImages.xcassets/video_on.imageset/Contents.json | Registers video_on asset with template rendering. |
| podcasts/PlayerImages.xcassets/video_off.imageset/video_off.svg | Adds “video off” shelf icon (SVG). |
| podcasts/PlayerImages.xcassets/video_off.imageset/Contents.json | Registers video_off asset with template rendering. |
| podcasts/PlaybackManager.swift | Adds video rendering state + toggle APIs; resets state per episode. |
| podcasts/NowPlayingPlayerItemViewController+Update.swift | Updates Now Playing surface switching logic and forces artwork reload when hiding video. |
| podcasts/NowPlayingPlayerItemViewController+Shelf.swift | Adds shelf button + delegate handling for .videoToggle. |
| podcasts/NowPlayingPlayerItemViewController.swift | Uses shouldRenderVideo() when deciding whether to open the full video controller. |
| podcasts/MiniPlayerToFullPlayerAnimator.swift | Uses shouldRenderVideo() for transition decisions. |
| podcasts/Enumerations.swift | Adds analytics mapping, title/icon, and applicability for .videoToggle. |
| podcasts/en.lproj/Localizable.strings | Adds “Show Video” / “Hide Video” localized strings. |
| PocketCastsTests/Tests/Utilities/SettingsTests.swift | Updates expected default player action list to include .videoToggle. |
| Modules/Sources/PocketCastsUtils/General/AtomicBool.swift | Adds AtomicBool initializer for setting initial value. |
| Modules/Sources/PocketCastsDataModel/Public/Enums.swift | Adds PlayerAction.videoToggle to the shared model enum. |
…y docstring/guard Post a distinct videoRenderingToggled notification from toggleVideoRendering() instead of reusing videoPlaybackEngineSwitched, so the user toggle no longer feeds MiniPlayerViewController's auto-open path (only runtime video detection does). The Now Playing screen observes both notifications. Also guard toggleVideoRendering() on canToggleVideoRendering() and correct the docstring: the toggle is display-only and does not stop video decoding. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Member
Author
Review feedback addressed
|
…tors The property now returns shouldRenderVideo(), which reflects whether the video surface is currently shown (false when the user toggles video off), so the old name was misleading. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Member
Author
Review feedback addressed |
…endering value.toggle() is a separate read + write and can race. Add an atomic toggle() that flips storageValue on the serial queue, and use it in toggleVideoRendering(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
update() already reloads the artwork at the end of the method, so the explicit loadImage in the hide branch was a redundant second call. Keep only the layout pass that fixes the first-time blank artwork. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Member
Author
Review feedback addressed
|
3 tasks
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.
Fixes PCIOS-811
Adds an audio/video toggle to the player shelf for HLS streams that carry video.
When an HLS stream is found to contain video, a new Show/Hide Video action appears on the player shelf. Tapping it switches the Now Playing screen between the video surface and the episode artwork, letting the user listen audio-only. The whole feature is gated behind the existing
FeatureFlag.hlsflag and only shows for HLS streams found to carry video (not for regular video podcasts).Notable details
PlayerAction.videoTogglecase, added last in the default actions (so it defaults into the overflow menu; users can reorder it).PlaybackManagergainsvideoRenderingEnabledstate plusshouldRenderVideo()/canToggleVideoRendering()/toggleVideoRendering(). The state resets per episode.To test
Checklist
CHANGELOG.mdif necessary.