# @ctrl/plex 中文文档

规范地址：https://npmcn.com/package/%40ctrl/plex/

版本：8\.0\.0
npm 元数据更新时间：2026-10-16T04:09:51.211Z
中文译文更新时间：2026-11-13T06:28:32.605Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40ctrl/plex
原文对照：https://npmcn.com/package/%40ctrl/plex/?lang=original
项目主页：https://github.com/scttcper/plex#readme
源码仓库：https://github.com/scttcper/plex

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：734 kB，107 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=24
- 运行依赖：4 个
- 首次发布：2020-07-26T01:28:13.692Z
- 最新版本发布：2026-10-16T04:09:50.874Z
- 近 30 天下载量：2155（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：51（近 12 个月 25 个）

## 中文简介

在打字符中使用 Plex api 客户端

## 安装

```sh
npm install @ctrl/plex
```

也可以使用：`pnpm add @ctrl/plex`、`yarn add @ctrl/plex`、`bun add @ctrl/plex`

## README

# @ ctrl/ 复杂 [![npm](https://badgen.net/npm/v/@ctrl/plex)](https://www.npmjs.com/package/@ctrl/plex)

> 类型脚本 [缩写](https://www.plex.tv/) 使用 API 客户端 [函数](https://github.com/unjs/ofetch) 基于 [pkkid/python-plexapi (英语)](https://github.com/pushingkarmaorg/python-plexapi)

### 安装

```console
npm install @ctrl/plex
```

### 文档

[https://plex.ep. works.dev (中文(简体) )](https://plex.ep.workers.dev/)

### 使用

创建复式连接

```ts
import { MyPlexAccount } from '@ctrl/plex';

const account = await new MyPlexAccount({
  baseUrl: 'http://localhost:32400',
  // Use username and password based auth
  username: 'username',
  password: 'password',
  // OR Token based auth
  token: 'token',
}).connect();

// List all available servers (resources) attached to your account
const resources = await account.resources();

// Connect to a specific server by name
// You can find the server name in the Plex Web UI settings or by listing resources above
const resource = await account.resource('<SERVERNAME>');
const plex = await resource.connect();
const library = await plex.library();

// List all libraries (Movies, TV Shows, Music, etc.)
const sections = await library.sections();
```

识别您的应用程序。 Plex 按其产品名称和客户身份标识列出每个客户端, 因此设置 在连接和坚持标识符之前,您自己可以使用,所以Plex不断看到同一设备.

```ts
import { setPlexHeaders } from '@ctrl/plex';

setPlexHeaders({
  product: 'My App',
  version: '1.0.0',
  identifier: 'replace-with-a-persisted-client-identifier',
});
```

不收集 Plex 用户名或密码而认证 。 坚持客户端标识符,所以 整个登录点保持稳定.

```ts
import { MyPlexAccount, MyPlexPinLogin } from '@ctrl/plex';

const clientIdentifier = 'replace-with-a-persisted-client-identifier';
const login = await MyPlexPinLogin.create({ clientIdentifier, mode: 'oauth' });

console.log(`Open ${login.oauthUrl()} to sign in`);

const authentication = await login.wait({ timeout: 120_000 });
const account = await new MyPlexAccount({ token: authentication.token }).connect();
```

创建并刷新已签名的 Plex JWT 。 靴子纹章一定是为同一个 客户端标识符 。 安全存储返回的证书; 它们包含私人签名密钥 .

```ts
import { MyPlexAccount, refreshPlexJwt, registerPlexJwt } from '@ctrl/plex';

let credentials = await registerPlexJwt({
  token: authentication.token,
  clientIdentifier,
  scopes: ['username', 'email', 'friendly_name'],
});

credentials = await refreshPlexJwt({ credentials });
const jwtAccount = await new MyPlexAccount({ token: credentials.token }).connect();
```

###### 例1:列出所有未观看的电影.

```ts
import { MovieSection } from '@ctrl/plex';

// Pass MovieSection generic because the section title doesn't imply a section type.
const section = await library.section<MovieSection>('Movies');
// Get an array of Movie objects
const results = await section.search({ unwatched: true });
```

###### 例2:搜索包含标题的电影列表

```ts
const library = await plex.library();
const section = await library.section<MovieSection>('Movies');
const results = await section.search({ title: 'Rush Hour' });
```

###### 例3:列出所有包含特定查询的内容

```ts
const hubs = await plex.search('Arnold');
// Each hub is one category of results (movies, episodes, actors, ...)
for (const hub of hubs) {
  const [first] = await hub.items();
  console.log(hub.title, first?.title);
}
```

###### 例4:列出tv节目的所有剧集.

```ts
import { ShowSection } from '@ctrl/plex';

// Pass ShowSection generic because the section title doesn't imply a section type.
const section = await library.section<ShowSection>('TV Shows');
// Get an array of Show objects
const results = await section.search({ title: 'Silicon Valley' });
const episodes = await results[0].episodes();
```

###### 例5:根据搜索结果创建播放列表

```ts
import { Playlist } from '@ctrl/plex';

// The ten highest rated movies
const topMovies = await section.search({ sort: 'rating:desc', maxresults: 10 });

// Create a new playlist
const bestMovies = await Playlist.create(plex, 'Best Movies', { items: topMovies });
```

### 从 v7 升级

v8是大型发布. 完整列表在发布注释中,最有可能影响您的变化:

-   需要24号节点或更新.
-   类型很严格: 字段Plex可以省略是可选的,以及 `PlexServer.query()` 编号 : `MyPlexAccount.query()` 返回时 `unknown` 除非你通过一个类型争论.
-   位置参数成为选项对象, 例如 `connect({ timeout })`, (中文(简体) ), `removeItem(item, { refresh })`, (中文(简体) ), `updateProgress({ time })` 财务报告和审定财务报表 `account.device({ name })`。 。 。 .
-   `PlexClient` 命令带走 `{ type }` 而不是立场 `mtype`,以及 `proxyThroughServer({ server })` 替换 `_server` 编号 : `_proxyThroughServer` 字段.
-   音乐段落默认列出艺术家列表 `onDeck()` 返回事件和音轨.
-   音频 `art` 财务报告和审定财务报表 `thumb` 是服务器路径, 使用 `artUrl` 编号 : `thumbUrl` 用于符号 URL.
-   plex.tv设备来自JSON API, `MyPlexDevice.id` 是一个数字.

### 与 python 复杂客户端的差异

联合来文是另一种语言,因此不可能采用某些方法. 必须主要单独等待与请求挂钩的功能。 JS的建筑师通常不会提出要求 并且访问属性通常也不能提出请求。 方法选择对象而不是蟒蛇样式 关键词参数和答复作为JSON请求.

### 测试

测试是针对一个真正的复杂情况进行的.

创建一个复杂的账户仅用于测试,使用一个真实账户会打破一切. 将其全权证书放入 `.env` 文件在 repo 的根部,测试和脚本自动加载.

```sh
PLEX_USERNAME=email
PLEX_PASSWORD=password
PLEXAPI_AUTH_SERVER_TOKEN=token
```

设置测试内容( 一次)

```sh
pnpm run add-media
```

运行测试

```sh
pnpm test
```

后测试, 从账户中删除 plex 服务器 。 警告,这是破坏性的。 不要在真实的复杂账户上使用它.

```sh
pnpm run test-cleanup
```

### 正在本地测试

#### 步骤1

从 [https://www.plex.tv/claim/ (中文(简体) )](https://www.plex.tv/claim/) 导出 PLEQCLAIM TOKEN = 声明脚本

#### 步骤2

启动复方容器进行测试。 替换 `/Users/scooper/gh/plex` 带有此 repo 目录的路径.

```console
docker run -d \
  --name=plex \
  --net=host \
  -h orbstack \
  -p 32400:32400/tcp \
  -p 32400:32400 \
  -p 1900:1900/udp \
  -p 5353:5353/udp \
  -p 8324:8324 \
  -p 32410:32410/udp \
  -p 32412:32412/udp \
  -p 32413:32413/udp \
  -p 32414:32414/udp \
  -p 32469:32469 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Etc/UTC \
  -e VERSION=docker \
  -e PLEX_CLAIM=$PLEX_CLAIM_TOKEN \
  -v /Users/scooper/gh/plex/plex/media/db:/config \
  -v /Users/scooper/gh/plex/plex/media/transcode:/transcode \
  -v /Users/scooper/gh/plex/plex/media:/data \
  --restart unless-stopped \
  lscr.io/linuxserver/plex:latest
```

必要时拉出最新的复方容器

```console
docker pull lscr.io/linuxserver/plex:latest
```

有测试介质的靴子复合服务器 。 这个用 `PLEXAPI_AUTH_SERVER_TOKEN` 从 `.env`。 。 。 .

```console
pnpm run bootstraptest -- --no-docker --server-name=orbstack
```

## 常见问题

### @ctrl/plex 是什么？

在打字符中使用 Plex api 客户端

### 如何安装 @ctrl/plex？

在项目目录运行 npm install @ctrl/plex，或使用 pnpm add / yarn add / bun add。

### @ctrl/plex 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @ctrl/plex 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @ctrl/plex 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=24。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @ctrl/plex 可以商用吗？

@ctrl/plex 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @ctrl/plex 的下载量有多少？

根据 npm 官方下载统计，@ctrl/plex 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,155 次，日均约 72 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @ctrl/plex 还在维护吗？

最新版本 8\.0\.0 发布于 2026/10/16（28 天前）；至今共发布 51 个版本，其中过去 12 个月发布了 25 个；首次发布于 2020/07/26。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

