skills/media-chrome/SKILL.md
Media Chrome 是一个基于 Web Components 的媒体播放器控件库。此技能用于集成、配置和使用 media-chrome 组件,创建自定义视频/音频播放器,支持原生 HTML5 video/audio 以及 HLS、DASH、YouTube、Vimeo 等多种媒体源,并与 React、Vue、Angular 等框架兼容。当用户需要使用或扩展 media-chrome 功能时使用此技能。
npx skillsauth add long36708/longmo-skills media-chromeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Media Chrome 提供了一套可自定义的 Web Components 媒体播放器控件,可以轻松集成到任何项目中。本技能涵盖组件的安装、基本使用、高级配置、自定义组件开发以及在不同框架中的集成方式。
<!-- ES Modules -->
<script type="module" src="https://cdn.jsdelivr.net/npm/media-chrome@4/+esm"></script>
<!-- 或者使用 IIFE 版本 -->
<script src="https://cdn.jsdelivr.net/npm/media-chrome@4/dist/iife/index.js"></script>
npm install media-chrome
// ES Modules
import 'media-chrome';
// 或者按需导入
import { MediaController, MediaPlayButton } from 'media-chrome';
# 安装依赖
npm install
# 开发模式(带热重载)
npm run dev
# 构建
npm run build
# 运行测试
npm test
使用 <media-controller> 作为容器,slot="media" 放置媒体元素:
<media-controller>
<video
slot="media"
src="https://example.com/video.mp4"
playsinline
crossorigin
></video>
<media-control-bar>
<media-play-button></media-play-button>
<media-mute-button></media-mute-button>
<media-volume-range></media-volume-range>
<media-time-range></media-time-range>
<media-fullscreen-button></media-fullscreen-button>
</media-control-bar>
</media-controller>
添加 audio 属性到 <media-controller>:
<media-controller audio>
<audio
slot="media"
src="https://example.com/audio.mp3"
></audio>
<media-control-bar>
<media-play-button></media-play-button>
<media-time-display showduration></media-time-display>
<media-time-range></media-time-range>
<media-playback-rate-button></media-playback-rate-button>
<media-mute-button></media-mute-button>
<media-volume-range></media-volume-range>
</media-control-bar>
</media-controller>
| 属性 | 说明 | 示例值 |
|------|------|--------|
| audio | 音频模式,移除视频特定样式 | audio |
| defaultsubtitles | 默认启用字幕 | defaultsubtitles |
| hotkeys | 启用键盘快捷键(默认启用) | hotkeys |
| nohotkeys | 禁用键盘快捷键 | nohotkeys |
| keyboardforwardseekoffset | 前进跳转秒数 | "15" |
| keyboardbackwardseekoffset | 后退跳转秒数 | "5" |
| defaultstreamtype | 默认流类型 | "on-demand" 或 "live" |
<media-play-button> - 播放/暂停按钮<media-mute-button> - 静音按钮<media-volume-range> - 音量滑块<media-time-range> - 进度条(支持缩略图预览)<media-time-display> - 当前时间显示<media-duration-display> - 总时长显示<media-fullscreen-button> - 全屏按钮<media-pip-button> - 画中画按钮<media-airplay-button> - AirPlay 按钮<media-cast-button> - 投屏按钮<media-captions-button> - 字幕按钮<media-playback-rate-button> - 倍速按钮<media-poster-image> - 海报图片<media-loading-indicator> - 加载指示器| Slot 名称 | 说明 |
|-----------|------|
| media | 媒体元素(video/audio 或自定义媒体元素) |
| poster | 海报图片 |
| centered-chrome | 居中的控制元素(如加载指示器) |
| top-chrome | 顶部控制栏 |
| bottom-chrome | 底部控制栏 |
<video slot="media" src="video.mp4" playsinline crossorigin>
<track kind="captions" label="中文" src="captions.vtt" srclang="zh" default>
</video>
需要先加载 hls-video-element:
<script type="module" src="https://cdn.jsdelivr.net/npm/[email protected]/+esm"></script>
<media-controller>
<hls-video
slot="media"
src="https://example.com/stream.m3u8"
stream-type="on-demand"
preload="metadata"
playsinline
crossorigin
></hls-video>
<!-- 控制组件 -->
</media-controller>
<script type="module" src="https://cdn.jsdelivr.net/npm/[email protected]/+esm"></script>
<media-controller>
<youtube-video
slot="media"
video-id="VIDEO_ID"
playsinline
></youtube-video>
<!-- 控制组件 -->
</media-controller>
参考 examples/media-elements/ 目录下的示例:
dash-video-element)vimeo-video-element)/* 防止未定义的元素显示 */
:not(:defined) {
display: none;
}
/* 防止布局偏移(CLS) */
media-controller:not([audio]) {
display: block;
max-width: 960px;
aspect-ratio: 16 / 9;
}
video {
width: 100%;
}
Media Chrome 组件支持多种 CSS 变量进行样式自定义:
media-controller {
--media-control-background: rgba(0, 0, 0, 0.7);
--media-control-hover-background: rgba(0, 0, 0, 0.9);
--media-primary-color: #3b82f6;
--media-text-color: #ffffff;
}
/* 播放按钮 */
media-play-button {
--media-play-button-display: flex;
--media-play-button-width: 40px;
--media-play-button-height: 40px;
}
/* 进度条 */
media-time-range {
--media-time-range-height: 6px;
}
查看 references/css-variables.md 获取完整的 CSS 变量列表。
使用官方 React 包装器:
npm install media-chrome
import { MediaController, MediaPlayButton, MediaMuteButton } from 'media-chrome/react';
function VideoPlayer() {
return (
<MediaController>
<video slot="media" src="video.mp4" playsinline />
<MediaPlayButton />
<MediaMuteButton />
</MediaController>
);
}
或直接使用 Web Components:
import { useEffect, useRef } from 'react';
function VideoPlayer() {
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
import('media-chrome');
}, []);
return (
<media-controller>
<video ref={videoRef} slot="media" src="video.mp4" playsinline />
<media-play-button />
<media-mute-button />
</media-controller>
);
}
<script setup>
import { onMounted, ref } from 'vue';
onMounted(() => {
import('media-chrome');
});
</script>
<template>
<media-controller>
<video slot="media" src="video.mp4" playsinline />
<media-play-button />
<media-mute-button />
</media-controller>
</template>
import { Component, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-video-player',
template: `
<media-controller>
<video slot="media" src="video.mp4" playsinline></video>
<media-play-button></media-play-button>
<media-mute-button></media-mute-button>
</media-controller>
`
})
export class VideoPlayerComponent implements AfterViewInit {
ngAfterViewInit() {
import('media-chrome');
}
}
需要导入菜单组件:
<script type="module" src="media-chrome/dist/menu/index.js"></script>
<media-controller>
<video slot="media" src="video.mp4">
<track kind="captions" label="中文" src="zh.vtt" srclang="zh">
<track kind="captions" label="English" src="en.vtt" srclang="en">
</video>
<media-control-bar>
<media-play-button></media-play-button>
<media-captions-button></media-captions-button>
<media-fullscreen-button></media-fullscreen-button>
</media-control-bar>
<media-captions-menu anchor="auto" hidden></media-captions-menu>
</media-controller>
<media-settings-menu anchor="auto" hidden>
<media-settings-menu-item>
Speed
<media-playback-rate-menu slot="submenu" hidden>
<div slot="title">Speed</div>
</media-playback-rate-menu>
</media-settings-menu-item>
<media-settings-menu-item>
Quality
<media-rendition-menu slot="submenu" hidden>
<div slot="title">Quality</div>
</media-rendition-menu>
</media-settings-menu-item>
</media-settings-menu>
在 media-time-range 中添加缩略图:
<video slot="media" src="video.mp4">
<track kind="metadata" label="thumbnails" src="thumbnails.vtt" default>
</video>
<media-time-range>
<media-preview-thumbnail slot="preview"></media-preview-thumbnail>
</media-time-range>
默认支持的快捷键:
Space/K - 播放/暂停M - 静音F - 全屏左右箭头 - 快进/快退 10 秒上下箭头 - 调整音量> / < - 增加/减少播放速度自定义快捷键:
<media-controller keyboardforwardseekoffset="15" keyboardbackwardseekoffset="5">
<!-- ... -->
</media-controller>
当需要创建自定义媒体控制组件时,参考项目源码中的现有组件实现:
MediaChromeButton、MediaChromeRange 等基类MediaUIEvents 和 MediaUIAttributes 常量observedAttributes 和相关 getter/setterassociateElement(this) 关联到 media-controller参考文件:
src/js/media-play-button.ts - 基础按钮组件src/js/media-time-range.ts - 进度条组件src/js/constants.ts - 事件和属性常量示例结构:
import { MediaChromeButton } from './media-chrome-button.js';
import { MediaUIEvents, MediaUIAttributes } from './constants.js';
import { globalThis } from './utils/server-safe-globals.js';
class MyCustomButton extends MediaChromeButton {
handleClick(): void {
const evt = new globalThis.CustomEvent(
MediaUIEvents.MEDIA_PLAY_REQUEST,
{
composed: true,
bubbles: true,
}
);
this.dispatchEvent(evt);
}
}
if (!globalThis.customElements.get('my-custom-button')) {
globalThis.customElements.define('my-custom-button', MyCustomButton);
}
组件通过派发事件与媒体元素通信:
media-play-request - 请求播放media-pause-request - 请求暂停media-mute-request - 请求静音media-unmute-request - 请求取消静音media-seek-request - 请求跳转时间media-fullscreen-request - 请求全屏media-airplay-request - 请求 AirPlaymedia-cast-request - 请求投屏通过 MediaUIAttributes 监听媒体状态:
media-paused - 是否暂停media-muted - 是否静音media-duration - 总时长media-current-time - 当前时间media-volume - 音量media-playing - 是否播放中# 安装依赖
npm install
# 清理构建
npm run clean
# 格式化代码
npm run format
# Lint 检查
npm run lint
# 类型检查
npm run build:types
# 构建 ESM
npm run build:esm
# 构建 CJS
npm run build:cjs
# 构建 IIFE
npm run build:iife:*
# 构建 React 包装器
npm run build:react
# 完整构建
npm run build
# 监听模式开发
npm run dev
# 运行测试
npm test
src/js/ - 源代码目录
media-*.ts - 各个组件的实现constants.ts - 常量定义utils/ - 工具函数media-store/ - 状态管理examples/ - 示例代码
vanilla/ - 原生 JS 示例nextjs-with-typescript/ - Next.js 示例vite-react-with-typescript/ - Vite + React 示例test/ - 测试文件docs/ - 文档文件src/js/ 创建组件文件(如 media-my-button.ts)MediaChromeButton、MediaChromeRange 等)src/js/index.ts 中导出组件test/examples/references/css-variables.md - CSS 变量完整列表examples/vanilla/basic.html - 基础示例examples/vanilla/advanced.html - 高级示例examples/vanilla/mobile.html - 移动端示例src/js/constants.ts - 常量定义A: 使用 CSS 隐藏不可用的控件:
media-airplay-button[mediaairplayunavailable] {
display: none;
}
A: 使用 slot 自定义图标:
<media-play-button>
<svg slot="icon" viewBox="0 0 24 24">
<!-- 自定义图标路径 -->
</svg>
</media-play-button>
A: 使用 CSS 容器查询或 breakpoint 属性:
<media-control-bar>
<media-play-button desktop></media-play-button>
<media-play-button mobile hidden></media-play-button>
</media-control-bar>
A: 支持所有现代浏览器(Chrome、Firefox、Safari、Edge),需要 Custom Elements 和 Shadow DOM 支持。
documentation
Use this skill any time a .pptx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx file (even if the extracted content will be used elsewhere, like in an email or summary); editing, modifying, or updating existing presentations; combining or splitting slide files; working with templates, layouts, speaker notes, or comments. Trigger whenever the user mentions "deck," "slides," "presentation," or references a .pptx filename, regardless of what they plan to do with the content afterward. If a .pptx file needs to be opened, created, or touched, use this skill.
development
Portless development server proxy that eliminates port conflicts by routing through localhost subdomains. Use when setting up development servers, managing multiple apps, avoiding port conflicts, or working with monorepos and turborepo projects.
content-media
Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text/tables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting/decrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.
development
MSW (Mock Service Worker) v2 最佳实践、模式和API指南,用于 JavaScript/TypeScript测试和开发中的API模拟。涵盖处理器 设计、服务器设置、响应构造、测试模式、GraphQL和 v1到v2迁移。基准版本:msw ^2.0.0。 触发条件:msw导入,http.get,http.post,HttpResponse,setupServer, setupWorker,graphql.query,提及"msw"、"mock service worker"、 "api mocking"或"msw v2"。