pear-desktop:Pear 🍐 is extension for music player

Pear 🍐 is extension for music player

分支14Tags94
文件最后提交记录最后更新时间
4 个月前
3 天前
4 个月前
3 天前
3 天前
4 小时前
5 个月前
3 天前
3 天前
8 个月前
2 年前
3 年前
4 个月前
8 天前
3 天前
3 个月前
3 天前
3 天前
5 天前
8 个月前
3 天前
3 天前
7 天前
1 年前
2 个月前
5 个月前

🍐 Pear Desktop

GitHub release GitHub license eslint code style Build status GitHub All Releases

Known Vulnerabilities

  • 原生外观与体验扩展

Important

⚠️ 免责声明

无关联声明

本项目及其贡献者与 Google LLC、YouTube 及其任何子公司或关联公司均无关联、未获授权、未被认可,也无任何官方联系。这是一个由志愿者团队开发的独立、非盈利且非官方的扩展,旨在提供桌面端使用体验。

商标声明

“Google”和“YouTube Music”等相关名称、标识、徽章及图像均为其各自所有者的注册商标。使用这些商标仅为识别和参考目的,不暗示与商标持有人有任何关联。我们无意侵犯这些商标权或对商标持有人造成损害。

责任限制

本应用程序(扩展)按“现状”提供,您使用本程序的风险由您自行承担。在任何情况下,开发者或贡献者均不对因使用本软件或与本软件相关的任何索赔、损害或其他责任(包括任何法律后果)承担责任。使用本软件所产生的任何及所有结果的责任完全由用户承担。

内容

翻译

您可以通过 Hosted Weblate 协助进行翻译工作。

translation status translation status 2

下载

您可以查看 最新发布版本 以快速找到最新版本。

Arch Linux

从 AUR 安装 pear-desktop 软件包。有关 AUR 安装说明,请查看此 维基页面

Solus

sudo eopkg install pear-desktop

macOS

您可以使用 Homebrew 安装该应用(请参阅 cask 定义):

brew install pear-devs/pear/pear-desktop

如果您手动安装应用程序,启动时遇到“已损坏,无法打开”的错误,请在终端中运行以下命令:

/usr/bin/xattr -cr /Applications/Pear\ Desktop.app

Windows

您可以使用 Scoop 包管理器extras 软件源 安装 pear-desktop 软件包。

scoop bucket add extras
scoop install extras/pear-desktop

或者,你可以使用 Winget——Windows 11 的官方命令行程序包管理器来安装 pear-devs.pear-desktop 包。

注意:由于该程序来自“未知发布者”,Microsoft Defender SmartScreen 可能会阻止安装。在 GitHub 上手动下载后尝试运行可执行文件(.exe)进行手动安装时,也会出现同样的情况(文件相同)。

winget install pear-devs.pear-desktop

如何在无网络连接的情况下安装?(Windows 系统)

  • 发布页面 下载适用于您设备架构*.nsis.7z 文件。
    • 64 位 Windows 系统选择 x64
    • 32 位 Windows 系统选择 ia32
    • ARM64 Windows 系统选择 arm64
  • 在发布页面下载安装程序(*-Setup.exe)。
  • 将它们放在同一目录下。
  • 运行安装程序。

主题

您可以加载 CSS 文件来更改应用程序的外观(选项 > 视觉调整 > 主题)。

部分预定义主题可在 https://github.com/kerichdev/themes-for-ytmdesktop-player 获取。

开发

git clone https://github.com/pear-devs/pear-desktop
cd pear-desktop
pnpm install --frozen-lockfile
pnpm dev

除了在系统上安装 pnpm,你也可以使用 devcontainers。你可以将 devcontainers 用作 VS Code 中的开发环境,或者作为一种无需在主机系统上安装依赖即可轻松构建项目的方式。

请注意,这有其自身的限制(例如,至少在某些 Linux 主机上,GUI 无法正常工作)。

构建你自己的插件

通过插件,你可以:

  • 操控应用程序 - electron 的 BrowserWindow 会传递给插件处理程序
  • 通过操作 HTML/CSS 来更改前端

创建插件

src/plugins/YOUR-PLUGIN-NAME 中创建一个文件夹:

  • index.ts:插件的主文件
import style from './style.css?inline'; // import style as inline

import { createPlugin } from '@/utils';

export default createPlugin({
  name: 'Plugin Label',
  restartNeeded: true, // if value is true, ytmusic show restart dialog
  config: {
    enabled: false,
  }, // your custom config
  stylesheets: [style], // your custom style,
  menu: async ({ getConfig, setConfig }) => {
    // All *Config methods are wrapped Promise<T>
    const config = await getConfig();
    return [
      {
        label: 'menu',
        submenu: [1, 2, 3].map((value) => ({
          label: `value ${value}`,
          type: 'radio',
          checked: config.value === value,
          click() {
            setConfig({ value });
          },
        })),
      },
    ];
  },
  backend: {
    start({ window, ipc }) {
      window.maximize();

      // you can communicate with renderer plugin
      ipc.handle('some-event', () => {
        return 'hello';
      });
    },
    // it fired when config changed
    onConfigChange(newConfig) { /* ... */ },
    // it fired when plugin disabled
    stop(context) { /* ... */ },
  },
  renderer: {
    async start(context) {
      console.log(await context.ipc.invoke('some-event'));
    },
    // Only renderer available hook
    onPlayerApiReady(api, context) {
      // set plugin config easily
      context.setConfig({ myConfig: api.getVolume() });
    },
    onConfigChange(newConfig) { /* ... */ },
    stop(_context) { /* ... */ },
  },
  preload: {
    async start({ getConfig }) {
      const config = await getConfig();
    },
    onConfigChange(newConfig) {},
    stop(_context) {},
  },
});

常见使用场景

  • 注入自定义 CSS:在同一文件夹中创建一个 style.css 文件,然后:
// index.ts
import style from './style.css?inline'; // import style as inline

import { createPlugin } from '@/utils';

export default createPlugin({
  name: 'Plugin Label',
  restartNeeded: true, // if value is true, pear-desktop will show a restart dialog
  config: {
    enabled: false,
  }, // your custom config
  stylesheets: [style], // your custom style
  renderer() {} // define renderer hook
});
  • 如果你想更改 HTML:
import { createPlugin } from '@/utils';

export default createPlugin({
  name: 'Plugin Label',
  restartNeeded: true, // if value is true, ytmusic will show the restart dialog
  config: {
    enabled: false,
  }, // your custom config
  renderer() {
    console.log('hello from renderer');
  } // define renderer hook
});
  • 前后端通信:可通过 electron 的 ipcMain 模块实现。详见 index.ts 文件及 sponsorblock 插件中的示例。

构建

  1. 克隆仓库
  2. 按照 此指南 安装 pnpm
  3. 运行 pnpm install --frozen-lockfile 安装依赖
  4. 运行 pnpm build:OS
  • pnpm dist:win - Windows 系统
  • pnpm dist:linux - Linux 系统(amd64)
  • pnpm dist:linux:deb-arm64 - Linux 系统(适用于 Debian 的 arm64)
  • pnpm dist:linux:rpm-arm64 - Linux 系统(适用于 Fedora 的 arm64)
  • pnpm dist:mac - macOS 系统(amd64)
  • pnpm dist:mac:arm64 - macOS 系统(arm64)

使用 electron-builder 为 macOS、Linux 和 Windows 系统构建应用。

在开发容器中构建

  1. 克隆仓库;
  2. 在 VS Code 中打开文件夹;
  3. 出现提示时,在容器中重新打开;
  4. 按上述步骤运行 pnpm build(选择所需目标);
  5. dist 文件夹中收集构建文件。

由于开发容器使用工作区挂载,因此构建文件也会在主机系统中可用。

生产环境预览

pnpm start

测试

pnpm test

使用 Playwright 测试应用程序。

许可协议

MIT © pear-devs

常见问题

为什么应用菜单没有显示?

如果“隐藏菜单”选项已开启,您可以使用 alt 键显示菜单(如果使用应用内菜单插件,则使用 ` [反引号])。