From 08e63c07f4452b147a071c3ab76f1d4c62a6a6f6 Mon Sep 17 00:00:00 2001
From: unknown
Date: Tue, 21 Jul 2026 08:35:59 +0800
Subject: [PATCH] feat(widgets): VideoPlayer data-aksrt-video shared player
shell
Route non-embed videos through video-player.js with poster/type/autoplay
loop/muted attrs; keep platform iframe embeds; admin empty warning.
---
assets/js/video-player.js | 6 +++-
src/AKSRT/Widgets/WidgetVideoPlayer.php | 48 +++++++++++++++----------
2 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/assets/js/video-player.js b/assets/js/video-player.js
index fe52c533..8f0e461f 100644
--- a/assets/js/video-player.js
+++ b/assets/js/video-player.js
@@ -65,6 +65,8 @@
this.poster = this.el.dataset.poster || '';
this.type = this.el.dataset.type || detectType(this.src);
this.autoplay = this.el.dataset.autoplay === 'true';
+ this.loop = this.el.dataset.loop === 'true';
+ this.muted = this.el.dataset.muted === 'true' || this.autoplay;
this.init();
}
@@ -76,8 +78,10 @@
this.video.controls = true;
this.video.playsInline = true;
this.video.preload = this.autoplay ? 'auto' : 'metadata';
+ if (this.loop) this.video.loop = true;
+ if (this.muted) this.video.muted = true;
if (this.poster) this.video.poster = this.poster;
- this.video.style.cssText = 'display:block;width:100%;height:auto;max-height:70vh;';
+ this.video.style.cssText = 'display:block;width:100%;height:100%;object-fit:contain;max-height:none;';
// Play overlay
this.overlay = document.createElement('div');
diff --git a/src/AKSRT/Widgets/WidgetVideoPlayer.php b/src/AKSRT/Widgets/WidgetVideoPlayer.php
index d20a2d0f..fde4bf8c 100644
--- a/src/AKSRT/Widgets/WidgetVideoPlayer.php
+++ b/src/AKSRT/Widgets/WidgetVideoPlayer.php
@@ -1,6 +1,6 @@
__('侧栏/流体区嵌入视频播放器。', 'aksrt')]
+ [
+ 'description' => __('侧栏/流体区嵌入视频(共享 aksrt-video 播放器)。', 'aksrt'),
+ 'classname' => 'widget_aksrt_video_player',
+ ]
);
}
@@ -31,6 +34,12 @@ class WidgetVideoPlayer extends \WP_Widget {
$aspect = (string) ($instance['aspect_ratio'] ?? '');
if ($video_url === '') {
+ if (current_user_can('manage_options')) {
+ echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo '' . esc_html__('视频播放器:', 'aksrt') . '' .
+ esc_html__('请配置视频 URL 或移出该模块', 'aksrt') . '
';
+ echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ }
return;
}
@@ -47,29 +56,32 @@ class WidgetVideoPlayer extends \WP_Widget {
}
$embed = $this->get_embed_url($video_url);
- $cls = 'aksrt-video-widget' . ($hide_controller ? ' controller-hide' : '');
+ $cls = 'aksrt-video-widget relative-h radius8' . ($hide_controller ? ' controller-hide' : '');
echo '';
+
if ($embed !== '') {
$src = $embed;
if ($autoplay) {
$src = add_query_arg(['autoplay' => '1', 'mute' => '1'], $src);
}
- echo '
';
+ echo '
';
} else {
- $attrs = ' controls playsinline';
- if ($autoplay) {
- $attrs .= ' autoplay';
+ // Shared player stack (assets/js/video-player.js).
+ $type = 'mp4';
+ if (preg_match('/\.m3u8(\?|$)/i', $video_url)) {
+ $type = 'hls';
+ } elseif (preg_match('/\.flv(\?|$)/i', $video_url)) {
+ $type = 'flv';
}
- if ($loop) {
- $attrs .= ' loop';
- }
- if ($muted) {
- $attrs .= ' muted';
- }
- if ($poster !== '') {
- $attrs .= ' poster="' . esc_url($poster) . '"';
- }
- echo '
';
+ printf(
+ '
',
+ esc_url($video_url),
+ esc_attr($type),
+ $poster !== '' ? ' data-poster="' . esc_url($poster) . '"' : '',
+ $autoplay ? ' data-autoplay="true"' : '',
+ $loop ? ' data-loop="true"' : '',
+ $muted ? ' data-muted="true"' : ''
+ );
}
echo '
';
@@ -97,7 +109,7 @@ class WidgetVideoPlayer extends \WP_Widget {
-