@mingxy/ocosay 1.1.4 → 1.1.6

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.
@@ -1,31 +1,41 @@
1
1
  /**
2
2
  * Naudiodon Backend - 基于 PortAudio 的跨平台音频播放后端
3
3
  * 支持真正的流式播放(边收边播)
4
+ *
5
+ * 注意:naudiodon v2 API 变化:
6
+ * - v1: new naudiodon({sampleRate, channels, bitDepth})
7
+ * - v2: AudioIO({outOptions: {sampleRate, channelCount, sampleFormat}})
4
8
  */
5
9
  import { AudioBackend, BackendOptions } from './base';
6
- interface NaudiodonAudioOutput {
10
+ interface IoStreamWrite {
7
11
  start(): void;
8
- write(chunk: Buffer): void;
12
+ write(chunk: Buffer, callback?: (err?: Error) => void): void;
9
13
  end(): void;
10
- quit(): void;
11
- on(event: string, callback: (error: Error) => void): void;
14
+ quit(callback?: () => void): void;
15
+ on(event: 'error', callback: (error: Error) => void): void;
16
+ on(event: 'close', callback: () => void): void;
17
+ }
18
+ interface AudioOptions {
19
+ sampleRate?: number;
20
+ channelCount?: number;
21
+ sampleFormat?: number;
12
22
  }
13
- interface Naudiodon {
14
- new (options: {
15
- sampleRate?: number;
16
- channels?: number;
17
- bitDepth?: number;
18
- }): NaudiodonAudioOutput;
23
+ interface AudioIO {
24
+ (options: {
25
+ outOptions: AudioOptions;
26
+ }): IoStreamWrite;
19
27
  }
20
28
  declare global {
21
29
  interface NodeModule {
22
- require(id: 'naudiodon'): Naudiodon;
30
+ require(id: 'naudiodon'): {
31
+ AudioIO: AudioIO;
32
+ };
23
33
  }
24
34
  }
25
35
  export declare class NaudiodonBackend implements AudioBackend {
26
36
  readonly name = "naudiodon";
27
37
  readonly supportsStreaming = true;
28
- private audioOutput?;
38
+ private audioStream?;
29
39
  private events?;
30
40
  private _started;
31
41
  private _paused;
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * Naudiodon Backend - 基于 PortAudio 的跨平台音频播放后端
3
3
  * 支持真正的流式播放(边收边播)
4
+ *
5
+ * 注意:naudiodon v2 API 变化:
6
+ * - v1: new naudiodon({sampleRate, channels, bitDepth})
7
+ * - v2: AudioIO({outOptions: {sampleRate, channelCount, sampleFormat}})
4
8
  */
5
9
  class UnsupportedError extends Error {
6
10
  constructor(message) {
@@ -11,7 +15,7 @@ class UnsupportedError extends Error {
11
15
  export class NaudiodonBackend {
12
16
  name = 'naudiodon';
13
17
  supportsStreaming = true;
14
- audioOutput;
18
+ audioStream;
15
19
  events;
16
20
  _started = false;
17
21
  _paused = false;
@@ -31,16 +35,17 @@ export class NaudiodonBackend {
31
35
  return;
32
36
  try {
33
37
  const naudiodon = require('naudiodon');
34
- const AudioOutput = naudiodon;
35
- this.audioOutput = new AudioOutput({
36
- sampleRate: this.sampleRate,
37
- channels: this.channels,
38
- bitDepth: 16
38
+ this.audioStream = naudiodon.AudioIO({
39
+ outOptions: {
40
+ sampleRate: this.sampleRate,
41
+ channelCount: this.channels,
42
+ sampleFormat: 16
43
+ }
39
44
  });
40
- this.audioOutput.on('error', (error) => {
45
+ this.audioStream.on('error', (error) => {
41
46
  this.handleError(error);
42
47
  });
43
- this.audioOutput.start();
48
+ this.audioStream.start();
44
49
  this._started = true;
45
50
  this._stopped = false;
46
51
  this.events?.onStart?.();
@@ -55,16 +60,16 @@ export class NaudiodonBackend {
55
60
  write(chunk) {
56
61
  if (!this._started || this._stopped)
57
62
  return;
58
- if (this.audioOutput) {
63
+ if (this.audioStream) {
59
64
  const adjustedChunk = this.adjustVolume(chunk);
60
- this.audioOutput.write(adjustedChunk);
65
+ this.audioStream.write(adjustedChunk);
61
66
  this.bytesWritten += chunk.length;
62
67
  this.events?.onProgress?.(this.bytesWritten);
63
68
  }
64
69
  }
65
70
  end() {
66
- if (this.audioOutput) {
67
- this.audioOutput.end();
71
+ if (this.audioStream) {
72
+ this.audioStream.end();
68
73
  }
69
74
  }
70
75
  pause() {
@@ -82,14 +87,14 @@ export class NaudiodonBackend {
82
87
  this._stopped = true;
83
88
  this._started = false;
84
89
  this._paused = false;
85
- if (this.audioOutput) {
90
+ if (this.audioStream) {
86
91
  try {
87
- this.audioOutput.quit();
92
+ this.audioStream.quit();
88
93
  }
89
94
  catch (e) {
90
95
  // 忽略退出错误
91
96
  }
92
- this.audioOutput = undefined;
97
+ this.audioStream = undefined;
93
98
  }
94
99
  this.bytesWritten = 0;
95
100
  this.events?.onStop?.();
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingxy/ocosay",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "OpenCode TTS 播放插件 - 支持豆包模式边接收边朗读",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",
@@ -48,7 +48,7 @@
48
48
  "zod": "^4.3.6"
49
49
  },
50
50
  "optionalDependencies": {
51
- "naudiodon": "^1.0.0"
51
+ "naudiodon": "^2.0.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/howler": "^2.2.12",
package/dist/plugin.js CHANGED
@@ -6750,7 +6750,7 @@ var UnsupportedError = class extends Error {
6750
6750
  var NaudiodonBackend = class {
6751
6751
  name = "naudiodon";
6752
6752
  supportsStreaming = true;
6753
- audioOutput;
6753
+ audioStream;
6754
6754
  events;
6755
6755
  _started = false;
6756
6756
  _paused = false;
@@ -6769,16 +6769,17 @@ var NaudiodonBackend = class {
6769
6769
  if (this._started) return;
6770
6770
  try {
6771
6771
  const naudiodon = __require("naudiodon");
6772
- const AudioOutput = naudiodon;
6773
- this.audioOutput = new AudioOutput({
6774
- sampleRate: this.sampleRate,
6775
- channels: this.channels,
6776
- bitDepth: 16
6772
+ this.audioStream = naudiodon.AudioIO({
6773
+ outOptions: {
6774
+ sampleRate: this.sampleRate,
6775
+ channelCount: this.channels,
6776
+ sampleFormat: 16
6777
+ }
6777
6778
  });
6778
- this.audioOutput.on("error", (error) => {
6779
+ this.audioStream.on("error", (error) => {
6779
6780
  this.handleError(error);
6780
6781
  });
6781
- this.audioOutput.start();
6782
+ this.audioStream.start();
6782
6783
  this._started = true;
6783
6784
  this._stopped = false;
6784
6785
  this.events?.onStart?.();
@@ -6791,16 +6792,16 @@ var NaudiodonBackend = class {
6791
6792
  }
6792
6793
  write(chunk) {
6793
6794
  if (!this._started || this._stopped) return;
6794
- if (this.audioOutput) {
6795
+ if (this.audioStream) {
6795
6796
  const adjustedChunk = this.adjustVolume(chunk);
6796
- this.audioOutput.write(adjustedChunk);
6797
+ this.audioStream.write(adjustedChunk);
6797
6798
  this.bytesWritten += chunk.length;
6798
6799
  this.events?.onProgress?.(this.bytesWritten);
6799
6800
  }
6800
6801
  }
6801
6802
  end() {
6802
- if (this.audioOutput) {
6803
- this.audioOutput.end();
6803
+ if (this.audioStream) {
6804
+ this.audioStream.end();
6804
6805
  }
6805
6806
  }
6806
6807
  pause() {
@@ -6816,12 +6817,12 @@ var NaudiodonBackend = class {
6816
6817
  this._stopped = true;
6817
6818
  this._started = false;
6818
6819
  this._paused = false;
6819
- if (this.audioOutput) {
6820
+ if (this.audioStream) {
6820
6821
  try {
6821
- this.audioOutput.quit();
6822
+ this.audioStream.quit();
6822
6823
  } catch (e) {
6823
6824
  }
6824
- this.audioOutput = void 0;
6825
+ this.audioStream = void 0;
6825
6826
  }
6826
6827
  this.bytesWritten = 0;
6827
6828
  this.events?.onStop?.();
@@ -9577,7 +9578,7 @@ function markNaudiodonSkipped() {
9577
9578
  }
9578
9579
  async function ensureNaudiodonCompiled() {
9579
9580
  if (shouldSkipNaudiodon()) {
9580
- logger7.info("naudiodon skipped previously, skipping compile attempt");
9581
+ logger7.info("naudiodon skipped previously");
9581
9582
  return;
9582
9583
  }
9583
9584
  try {
@@ -9585,12 +9586,12 @@ async function ensureNaudiodonCompiled() {
9585
9586
  logger7.info("naudiodon already compiled");
9586
9587
  return;
9587
9588
  } catch {
9588
- logger7.info("naudiodon not compiled, attempting to compile...");
9589
+ logger7.info("naudiodon not compiled, will attempt to compile");
9590
+ notificationService.info("\u6B63\u5728\u7F16\u8BD1 naudiodon...", "Ocosay \u97F3\u9891\u540E\u7AEF");
9589
9591
  }
9590
9592
  try {
9591
9593
  const naudiodonPath = dirname2(require2.resolve("naudiodon"));
9592
- logger7.info({ naudiodonPath }, "found naudiodon at");
9593
- notificationService.info("\u6B63\u5728\u7F16\u8BD1 naudiodon...", "Ocosay \u97F3\u9891\u540E\u7AEF");
9594
+ logger7.info({ naudiodonPath }, "found naudiodon, rebuilding");
9594
9595
  execSync("npm rebuild naudiodon", {
9595
9596
  cwd: naudiodonPath,
9596
9597
  stdio: "inherit"
@@ -9598,7 +9599,7 @@ async function ensureNaudiodonCompiled() {
9598
9599
  logger7.info("naudiodon compiled successfully");
9599
9600
  notificationService.success("naudiodon \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA");
9600
9601
  } catch (err) {
9601
- logger7.warn({ err }, "naudiodon rebuild failed, checking for PortAudio...");
9602
+ logger7.warn({ err }, "naudiodon rebuild failed, checking for PortAudio");
9602
9603
  notificationService.warning("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u6B63\u5728\u5C1D\u8BD5\u5B89\u88C5 PortAudio...");
9603
9604
  const installed = installPortAudio();
9604
9605
  if (installed) {
@@ -9612,12 +9613,13 @@ async function ensureNaudiodonCompiled() {
9612
9613
  logger7.info("naudiodon compiled successfully after PortAudio install");
9613
9614
  notificationService.success("naudiodon \u7F16\u8BD1\u6210\u529F", "\u97F3\u9891\u540E\u7AEF\u5DF2\u5C31\u7EEA");
9614
9615
  } catch (retryErr) {
9615
- logger7.error({ err: retryErr }, "failed to compile naudiodon even after PortAudio install");
9616
- notificationService.error("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u5DF2\u8DF3\u8FC7\uFF0C\u4E4B\u540E\u4E0D\u518D\u91CD\u8BD5");
9616
+ logger7.error({ err: retryErr }, "naudiodon compile failed even after PortAudio install");
9617
+ notificationService.error("naudiodon \u7F16\u8BD1\u5931\u8D25", "\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u5C1D\u8BD5\u624B\u52A8\u5B89\u88C5");
9617
9618
  markNaudiodonSkipped();
9618
9619
  }
9619
9620
  } else {
9620
- notificationService.error("PortAudio \u5B89\u88C5\u5931\u8D25", "\u5DF2\u8DF3\u8FC7\uFF0C\u4E4B\u540E\u4E0D\u518D\u91CD\u8BD5");
9621
+ logger7.error("PortAudio install failed");
9622
+ notificationService.error("PortAudio \u5B89\u88C5\u5931\u8D25", "\u81EA\u52A8\u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u5C1D\u8BD5\u624B\u52A8\u5B89\u88C5");
9621
9623
  markNaudiodonSkipped();
9622
9624
  }
9623
9625
  }
@@ -9771,7 +9773,6 @@ var server = (async (input, _options) => {
9771
9773
  const opencodeTui = input.client?.tui;
9772
9774
  global.__opencode_tui__ = opencodeTui;
9773
9775
  notificationService.setTui(opencodeTui);
9774
- await ensureNaudiodonCompiled();
9775
9776
  const config = loadOrCreateConfig();
9776
9777
  try {
9777
9778
  await initialize({
@@ -9788,6 +9789,7 @@ var server = (async (input, _options) => {
9788
9789
  initError = err instanceof Error ? err : new Error(String(err));
9789
9790
  logger7.error({ error: initError }, "initialization failed");
9790
9791
  }
9792
+ await ensureNaudiodonCompiled();
9791
9793
  setTimeout(() => {
9792
9794
  if (initError) {
9793
9795
  notificationService.error(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingxy/ocosay",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "OpenCode TTS 播放插件 - 支持豆包模式边接收边朗读",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",
@@ -48,7 +48,7 @@
48
48
  "zod": "^4.3.6"
49
49
  },
50
50
  "optionalDependencies": {
51
- "naudiodon": "^1.0.0"
51
+ "naudiodon": "^2.0.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/howler": "^2.2.12",