Route non-embed videos through video-player.js with poster/type/autoplay loop/muted attrs; keep platform iframe embeds; admin empty warning.
146 lines
6.2 KiB
PHP
146 lines
6.2 KiB
PHP
<?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,
|
||
];
|
||
}
|
||
}
|