Files
wordpress-theme-aksrt/inc/classes/widgets/class-aksrt-video-player-widget.php
T

135 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
/**
* AKSRT Video Player Widget — 视频播放器
*
* 支持 MP4、YouTube、Bilibili 等视频源。
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Widget_Video_Player extends WP_Widget {
public function __construct() {
parent::__construct(
'aksrt_video_player',
__('视频播放器', 'aksrt'),
['description' => __('在侧栏嵌入视频播放器。', 'aksrt')]
);
}
public function widget($args, $instance): void {
$title = !empty($instance['title']) ? $instance['title'] : '';
$video_url = !empty($instance['video_url']) ? $instance['video_url'] : '';
$poster = !empty($instance['poster']) ? $instance['poster'] : '';
$autoplay = !empty($instance['autoplay']);
$aspect_ratio = !empty($instance['aspect_ratio']) ? $instance['aspect_ratio'] : '16:9';
if (empty($video_url)) return;
// 解析视频类型
$embed_url = $this->get_embed_url($video_url);
$is_embed = !empty($embed_url);
echo $args['before_widget'];
if ($title) {
echo $args['before_title'] . esc_html($title) . $args['after_title'];
}
// 计算 padding-bottom
$ratio_parts = explode(':', $aspect_ratio);
if (count($ratio_parts) === 2 && (int) $ratio_parts[1] > 0) {
$padding = ((int) $ratio_parts[1] / (int) $ratio_parts[0]) * 100;
} else {
$padding = 56.25; // 16:9
}
echo '<div class="aksrt-video-widget" style="padding-bottom: ' . esc_attr(number_format($padding, 4)) . '%;">';
if ($is_embed) {
echo '<iframe src="' . esc_url($embed_url) . '" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen' . (function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('widget') : ' loading="lazy"') . '></iframe>';
} else {
echo '<video' . ($autoplay ? ' autoplay' : '') . ' controls playsinline';
if ($poster) echo ' poster="' . esc_url($poster) . '"';
echo '>';
echo '<source src="' . esc_url($video_url) . '">';
echo '</video>';
}
echo '</div>';
echo $args['after_widget'];
}
/**
* 解析 YouTube / Bilibili 链接为嵌入 URL
*/
private function get_embed_url(string $url): string {
// YouTube
if (preg_match('/(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]+)/', $url, $m)) {
return 'https://www.youtube.com/embed/' . $m[1];
}
// Bilibili
if (preg_match('/bilibili\.com\/video\/(BV[a-zA-Z0-9]+)/', $url, $m)) {
return 'https://player.bilibili.com/player.html?bvid=' . $m[1] . '&high_quality=1';
}
// 腾讯视频
if (preg_match('/v\.qq\.com\/x\/page\/([a-zA-Z0-9]+)/', $url, $m)) {
return 'https://v.qq.com/txp/iframe/player.html?vid=' . $m[1];
}
return '';
}
public function form($instance): void {
$title = !empty($instance['title']) ? $instance['title'] : '';
$video_url = !empty($instance['video_url']) ? $instance['video_url'] : '';
$poster = !empty($instance['poster']) ? $instance['poster'] : '';
$autoplay = !empty($instance['autoplay']);
$aspect_ratio = !empty($instance['aspect_ratio']) ? $instance['aspect_ratio'] : '16:9';
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题(可选):', 'aksrt'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('video_url')); ?>"><?php esc_html_e('视频 URL:', 'aksrt'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('video_url')); ?>" name="<?php echo esc_attr($this->get_field_name('video_url')); ?>" type="url" value="<?php echo esc_attr($video_url); ?>" placeholder="https://...">
<small><?php esc_html_e('支持 MP4、YouTube、Bilibili、腾讯视频链接', 'aksrt'); ?></small>
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('poster')); ?>"><?php esc_html_e('封面图 URL:', 'aksrt'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('poster')); ?>" name="<?php echo esc_attr($this->get_field_name('poster')); ?>" type="url" value="<?php echo esc_attr($poster); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('aspect_ratio')); ?>"><?php esc_html_e('宽高比:', 'aksrt'); ?></label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('aspect_ratio')); ?>" name="<?php echo esc_attr($this->get_field_name('aspect_ratio')); ?>">
<option value="16:9" <?php selected($aspect_ratio, '16:9'); ?>>16:9</option>
<option value="4:3" <?php selected($aspect_ratio, '4:3'); ?>>4:3</option>
<option value="1:1" <?php selected($aspect_ratio, '1:1'); ?>>1:1</option>
</select>
</p>
<p>
<label>
<input type="checkbox" id="<?php echo esc_attr($this->get_field_id('autoplay')); ?>" name="<?php echo esc_attr($this->get_field_name('autoplay')); ?>" value="1" <?php checked($autoplay); ?>>
<?php esc_html_e('自动播放(仅 MP4)', 'aksrt'); ?>
</label>
</p>
<?php
}
public function update($new_instance, $old_instance): array {
$instance = [];
$instance['title'] = sanitize_text_field($new_instance['title'] ?? '');
$instance['video_url'] = esc_url_raw($new_instance['video_url'] ?? '');
$instance['poster'] = esc_url_raw($new_instance['poster'] ?? '');
$instance['autoplay'] = !empty($new_instance['autoplay']);
$instance['aspect_ratio'] = in_array($new_instance['aspect_ratio'] ?? '', ['16:9', '4:3', '1:1'], true) ? $new_instance['aspect_ratio'] : '16:9';
return $instance;
}
}