uniapp开发前端静态视频界面+如何将本地视频转换成网络地址

uniapp开发前端静态视频界面

界面样式例子

复制代码
<template>
  <view class="container">
    <!-- 顶部导航栏 -->
    <view class="navbar">
      <text class="nav-title">视频库</text>
    </view>

    <!-- 视频封面网格 -->
    <view class="video-grid">
      <view class="video-item" v-for="(video, index) in videos" :key="index" @click="playVideo(index)">
        <!-- 视频封面 -->
        <view class="video-cover-container">
          <image class="video-cover" :src="video.coverUrl" mode="aspectFill" :alt="video.title"></image>
          <!-- 播放按钮覆盖层 -->
          <view class="play-button">
            <image src="/static/play.png" mode="widthFix" class="play-icon" alt="播放视频"></image>
          </view>
          <!-- 视频时长 -->
          <view class="video-duration">
            <text>{{ formatDuration(video.duration) }}</text>
          </view>
        </view>

        <!-- 视频标题 -->
        <view class="video-title">
          <text>{{ video.title }}</text>
        </view>
      </view>
    </view>

    <!-- 视频播放器弹窗 -->
    <view class="video-modal" v-if="showPlayer">
      <view class="modal-overlay" @click="closePlayer"></view>
      <view class="modal-content">
        <view class="modal-header">
          <text class="modal-title">{{ currentVideo.title }}</text>
          <view class="close-button" @click="closePlayer">
            <image src="/static/display.png" mode="widthFix" alt="关闭播放" class="close-icon"></image>
          </view>
        </view>
        <video class="video-player" :src="currentVideo.videoUrl" :title="currentVideo.title" controls autoplay @ended="closePlayer"></video>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue';

// 视频数据
const videos = ref([
  {
    id: 1,
    title: '情绪稳定才是最好的养生',
    coverUrl: '/static/health/cover1.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video1.mp4',
    duration: 185 // 秒
  },
  {
    id: 2,
    title: '养生操',
    coverUrl: '/static/health/cover2.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video2.mp4',
    duration: 247
  },
  {
    id: 3,
    title: '养生操',
    coverUrl: '/static/health/cover3.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video3.mp4',
    duration: 156
  },
  {
    id: 4,
    title: '养生操',
    coverUrl: '/static/health/cover4.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video4.mp4',
    duration: 210
  },
  {
    id: 5,
    title: '情绪稳定才是最好的养生',
    coverUrl: '/static/health/cover1.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video1.mp4',
    duration: 185 // 秒
  },
  {
    id: 6,
    title: '养生操',
    coverUrl: '/static/health/cover2.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video2.mp4',
    duration: 247
  },
  {
    id: 7,
    title: '养生操',
    coverUrl: '/static/health/cover3.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video3.mp4',
    duration: 156
  },
  {
    id: 8,
    title: '养生操',
    coverUrl: '/static/health/cover4.png', // 视频封面图路径
    videoUrl: 'http://172.19.129.147:8084/video4.mp4',
    duration: 210
  }
]);

// 播放状态
const showPlayer = ref(false);
const currentVideo = ref(null);

// 格式化时长为 MM:SS 格式
const formatDuration = (seconds) => {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
};

// 播放视频
const playVideo = (index) => {
  currentVideo.value = videos.value[index];
  showPlayer.value = true;
};

// 关闭播放器
const closePlayer = () => {
  showPlayer.value = false;
  currentVideo.value = null;
};

// 页面加载时的操作
onMounted(() => {
  // 可以在这里添加加载本地视频列表的逻辑
  console.log('视频画廊页面加载完成');
});
</script>

<style scoped>
.container {
  background-color: #f5f5f5;
  min-height: 100vh;
}

/* 导航栏样式 */
.navbar {
  height: 44px;
  background-color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid #eee;
  position: sticky;
  top: 0;
  z-index: 10;
}

.nav-title {
  font-size: 18px;
  font-weight: bold;
  color: #333;
}

/* 视频网格样式 */
.video-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 10px;
}

.video-item {
  background-color: #fff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 视频封面样式 */
.video-cover-container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 比例 */
}

.video-cover {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* 播放按钮样式 */
.play-button {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 48px;
  height: 48px;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.8;
  transition: opacity 0.3s;
}

.video-item:hover .play-button {
  opacity: 1;
}

.play-icon {
  width: 24px;
  height: 24px;
  tint-color: #fff;
}

/* 视频时长样式 */
.video-duration {
  position: absolute;
  bottom: 4px;
  right: 4px;
  background-color: rgba(0, 0, 0, 0.7);
  color: #fff;
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
}

/* 视频标题样式 */
.video-title {
  padding: 8px 10px;
  font-size: 14px;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 视频播放器弹窗样式 */
.video-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 100;
}

.modal-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
}

.modal-content {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  background-color: #000;
  color: #fff;
}

.modal-title {
  font-size: 16px;
  font-weight: 500;
  max-width: 80%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.close-button {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-icon {
  width: 20px;
  height: 20px;
  tint-color: #fff;
}

.video-player {
  flex: 1;
  width: 100%;
  background-color: #000;
}
</style>

如何将本地视频转换成网络地址

要将本地视频文件夹 D:\game_design\javacode\Identification\static\health 中的视频文件,转换为 http://example.com/video.mp4 这类 HTTP 地址,核心是将该文件夹作为「HTTP 服务的静态资源目录」 ,让视频文件通过 HTTP 协议被访问,并最终关联到 example.com 域名。以下是分场景的详细操作步骤(兼顾「本地测试」和「正式公网访问」,适配你的开发需求):

前提:确认视频文件信息

首先明确文件夹内的具体视频文件名 (比如你的视频叫 herb_intro.mp4),最终 HTTP 地址指向的是「文件」而非「文件夹」,因此需先确定:

目标视频的完整本地路径 = 你的文件夹路径 + 视频文件名,例如:
D:\game_design\javacode\Identification\static\health\herb_intro.mp4

第一步:搭建 HTTP 服务(核心:让本地文件夹可通过 HTTP 访问)

根据你的需求(开发 APP),推荐两种常用方式:临时测试用「Python 快速服务」正式开发用「结合 APP 后端服务」

方式 1:临时测试(用 Python 快速搭建 HTTP 服务)

适合本地调试 APP 时,快速生成 HTTP 地址访问视频,无需复杂配置。

  1. 打开 Windows 命令提示符(CMD)
    按下 Win + R,输入 cmd 回车,打开命令行窗口。

  2. 切换到目标视频文件夹
    输入以下命令(注意路径带空格,需用英文引号包裹),回车:

    复制代码
    cd "D:\game_design\javacode\Identification\static\health"

    (若提示 "系统找不到指定路径",检查路径是否拼写正确,比如是否有空格或错别字)

  3. 启动 HTTP 服务:若你的电脑安装了 Python 3(推荐),输入命令

    复制代码
    python -m http.server 

    8080 是端口号,可替换为 8000、8081 等未被占用的端口,若端口被占用会提示 "Address already in use",换个端口即可)启动成功后,命令行会显示 Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/)。第二步:获取「本地 HTTP 访问地址」(测试用)

方式 2:正式开发(结合 APP 后端服务,推荐)

若你的 "中草药识别 APP" 已有 Java 后端(如 Spring Boot),可直接将 static\health 文件夹配置为「静态资源目录」,让后端服务直接提供视频访问,更贴合开发流程。

  1. 以 Spring Boot 后端为例(假设你用 Java 开发)
    若你的后端项目是 Identification(对应路径中的 Identification 文件夹),static 目录本身就是 Spring Boot 默认的静态资源目录,无需额外配置!
    即:static\health 文件夹下的视频,会自动被后端服务识别为静态资源。
  2. 启动后端服务
    运行你的 Java 后端项目(如启动 Spring Boot 的 main 方法),假设后端服务的端口是 8080(默认常见端口)。

第二步:获取「本地 HTTP 访问地址」(测试用)

无论用哪种方式搭建服务,都先通过「本地 IP + 端口 + 视频文件名」生成访问地址,验证能否正常访问。

  1. 查看本地电脑的 IPv4 地址
    在 CMD 中输入 ipconfig,找到「无线局域网适配器 WLAN」或「以太网」下的「IPv4 地址」,例如 192.168.1.105(局域网内的本地 IP)。
  2. 拼接本地 HTTP 地址
    • 若用 Python 服务(端口 8080,视频名 herb_intro.mp4):
      http://192.168.1.105:8080/herb_intro.mp4
    • 若用 Spring Boot 后端(端口 8080,视频名 herb_intro.mp4):
      http://192.168.1.105:8080/health/herb_intro.mp4
      (注意:Spring Boot 会以 static 为根目录,因此路径需加 health 文件夹名,对应 static/health
  3. 验证访问
    打开浏览器,输入上述地址,若能正常播放视频,说明本地 HTTP 服务已搭建成功。

如果是静态开发测试到这一步就可以了

第三步:配置「公网域名访问」(实现 http://example.com/video.mp4

本地地址只能在局域网内访问(如手机连同一 WiFi),若需 APP 发布后所有人能访问,需将地址关联到 example.com 这类公网域名,分 3 个关键步骤:

1. 准备:注册域名(替换 example.com

example.com 是示例域名,需先注册一个真实可用的域名(如在阿里云、腾讯云、华为云等平台注册):

  • 搜索「阿里云域名注册」,查询你想要的域名(如 herb-identify.com),完成购买和实名认证。
  • 假设最终注册的域名为 your-domain.com(后续用它替代 example.com)。
2. 让本地服务可被公网访问(2 种方案)

方案 A:本地开发 / 测试用「内网穿透」 (无需服务器,简单快捷)

适合 APP 还在开发阶段,想临时让外部设备(如手机流量)访问本地视频:

  • 下载内网穿透工具(如「花生壳」「ngrok」「Sunny-Ngrok」),以花生壳为例:
    1. 注册花生壳账号,登录后点击「添加映射」,选择「HTTP 映射」。
    2. 「内网地址」填第一步获取的本地 IP + 端口(如 192.168.1.105:8080),「映射名称」自定义(如 herb-video)。
    3. 映射成功后,花生壳会生成一个「公网访问地址」(如 abc123.vip.gzicp.net)。

方案 B:正式部署用「云服务器」 (稳定,适合 APP 发布)

若 APP 需长期提供视频访问,需将视频文件夹部署到云服务器(如阿里云 EC2、腾讯云 CVM):

  1. 购买云服务器(选择 Windows 或 Linux 系统,推荐 Linux + Nginx 更稳定)。

  2. 将本地 static\health 文件夹及视频文件,通过 FTP 工具(如 FileZilla)上传到服务器的指定目录(如 Linux 下的 /var/www/herb-video)。

  3. 安装 Nginx(Web 服务器),配置静态资源指向:
    编辑 Nginx 配置文件(如 /etc/nginx/nginx.conf),添加:

    复制代码
    server {
        listen 80;  # 默认 HTTP 端口
        server_name your-domain.com;  # 你的域名
    
        # 配置视频文件夹为静态资源目录
        location / {
            root /var/www/herb-video;  # 服务器上视频文件夹的路径
            autoindex off;  # 关闭目录浏览(安全)
            add_header Access-Control-Allow-Origin *;  # 允许 APP 跨域访问(关键)
        }
    }
  4. 重启 Nginx 服务,确保配置生效

3. 域名解析:将域名指向公网地址

无论用「内网穿透」还是「云服务器」,都需将注册的域名(如 your-domain.com)解析到对应的公网地址:

  1. 进入域名注册平台(如阿里云)的「域名控制台」,找到你的域名,点击「解析」。
  2. 添加「A 记录」或「CNAME 记录」:
    • 若用云服务器:添加 A 记录,「主机记录」填 @(表示直接用 your-domain.com),「记录值」填云服务器的公网 IP(如 120.24.xx.xx)。
    • 若用内网穿透(如花生壳):添加 CNAME 记录,「主机记录」填 @,「记录值」填花生壳生成的公网地址(如 abc123.vip.gzicp.net)。
  3. 域名解析生效时间通常为 10-30 分钟(耐心等待)。

第四步:生成最终的 http://example.com/video.mp4 地址

解析生效后,根据视频文件名拼接最终地址:

  • 若视频文件名是 herb_intro.mp4,且通过云服务器 / Nginx 配置了根目录指向视频文件夹:
    最终地址 = http://your-domain.com/herb_intro.mp4
    (若想简化为 http://your-domain.com/video.mp4,只需将视频文件重命名为 video.mp4 即可)
  • 若用 Spring Boot 后端部署到服务器(端口 80,因 HTTP 默认端口是 80,可省略端口):
    最终地址 = http://your-domain.com/health/video.mp4
    (若想去掉 health,可在后端配置静态资源映射时,将 static/health 映射为根路径,或把视频移到 static 根目录)

关键注意事项(适配 APP 开发)

  1. 跨域问题 :若 APP 前端(如 Android/iOS 原生或 Flutter)访问视频时出现 "跨域错误",需在后端服务(如 Spring Boot/Nginx)添加跨域允许配置(如 Nginx 的 add_header Access-Control-Allow-Origin *)。
  2. 端口省略 :HTTP 协议默认端口是 80,若服务端口配置为 80,地址中可省略端口(如 http://your-domain.com/video.mp4,无需加 :80)。
  3. 视频格式兼容性:确保视频格式(如 MP4、HLS)适配 APP 播放组件,避免无法播放。
相关推荐
2501_916008895 小时前
iOS 抓包工具有哪些?全面盘点主流工具与功能对比分析
android·ios·小程序·https·uni-app·iphone·webview
2501_915921435 小时前
iOS混淆工具实战 视频流媒体类 App 的版权与播放安全保护
android·ios·小程序·https·uni-app·iphone·webview
NewChapter °5 小时前
如何通过 Gitee API 上传文件到指定仓库
前端·vue.js·gitee·uni-app
LeonIter6 小时前
视频判重需求:别为同一内容花两次钱!
音视频·特征提取·重复判定
SY_FC7 小时前
uniapp阿里云验证码使用
阿里云·uni-app·notepad++
二川bro8 小时前
第24节:3D音频与空间音效实现
3d·音视频
算家云8 小时前
腾讯最新开源HunyuanVideo-Foley本地部署教程:端到端TV2A框架,REPA策略+MMDiT架构,重新定义视频音效新SOTA!
人工智能·音视频·算家云·hunyuanvideo·模型部署教程·镜像社区
—Qeyser8 小时前
好看的背景颜色 uniapp+小程序
小程序·uni-app·uniapp·微信小游戏
2501_916008899 小时前
uni-app iOS 日志与崩溃分析全流程 多工具协作的实战指南
android·ios·小程序·https·uni-app·iphone·webview