Files
wordpress-theme-aksrt/src/AKSRT/Widgets/WidgetVideoPlayer.php
T
kate522 08e63c07f4 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.
2026-07-21 08:35:59 +08:00

146 lines
6.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Video player widget (zibll dplayer lite via data-aksrt-video + embed).
*
* @package AKSRT
*/
namespace AKSRT\Widgets;
defined('ABSPATH') || exit;
class WidgetVideoPlayer extends \WP_Widget {
public function __construct() {
parent::__construct(
'aksrt_video_player',
__('视频播放器', 'aksrt'),
[
'description' => __('侧栏/流体区嵌入视频(共享 aksrt-video 播放器)。', 'aksrt'),
'classname' => 'widget_aksrt_video_player',
]
);
}
public function widget($args, $instance): void {
$title = (string) ($instance['title'] ?? '');
$video_url = trim((string) ($instance['video_url'] ?? $instance['url'] ?? ''));
$poster = trim((string) ($instance['poster'] ?? $instance['pic'] ?? ''));
$autoplay = !empty($instance['autoplay']);
$loop = !empty($instance['loop']);
$muted = $autoplay || !empty($instance['muted']);
$hide_controller = !empty($instance['hide_controller']);
$scale = max(20, min(100, (int) ($instance['scale_height'] ?? 56)));
$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 '<div class="c-red muted-box mb20"><b>' . esc_html__('视频播放器:', 'aksrt') . '</b>' .
esc_html__('请配置视频 URL 或移出该模块', 'aksrt') . '</div>';
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
return;
}
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if ($title !== '') {
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
if ($aspect !== '' && str_contains($aspect, ':')) {
$parts = explode(':', $aspect);
if (count($parts) === 2 && (int) $parts[0] > 0) {
$scale = (int) round(((int) $parts[1] / (int) $parts[0]) * 100);
}
}
$embed = $this->get_embed_url($video_url);
$cls = 'aksrt-video-widget relative-h radius8' . ($hide_controller ? ' controller-hide' : '');
echo '<div class="' . esc_attr($cls) . '" style="padding-bottom:' . esc_attr((string) $scale) . '%">';
if ($embed !== '') {
$src = $embed;
if ($autoplay) {
$src = add_query_arg(['autoplay' => '1', 'mute' => '1'], $src);
}
echo '<iframe class="aksrt-video-widget__frame" src="' . esc_url($src) . '" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen loading="lazy"></iframe>';
} else {
// 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';
}
printf(
'<div class="aksrt-video aksrt-video-widget__player" data-aksrt-video data-src="%s" data-type="%s"%s%s%s%s></div>',
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 '</div>';
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
private function get_embed_url(string $url): string {
if (preg_match('#(?:youtube\.com/watch\?v=|youtu\.be/)([A-Za-z0-9_-]+)#', $url, $m)) {
return 'https://www.youtube.com/embed/' . rawurlencode($m[1]);
}
if (preg_match('#bilibili\.com/video/(BV[\w]+)#', $url, $m)) {
return 'https://player.bilibili.com/player.html?bvid=' . rawurlencode($m[1]) . '&high_quality=1';
}
if (preg_match('#v\.qq\.com/.+?/([A-Za-z0-9]+)\.html#', $url, $m)) {
return 'https://v.qq.com/txp/iframe/player.html?vid=' . rawurlencode($m[1]);
}
return '';
}
public function form($instance): void {
?>
<p>
<label><?php esc_html_e('标题', 'aksrt'); ?>
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('title')); ?>" value="<?php echo esc_attr((string) ($instance['title'] ?? '')); ?>">
</label>
</p>
<p>
<label><?php esc_html_e('视频 URL(mp4/m3u8/flv 或 YouTube/B站/腾讯)', 'aksrt'); ?>
<input class="widefat" type="url" name="<?php echo esc_attr($this->get_field_name('video_url')); ?>" value="<?php echo esc_attr((string) ($instance['video_url'] ?? '')); ?>">
</label>
</p>
<p>
<label><?php esc_html_e('封面图 URL', 'aksrt'); ?>
<input class="widefat" type="url" name="<?php echo esc_attr($this->get_field_name('poster')); ?>" value="<?php echo esc_attr((string) ($instance['poster'] ?? '')); ?>">
</label>
</p>
<p>
<label><?php esc_html_e('高度占比 %', 'aksrt'); ?>
<input class="tiny-text" type="number" min="20" max="100" name="<?php echo esc_attr($this->get_field_name('scale_height')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['scale_height'] ?? 56))); ?>">
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('autoplay')); ?>" value="1" <?php checked(!empty($instance['autoplay'])); ?>> <?php esc_html_e('自动播放', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('loop')); ?>" value="1" <?php checked(!empty($instance['loop'])); ?>> <?php esc_html_e('循环', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_controller')); ?>" value="1" <?php checked(!empty($instance['hide_controller'])); ?>> <?php esc_html_e('隐藏控制条样式', 'aksrt'); ?></label>
</p>
<?php
}
public function update($new_instance, $old_instance): array {
return [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'video_url' => esc_url_raw(trim((string) ($new_instance['video_url'] ?? ''))),
'poster' => esc_url_raw(trim((string) ($new_instance['poster'] ?? ''))),
'scale_height' => max(20, min(100, (int) ($new_instance['scale_height'] ?? 56))),
'autoplay' => !empty($new_instance['autoplay']) ? 1 : 0,
'loop' => !empty($new_instance['loop']) ? 1 : 0,
'hide_controller' => !empty($new_instance['hide_controller']) ? 1 : 0,
];
}
}