@mingxy/ocosay 1.1.32 → 1.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ import { HowlerBackend } from './howler-backend';
18
18
  import { PlaySoundBackend } from './playsound-backend';
19
19
  import { SpeakerBackend } from './speaker-backend';
20
20
  import { logger } from '../../utils/logger';
21
+ import { notificationService } from '../notification';
21
22
  function execCmd(cmd) {
22
23
  try {
23
24
  const output = execSync(cmd, { stdio: 'pipe', encoding: 'utf8' });
@@ -97,6 +98,7 @@ export function createBackend(type = BackendType.AUTO, options = {}) {
97
98
  }
98
99
  catch (err) {
99
100
  logger.error({ err }, 'failed to initialize naudiodon backend');
101
+ notificationService.warning('naudiodon 初始化失败', '将使用其他音频后端', 5000);
100
102
  }
101
103
  }
102
104
  switch (platform) {
@@ -24,7 +24,7 @@ export declare class PlaySoundBackend implements AudioBackend {
24
24
  private chunks;
25
25
  private hasEnded;
26
26
  constructor(options?: BackendOptions);
27
- start(filePath: string): void;
27
+ start(filePath: string): Promise<void>;
28
28
  private playWithPlaySound;
29
29
  write(chunk: Buffer): void;
30
30
  end(): void;
@@ -32,7 +32,7 @@ export class PlaySoundBackend {
32
32
  constructor(options = {}) {
33
33
  this.events = options.events;
34
34
  }
35
- start(filePath) {
35
+ async start(filePath) {
36
36
  if (this._started)
37
37
  return;
38
38
  if (!SAFE_PATH_REGEX.test(filePath)) {
@@ -42,8 +42,8 @@ export class PlaySoundBackend {
42
42
  this._started = true;
43
43
  this._stopped = false;
44
44
  this.events?.onStart?.();
45
- // 动态导入 play-sound
46
- this.playWithPlaySound(filePath);
45
+ // 等待 play-sound 播放完成
46
+ await this.playWithPlaySound(filePath);
47
47
  }
48
48
  async playWithPlaySound(filePath) {
49
49
  try {
@@ -120,11 +120,8 @@ export class AudioPlayer extends EventEmitter {
120
120
  * 播放音频文件
121
121
  * 使用 AudioBackend 统一后端播放
122
122
  */
123
- playFile(filePath, _format) {
124
- return new Promise((resolve) => {
125
- this.backend.start(filePath);
126
- resolve(); // backend.start() 是同步的,立即 resolve
127
- });
123
+ async playFile(filePath, _format) {
124
+ await this.backend.start(filePath);
128
125
  }
129
126
  pause() {
130
127
  if (!this._playing || this._paused)
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingxy/ocosay",
3
- "version": "1.1.31",
3
+ "version": "1.1.32",
4
4
  "description": "OpenCode TTS 播放插件 - 支持豆包模式边接收边朗读",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",
package/dist/plugin.js CHANGED
@@ -7487,7 +7487,7 @@ var PlaySoundBackend = class {
7487
7487
  constructor(options = {}) {
7488
7488
  this.events = options.events;
7489
7489
  }
7490
- start(filePath) {
7490
+ async start(filePath) {
7491
7491
  if (this._started) return;
7492
7492
  if (!SAFE_PATH_REGEX4.test(filePath)) {
7493
7493
  throw new Error(`Invalid file path: ${filePath}`);
@@ -7496,7 +7496,7 @@ var PlaySoundBackend = class {
7496
7496
  this._started = true;
7497
7497
  this._stopped = false;
7498
7498
  this.events?.onStart?.();
7499
- this.playWithPlaySound(filePath);
7499
+ await this.playWithPlaySound(filePath);
7500
7500
  }
7501
7501
  async playWithPlaySound(filePath) {
7502
7502
  try {
@@ -7767,6 +7767,81 @@ var SpeakerBackend = class {
7767
7767
 
7768
7768
  // src/core/backends/index.ts
7769
7769
  import { execSync } from "child_process";
7770
+
7771
+ // src/core/notification.ts
7772
+ var logger3 = createModuleLogger("NotificationService");
7773
+ var NotificationService = class {
7774
+ tui = null;
7775
+ pendingToasts = [];
7776
+ retryTimer;
7777
+ setTui(tui) {
7778
+ this.tui = tui;
7779
+ logger3.debug("tui reference set");
7780
+ this.flushPending();
7781
+ }
7782
+ showToast(options) {
7783
+ const { title, message, variant = "info", duration = 5e3 } = options;
7784
+ if (!this.tui) {
7785
+ logger3.debug({ title }, "tui not ready, queueing toast");
7786
+ this.pendingToasts.push(options);
7787
+ this.scheduleRetry();
7788
+ return false;
7789
+ }
7790
+ try {
7791
+ this.tui.showToast({
7792
+ body: {
7793
+ title,
7794
+ message,
7795
+ variant,
7796
+ duration
7797
+ }
7798
+ });
7799
+ logger3.debug({ title, variant }, "toast shown");
7800
+ return true;
7801
+ } catch (err) {
7802
+ logger3.warn({ err, title }, "toast call failed, queueing for retry");
7803
+ this.pendingToasts.push(options);
7804
+ this.scheduleRetry();
7805
+ return false;
7806
+ }
7807
+ }
7808
+ scheduleRetry() {
7809
+ if (this.retryTimer) return;
7810
+ this.retryTimer = setTimeout(() => {
7811
+ this.retryTimer = void 0;
7812
+ this.flushPending();
7813
+ }, 2e3);
7814
+ }
7815
+ flushPending() {
7816
+ if (this.pendingToasts.length === 0 || !this.tui) return;
7817
+ logger3.info({ count: this.pendingToasts.length }, "flushing pending toasts");
7818
+ const pending = [...this.pendingToasts];
7819
+ this.pendingToasts = [];
7820
+ for (const toast of pending) {
7821
+ try {
7822
+ this.showToast(toast);
7823
+ } catch (err) {
7824
+ this.pendingToasts.push(toast);
7825
+ logger3.warn({ err }, "showToast threw unexpected error, re-queued");
7826
+ }
7827
+ }
7828
+ }
7829
+ success(title, message, duration) {
7830
+ return this.showToast({ title, message, variant: "success", duration });
7831
+ }
7832
+ error(title, message, duration) {
7833
+ return this.showToast({ title, message, variant: "error", duration });
7834
+ }
7835
+ info(title, message, duration) {
7836
+ return this.showToast({ title, message, variant: "info", duration });
7837
+ }
7838
+ warning(title, message, duration) {
7839
+ return this.showToast({ title, message, variant: "warning", duration });
7840
+ }
7841
+ };
7842
+ var notificationService = new NotificationService();
7843
+
7844
+ // src/core/backends/index.ts
7770
7845
  function execCmd(cmd) {
7771
7846
  try {
7772
7847
  const output = execSync(cmd, { stdio: "pipe", encoding: "utf8" });
@@ -7813,6 +7888,11 @@ function createBackend(type = "auto" /* AUTO */, options = {}) {
7813
7888
  }
7814
7889
  } catch (err) {
7815
7890
  logger.error({ err }, "failed to initialize naudiodon backend");
7891
+ notificationService.warning(
7892
+ "naudiodon \u521D\u59CB\u5316\u5931\u8D25",
7893
+ "\u5C06\u4F7F\u7528\u5176\u4ED6\u97F3\u9891\u540E\u7AEF",
7894
+ 5e3
7895
+ );
7816
7896
  }
7817
7897
  }
7818
7898
  switch (platform) {
@@ -7966,11 +8046,8 @@ var AudioPlayer = class extends EventEmitter {
7966
8046
  * 播放音频文件
7967
8047
  * 使用 AudioBackend 统一后端播放
7968
8048
  */
7969
- playFile(filePath, _format) {
7970
- return new Promise((resolve) => {
7971
- this.backend.start(filePath);
7972
- resolve();
7973
- });
8049
+ async playFile(filePath, _format) {
8050
+ await this.backend.start(filePath);
7974
8051
  }
7975
8052
  pause() {
7976
8053
  if (!this._playing || this._paused) return;
@@ -8016,79 +8093,6 @@ var AudioPlayer = class extends EventEmitter {
8016
8093
  }
8017
8094
  };
8018
8095
 
8019
- // src/core/notification.ts
8020
- var logger3 = createModuleLogger("NotificationService");
8021
- var NotificationService = class {
8022
- tui = null;
8023
- pendingToasts = [];
8024
- retryTimer;
8025
- setTui(tui) {
8026
- this.tui = tui;
8027
- logger3.debug("tui reference set");
8028
- this.flushPending();
8029
- }
8030
- showToast(options) {
8031
- const { title, message, variant = "info", duration = 5e3 } = options;
8032
- if (!this.tui) {
8033
- logger3.debug({ title }, "tui not ready, queueing toast");
8034
- this.pendingToasts.push(options);
8035
- this.scheduleRetry();
8036
- return false;
8037
- }
8038
- try {
8039
- this.tui.showToast({
8040
- body: {
8041
- title,
8042
- message,
8043
- variant,
8044
- duration
8045
- }
8046
- });
8047
- logger3.debug({ title, variant }, "toast shown");
8048
- return true;
8049
- } catch (err) {
8050
- logger3.warn({ err, title }, "toast call failed, queueing for retry");
8051
- this.pendingToasts.push(options);
8052
- this.scheduleRetry();
8053
- return false;
8054
- }
8055
- }
8056
- scheduleRetry() {
8057
- if (this.retryTimer) return;
8058
- this.retryTimer = setTimeout(() => {
8059
- this.retryTimer = void 0;
8060
- this.flushPending();
8061
- }, 2e3);
8062
- }
8063
- flushPending() {
8064
- if (this.pendingToasts.length === 0 || !this.tui) return;
8065
- logger3.info({ count: this.pendingToasts.length }, "flushing pending toasts");
8066
- const pending = [...this.pendingToasts];
8067
- this.pendingToasts = [];
8068
- for (const toast of pending) {
8069
- try {
8070
- this.showToast(toast);
8071
- } catch (err) {
8072
- this.pendingToasts.push(toast);
8073
- logger3.warn({ err }, "showToast threw unexpected error, re-queued");
8074
- }
8075
- }
8076
- }
8077
- success(title, message, duration) {
8078
- return this.showToast({ title, message, variant: "success", duration });
8079
- }
8080
- error(title, message, duration) {
8081
- return this.showToast({ title, message, variant: "error", duration });
8082
- }
8083
- info(title, message, duration) {
8084
- return this.showToast({ title, message, variant: "info", duration });
8085
- }
8086
- warning(title, message, duration) {
8087
- return this.showToast({ title, message, variant: "warning", duration });
8088
- }
8089
- };
8090
- var notificationService = new NotificationService();
8091
-
8092
8096
  // src/core/speaker.ts
8093
8097
  var logger4 = createModuleLogger("Speaker");
8094
8098
  var Speaker2 = class extends EventEmitter2 {
@@ -10128,6 +10132,7 @@ async function ensurePlaySoundInstalled() {
10128
10132
  if (isModuleInstalled(dep)) {
10129
10133
  logger8.info("play-sound already installed");
10130
10134
  if (await verifyModuleLoad(dep)) {
10135
+ notificationService.success("play-sound \u5DF2\u5C31\u7EEA", "\u97F3\u9891\u540E\u7AEF\u6B63\u5E38", 5e3);
10131
10136
  return;
10132
10137
  }
10133
10138
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingxy/ocosay",
3
- "version": "1.1.32",
3
+ "version": "1.1.33",
4
4
  "description": "OpenCode TTS 播放插件 - 支持豆包模式边接收边朗读",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",