Skip to content

Add Filter to Show Cover Image When Self-Hosted Video Ends#2292

Merged
Misplon merged 3 commits intodevelopfrom
fix/video-show-poster-on-end
Mar 28, 2026
Merged

Add Filter to Show Cover Image When Self-Hosted Video Ends#2292
Misplon merged 3 commits intodevelopfrom
fix/video-show-poster-on-end

Conversation

@Misplon
Copy link
Copy Markdown
Member

@Misplon Misplon commented Mar 6, 2026

Summary

  • Adds a sow_video_show_cover_on_end filter (defaults to false) that, when enabled, resets a self-hosted video back to its poster/cover image after playback ends instead of freezing on the last frame.
  • Users can enable it with add_filter( 'sow_video_show_cover_on_end', '__return_true' );

How it works

  • The filter adds a data-show-cover-on-end attribute to the <video> element via the existing $video_args array.
  • The JS listens for the ended event and calls video.load() to reset the player to its initial state, re-displaying the poster image.

Test plan

  • Add a self-hosted video with a cover image, confirm default behavior is unchanged (freezes on last frame)
  • Enable the filter and confirm the video resets to the cover image after playback ends
  • Confirm it works with both MediaElement.js controls and hidden controls
  • Confirm loop still takes priority (looped videos don't fire ended)

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Misplon Misplon requested a review from AlexGStapleton March 6, 2026 11:57
@Misplon Misplon changed the title Add filter to show cover image when self-hosted video ends Add Filter to Show Cover Image When Self-Hosted Video Ends Mar 14, 2026
@AlexGStapleton
Copy link
Copy Markdown
Member

I'm having trouble getting both widgets/video/js/so-video-widget.js to output (it has a specific set of requirements) and the show-cover-on-end attribute present. What is the required settings combination, and is that combination a little too strict? It might be worth altering the so-video-widget.js changes to allow for it to be output with more settings combinations (will require JS adjustments to prevent issues).

@Misplon
Copy link
Copy Markdown
Member Author

Misplon commented Mar 18, 2026

@AlexGStapleton

You were right. The requirements were too strict.

Before this change, the filter would only work when so-video-widget.js was already being loaded, which for self-hosted videos effectively meant a fairly narrow combination of settings such as hidden controls or FitVids being enabled.

I have loosened that now in e5845b2e. If sow_video_show_cover_on_end returns true for a self-hosted video, we also enqueue so-video-widget.js, so the poster reset behavior is no longer tied to that smaller set of settings.

I also adjusted the JS initialization so repeated setup_widgets calls only initialize new video elements and do not reinitialize existing ones.

That should make the filter work with the normal self-hosted video setup as well.

Copy link
Copy Markdown
Member

@AlexGStapleton AlexGStapleton left a comment

Choose a reason for hiding this comment

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

Thanks for changing that. I don't see any direct issues with those changes and the cover now appears for me after the video finishes. Strangely, the image displays differently after playing. Are you getting this? This happens with every image I've tested so I don't think it's image specific.

Before play:

Image

After play:

Image

Comment thread widgets/video/tpl/default.php Outdated
$video_args['controls'] = '';
}

if ( apply_filters( 'sow_video_show_cover_on_end', false, $instance ) ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The value returned by apply_filters should ideally be typecast as a bool.

No need to do further validation beyond this. This is just to ensure a valid value is returned, and the contents are irrelevant).

@Misplon
Copy link
Copy Markdown
Member Author

Misplon commented Mar 26, 2026

@AlexGStapleton I've pushed follow-up changes in 5d12b65.

For the inline review point, sow_video_show_cover_on_end is now normalized through a dedicated boolean helper and that value is reused for both the JS enqueue decision and the template attribute output.

For the poster rendering issue, I removed the generic ended -> load() reset for MediaElement-backed videos and switched that path to MediaElement's built-in showPosterWhenEnded handling instead. The native load() fallback is still only used when MediaElement isn't in play.

I haven't done a browser pass yet on my side, so if you get a chance to retest the controls-enabled self-hosted case, that would be useful.

Copy link
Copy Markdown
Member

@AlexGStapleton AlexGStapleton left a comment

Choose a reason for hiding this comment

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

Browser pass looks good. Cover is now the correct size after the video finishes.

@Misplon Misplon merged commit e341b6d into develop Mar 28, 2026
@Misplon Misplon deleted the fix/video-show-poster-on-end branch March 28, 2026 15:25
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.

2 participants