Skip to content

MakeForce/APMPlayer

Repository files navigation

APMPlayer

一个基于原生 HTML5 video 标签构建的轻量级、自适应 MP4 视频播放器。

鸣谢

本项目全程依靠 AI 工具完成需求梳理、架构设计、代码开发、文档编写,特此诚挚致谢:

  1. 豆包
    负责全套开发规范文档生成、分阶段流程设计、API 文档与 README 排版、开源文件模板提供。
    官网:https://www.doubao.com

  2. Trae AI
    负责播放器核心代码实现、交互逻辑、UI 渲染与工程化构建。
    官网:https://trae.ai

项目完整开发流程

本项目遵循 Codex / Claude / Trae 标准化分阶段 AI 开发流程,严格执行阶段目标 + 验收机制,全部前置规划文档由豆包辅助生成:

  1. 需求与工程规范文档生成阶段
    向豆包(对话历史)完整输出项目需求,由豆包生成整套 AI 协同开发规范文件:

    • agents.md:AI 智能体行为约束、项目工程规则
    • planning.md:分阶段开发计划、各阶段目标与验收标准
    • SPED.md:产品规格说明书,功能、交互、API、兼容性定义
    • .rules:代码规范、提交规范、文件约束
    • memory/:项目记忆目录,存储需求变更、迭代记录、问题台账 所有阶段强制要求:完成当前阶段验收标准,才可进入下一开发阶段
  2. 工程初始化阶段
    在 Trae 编辑器创建 Vite+TS 库工程,导入豆包输出的全套规划规范文件,确认目录结构、构建配置、Git 配置无误后,启动正式编码开发。

  3. 分阶段编码迭代阶段
    依照 planning.md 划分的阶段依次开发,每阶段完成后对照验收项自测;全程使用 Trae 完成核心代码编写、交互逻辑实现、分层架构落地。

  4. 文档与开源配套完善阶段
    豆包辅助完成完整 README、.gitignore、MIT LICENSE 开源文件,统一输出标准化可直接使用的文本。

特点

  • 轻量级:零第三方播放器依赖,纯原生实现
  • 自适应:根据容器宽度自动调整控制器布局
  • 图标化:所有按钮采用内联 SVG 图标,无文字
  • 可扩展:支持自定义按钮注入
  • 交互流畅:XGPlayer 风格居中悬浮播放/暂停效果

快速开始

安装

pnpm install APMPlayer

在浏览器中使用

<link rel="stylesheet" href="dist/apm-player.css">
<script src="dist/apm-player.umd.js"></script>

<div id="player-container" style="width: 640px; height: 360px;"></div>

<script>
const container = document.getElementById('player-container');
const player = new APMPlayer({
  container: container,
  videoUrl: 'https://example.com/video.mp4',
  autoplay: false,
  muted: false,
});
</script>

在 ES Module 中使用

import APMPlayer from 'APMPlayer';
import 'APMPlayer/dist/apm-player.css';

const container = document.getElementById('player-container');
const player = new APMPlayer({
  container: container,
  videoUrl: 'https://example.com/video.mp4',
});

API

配置项

配置项 类型 默认值 说明
container HTMLElement - 播放器容器元素
videoUrl string - 视频地址
poster string - 视频封面图
autoplay boolean false 是否自动播放
muted boolean false 是否静音
loop boolean false 是否循环播放
showPip boolean true 是否显示画中画按钮
showDownload boolean true 是否显示下载按钮
showFullscreen boolean true 是否显示样式全屏按钮
showNativeFullscreen boolean true 是否显示原生全屏按钮
showLoading boolean true 是否显示加载动画
customButtons CustomButtonConfig[] - 自定义按钮配置

方法

// 播放
player.play();

// 暂停
player.pause();

// 切换播放/暂停
player.toggle();

// 跳转指定时间(秒)
player.seek(30);

// 设置音量(0-1)
player.setVolume(0.5);

// 切换静音
player.toggleMute();

// 切换画中画
player.togglePip();

// 下载视频
player.download();

// 切换样式全屏
player.toggleFullscreen();

// 切换原生全屏
player.toggleNativeFullscreen();

// 切换视频地址
player.setVideoUrl('new-video.mp4', 'new-poster.jpg');

// 销毁播放器
player.destroy();

事件

player.on('play', () => {
  console.log('视频开始播放');
});

player.on('pause', () => {
  console.log('视频暂停');
});

player.on('ended', () => {
  console.log('视频播放结束');
});

player.on('timeupdate', (currentTime, duration) => {
  console.log(`当前时间: ${currentTime}, 总时长: ${duration}`);
});

player.on('volumechange', (volume, muted) => {
  console.log(`音量: ${volume}, 静音: ${muted}`);
});

player.on('loadedmetadata', (duration) => {
  console.log(`视频元数据加载完成,时长: ${duration}`);
});

player.on('progress', (buffered) => {
  console.log(`缓冲进度: ${buffered}%`);
});

player.on('error', (error) => {
  console.error('播放错误:', error);
});

player.on('fullscreenchange', (isFullscreen) => {
  console.log(`全屏状态: ${isFullscreen}`);
});

player.on('pipchange', (isPip) => {
  console.log(`画中画状态: ${isPip}`);
});

自定义按钮

const player = new APMPlayer({
  container: container,
  videoUrl: 'video.mp4',
  customButtons: [
    {
      id: 'custom-btn',
      icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/></svg>',
      onClick: (player) => {
        console.log('自定义按钮点击');
      },
      tooltip: '自定义按钮',
      alwaysCollapsed: false,
    },
  ],
});

键盘快捷键

按键 功能
Space 播放/暂停
ArrowLeft 快退 5 秒
ArrowRight 快进 5 秒
ArrowUp 音量增加 10%
ArrowDown 音量减少 10%
F 切换原生全屏
M 切换静音

项目介绍

架构设计

采用分层架构设计,确保代码的可维护性和可扩展性:

src/
├── core/          # 核心逻辑层
│   └── index.ts   # 媒体核心能力封装
├── ui/            # UI 渲染层
│   └── index.ts   # 控制器、悬浮图标、菜单等
├── buttons/       # 按钮管理层
│   └── index.ts   # 按钮注册、收纳、渲染
├── types.ts       # 类型定义
├── utils.ts       # 工具函数
├── styles/        # 样式文件
│   └── index.css
└── index.ts       # 播放器主类

核心特性

1. 自适应收纳

播放器会根据容器宽度自动调整按钮布局:

  • 宽度充足时,所有按钮横向展示
  • 宽度不足时,自动将选配按钮和自定义按钮收纳到三点菜单中
  • MORE 按钮仅在需要收纳时显示

2. 控制栏显隐逻辑

  • 视频播放中,鼠标离开播放器:自动隐藏
  • 视频播放中,鼠标不动 3 秒:自动隐藏
  • 视频暂停中:不自动隐藏
  • 正在拖拽进度条/音量:不自动隐藏
  • 更多菜单显示中:不自动隐藏

3. XGPlayer 风格悬浮图标

  • 首次加载未播放:居中展示透明轮廓播放图标,点击播放且图标永久消失
  • 播放中点击视频空白处:浮现透明轮廓暂停图标,渐变淡出消失
  • 暂停中点击视频空白处:浮现透明轮廓播放图标,渐变淡出消失

4. 双全屏模式

  • 样式全屏:容器全屏,非系统全屏,兼容更多场景
  • 原生全屏:系统原生全屏,支持 ESC 键退出

5. 生命周期管理

所有事件监听、观察者都会在 destroy() 方法中彻底销毁,避免内存泄漏。

技术栈

  • TypeScript 7.0+
  • Vite 8.0+
  • 原生 HTML5 Video API

构建命令

# 开发模式
pnpm run dev

# 生产构建
pnpm run build

# 类型检查
pnpm run typecheck

# 预览构建产物
pnpm run preview

浏览器兼容性

支持所有现代浏览器,包括:

  • Chrome/Edge (最新版本)
  • Firefox (最新版本)
  • Safari (最新版本)

许可证 License

MIT License

Releases

Packages

Contributors

Languages