269 lines
5.0 KiB
Vue
269 lines
5.0 KiB
Vue
![]() |
<template>
|
|||
|
<div class="local-video-demo">
|
|||
|
<div class="container">
|
|||
|
<h1>本地视频播放演示</h1>
|
|||
|
<p class="description">
|
|||
|
这个页面演示了如何使用CKPlayer播放器播放public文件夹中的本地视频文件。
|
|||
|
</p>
|
|||
|
|
|||
|
<div class="demo-section">
|
|||
|
<h2>本地视频播放</h2>
|
|||
|
<div class="video-wrapper">
|
|||
|
<VideoPlayer
|
|||
|
:use-local-video="true"
|
|||
|
title="本地视频演示"
|
|||
|
description="这是来自public/video/first.mp4的本地视频文件,使用CKPlayer播放器进行播放。"
|
|||
|
:autoplay="false"
|
|||
|
:show-controls="true"
|
|||
|
@play="onPlay"
|
|||
|
@pause="onPause"
|
|||
|
@ended="onEnded"
|
|||
|
@error="onError"
|
|||
|
/>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="info-section">
|
|||
|
<h3>技术说明</h3>
|
|||
|
<ul>
|
|||
|
<li>使用CKPlayer播放器替代原生HTML5 video元素</li>
|
|||
|
<li>支持本地视频文件播放(public/video/first.mp4)</li>
|
|||
|
<li>支持HLS流媒体和MP4格式</li>
|
|||
|
<li>提供完整的播放控制功能</li>
|
|||
|
<li>响应式设计,支持移动端</li>
|
|||
|
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
|
|||
|
<div class="controls-section">
|
|||
|
<h3>播放控制</h3>
|
|||
|
<div class="control-buttons">
|
|||
|
<button @click="playVideo" class="control-btn">播放</button>
|
|||
|
<button @click="pauseVideo" class="control-btn">暂停</button>
|
|||
|
<button @click="seekVideo(30)" class="control-btn">跳转到30秒</button>
|
|||
|
<button @click="setVideoVolume(50)" class="control-btn">音量50%</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="status-section">
|
|||
|
<h3>播放状态</h3>
|
|||
|
<div class="status-info">
|
|||
|
<div class="status-item">
|
|||
|
<strong>播放状态:</strong> {{ isPlaying ? '播放中' : '已暂停' }}
|
|||
|
</div>
|
|||
|
<div class="status-item">
|
|||
|
<strong>错误信息:</strong> {{ errorMessage || '无' }}
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
|
|||
|
<script setup lang="ts">
|
|||
|
import { ref } from 'vue'
|
|||
|
import VideoPlayer from '@/components/VideoPlayer.vue'
|
|||
|
|
|||
|
|
|||
|
// 播放状态
|
|||
|
const isPlaying = ref(false)
|
|||
|
const errorMessage = ref('')
|
|||
|
|
|||
|
// 视频播放器引用
|
|||
|
const videoPlayerRef = ref<InstanceType<typeof VideoPlayer>>()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const onPlay = () => {
|
|||
|
isPlaying.value = true
|
|||
|
console.log('视频开始播放')
|
|||
|
}
|
|||
|
|
|||
|
const onPause = () => {
|
|||
|
isPlaying.value = false
|
|||
|
console.log('视频暂停')
|
|||
|
}
|
|||
|
|
|||
|
const onEnded = () => {
|
|||
|
isPlaying.value = false
|
|||
|
console.log('视频播放结束')
|
|||
|
}
|
|||
|
|
|||
|
const onError = (error: Event) => {
|
|||
|
errorMessage.value = '视频播放出错'
|
|||
|
console.error('视频播放错误:', error)
|
|||
|
}
|
|||
|
|
|||
|
// 控制方法
|
|||
|
const playVideo = () => {
|
|||
|
if (videoPlayerRef.value) {
|
|||
|
videoPlayerRef.value.play()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const pauseVideo = () => {
|
|||
|
if (videoPlayerRef.value) {
|
|||
|
videoPlayerRef.value.pause()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const seekVideo = (time: number) => {
|
|||
|
if (videoPlayerRef.value) {
|
|||
|
videoPlayerRef.value.seek(time)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const setVideoVolume = (volume: number) => {
|
|||
|
if (videoPlayerRef.value) {
|
|||
|
videoPlayerRef.value.setVolume(volume)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
</script>
|
|||
|
|
|||
|
<style scoped>
|
|||
|
.local-video-demo {
|
|||
|
min-height: 100vh;
|
|||
|
background: #f5f5f5;
|
|||
|
padding: 20px 0;
|
|||
|
}
|
|||
|
|
|||
|
.container {
|
|||
|
max-width: 1200px;
|
|||
|
margin: 0 auto;
|
|||
|
padding: 0 20px;
|
|||
|
}
|
|||
|
|
|||
|
h1 {
|
|||
|
text-align: center;
|
|||
|
color: #333;
|
|||
|
margin-bottom: 10px;
|
|||
|
}
|
|||
|
|
|||
|
.description {
|
|||
|
text-align: center;
|
|||
|
color: #666;
|
|||
|
margin-bottom: 40px;
|
|||
|
font-size: 16px;
|
|||
|
}
|
|||
|
|
|||
|
.demo-section {
|
|||
|
background: white;
|
|||
|
border-radius: 8px;
|
|||
|
padding: 24px;
|
|||
|
margin-bottom: 24px;
|
|||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|||
|
}
|
|||
|
|
|||
|
.demo-section h2 {
|
|||
|
margin-top: 0;
|
|||
|
margin-bottom: 20px;
|
|||
|
color: #333;
|
|||
|
}
|
|||
|
|
|||
|
.video-wrapper {
|
|||
|
max-width: 800px;
|
|||
|
margin: 0 auto;
|
|||
|
}
|
|||
|
|
|||
|
.info-section,
|
|||
|
.controls-section,
|
|||
|
.status-section {
|
|||
|
background: white;
|
|||
|
border-radius: 8px;
|
|||
|
padding: 24px;
|
|||
|
margin-bottom: 24px;
|
|||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|||
|
}
|
|||
|
|
|||
|
.info-section h3,
|
|||
|
.controls-section h3,
|
|||
|
.status-section h3 {
|
|||
|
margin-top: 0;
|
|||
|
margin-bottom: 16px;
|
|||
|
color: #333;
|
|||
|
}
|
|||
|
|
|||
|
.info-section ul {
|
|||
|
margin: 0;
|
|||
|
padding-left: 20px;
|
|||
|
}
|
|||
|
|
|||
|
.info-section li {
|
|||
|
margin-bottom: 8px;
|
|||
|
color: #666;
|
|||
|
}
|
|||
|
|
|||
|
.control-buttons {
|
|||
|
display: flex;
|
|||
|
gap: 12px;
|
|||
|
flex-wrap: wrap;
|
|||
|
}
|
|||
|
|
|||
|
.control-btn {
|
|||
|
padding: 8px 16px;
|
|||
|
background: #1890ff;
|
|||
|
color: white;
|
|||
|
border: none;
|
|||
|
border-radius: 4px;
|
|||
|
cursor: pointer;
|
|||
|
transition: background-color 0.3s;
|
|||
|
}
|
|||
|
|
|||
|
.control-btn:hover {
|
|||
|
background: #40a9ff;
|
|||
|
}
|
|||
|
|
|||
|
.control-btn.secondary {
|
|||
|
background: #f5f5f5;
|
|||
|
color: #666;
|
|||
|
}
|
|||
|
|
|||
|
.control-btn.secondary:hover {
|
|||
|
background: #e6e6e6;
|
|||
|
}
|
|||
|
|
|||
|
.status-info {
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
gap: 8px;
|
|||
|
}
|
|||
|
|
|||
|
.status-item {
|
|||
|
color: #666;
|
|||
|
}
|
|||
|
|
|||
|
.status-item strong {
|
|||
|
color: #333;
|
|||
|
}
|
|||
|
|
|||
|
/* 响应式设计 */
|
|||
|
@media (max-width: 768px) {
|
|||
|
.container {
|
|||
|
padding: 0 16px;
|
|||
|
}
|
|||
|
|
|||
|
.demo-section,
|
|||
|
.info-section,
|
|||
|
.controls-section,
|
|||
|
.status-section {
|
|||
|
padding: 16px;
|
|||
|
}
|
|||
|
|
|||
|
.control-buttons {
|
|||
|
justify-content: center;
|
|||
|
}
|
|||
|
|
|||
|
.control-btn {
|
|||
|
flex: 1;
|
|||
|
min-width: 120px;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|