|
1 | 1 | import { debug } from './common'; |
| 2 | +import { spawnSync, spawn } from 'child_process'; |
2 | 3 |
|
3 | 4 | type Command = { |
4 | 5 | cmd: string; |
@@ -52,28 +53,38 @@ const findDefaultAudioPlayer_ = (): Command | null => { |
52 | 53 | for (const player of commonPlayers) { |
53 | 54 | const checkCmd = isWindows ? 'where' : 'which'; |
54 | 55 | try { |
55 | | - Bun.spawnSync([checkCmd, player.cmd]); |
| 56 | + spawnSync(checkCmd, [player.cmd]); |
56 | 57 | return player; // found! |
57 | 58 | } catch {} |
58 | 59 | } |
59 | 60 |
|
60 | 61 | return null; |
61 | 62 | }; |
62 | 63 |
|
63 | | -export const playAudioFile = async ( |
64 | | - path: string, |
65 | | - customCommand: string | null |
66 | | -): Promise<unknown> => { |
| 64 | +export const playAudioFile = async (path: string, customCommand: string | null) => { |
67 | 65 | const command = ensureAudioPlayer( |
68 | 66 | customCommand ? parseCustomCommand(customCommand) : findDefaultAudioPlayer() |
69 | 67 | ); |
70 | 68 | const isWindows = process.platform === 'win32'; |
71 | 69 | const sanitizedPath = isWindows ? path.replace(/\\/g, '\\\\') : path; |
72 | 70 |
|
73 | | - return Bun.spawn([command.cmd, ...command.argsWithPath(sanitizedPath)], { |
74 | | - stdout: 'ignore', |
75 | | - stderr: 'ignore', |
76 | | - }).exited; |
| 71 | + return new Promise<void>((resolve, reject) => { |
| 72 | + const process = spawn(command.cmd, [...command.argsWithPath(sanitizedPath)], { |
| 73 | + stdio: ['ignore', 'ignore', 'ignore'], |
| 74 | + }); |
| 75 | + |
| 76 | + process.on('close', (code: number) => { |
| 77 | + if (code === 0) { |
| 78 | + resolve(); |
| 79 | + } else { |
| 80 | + reject(new Error(`Process exited with code ${code}`)); |
| 81 | + } |
| 82 | + }); |
| 83 | + |
| 84 | + process.on('error', (err: any) => { |
| 85 | + reject(err); |
| 86 | + }); |
| 87 | + }); |
77 | 88 | }; |
78 | 89 |
|
79 | 90 | export const parseCustomCommand = (command: string): Command => { |
@@ -114,17 +125,30 @@ export const withStdinAudioPlayer = async ( |
114 | 125 | const command = ensureStdinSupport( |
115 | 126 | ensureAudioPlayer(customCommand ? parseCustomCommand(customCommand) : findDefaultAudioPlayer()) |
116 | 127 | ); |
117 | | - |
118 | 128 | debug([command.cmd, command.argsWithStdin]); |
119 | | - const proc = Bun.spawn([command.cmd, ...command.argsWithStdin], { |
120 | | - stdout: 'ignore', |
121 | | - stderr: 'ignore', |
122 | | - stdin: 'pipe', |
| 129 | + |
| 130 | + const { spawn } = require('child_process'); |
| 131 | + const proc = spawn(command.cmd, [...command.argsWithStdin], { |
| 132 | + stdio: ['pipe', 'ignore', 'ignore'], |
123 | 133 | }); |
124 | 134 |
|
125 | | - await f((audioBuffer: Buffer) => { |
| 135 | + await f((audioBuffer) => { |
126 | 136 | proc.stdin.write(audioBuffer); |
127 | 137 | }); |
| 138 | + |
128 | 139 | proc.stdin.end(); |
129 | | - await proc.exited; |
| 140 | + |
| 141 | + return new Promise((resolve, reject) => { |
| 142 | + proc.on('close', (code: number) => { |
| 143 | + if (code === 0) { |
| 144 | + resolve(); |
| 145 | + } else { |
| 146 | + reject(new Error(`Process exited with code ${code}`)); |
| 147 | + } |
| 148 | + }); |
| 149 | + |
| 150 | + proc.on('error', (err: any) => { |
| 151 | + reject(err); |
| 152 | + }); |
| 153 | + }); |
130 | 154 | }; |
0 commit comments