Skip to content

Commit 01ae55f

Browse files
committed
fix: Fixed getBase64FromMediaMessage with convertToMp4
1 parent 97f633a commit 01ae55f

File tree

2 files changed

+78
-54
lines changed

2 files changed

+78
-54
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* Fixed send message to group without no cache (local or redis)
2626
* Fixed startTypebot with startSession = true
2727
* Fixed issue of always creating a new label when saving chatwoot
28+
* Fixed getBase64FromMediaMessage with convertToMp4
2829

2930
# 2.1.1 (2024-09-22 10:31)
3031

src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Lines changed: 77 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ import makeWASocket, {
113113
} from 'baileys';
114114
import { Label } from 'baileys/lib/Types/Label';
115115
import { LabelAssociation } from 'baileys/lib/Types/LabelAssociation';
116+
import { spawn } from 'child_process';
116117
import { isBase64, isURL } from 'class-validator';
117118
import { randomBytes } from 'crypto';
118119
import EventEmitter2 from 'eventemitter2';
@@ -2454,53 +2455,69 @@ export class BaileysStartupService extends ChannelStartupService {
24542455
}
24552456

24562457
public async processAudioMp4(audio: string) {
2457-
let inputAudioStream: PassThrough;
2458+
let inputStream: PassThrough;
24582459

24592460
if (isURL(audio)) {
2460-
const timestamp = new Date().getTime();
2461-
const url = `${audio}?timestamp=${timestamp}`;
2462-
2463-
const config: any = {
2464-
responseType: 'stream',
2465-
};
2466-
2467-
const response = await axios.get(url, config);
2468-
inputAudioStream = response.data.pipe(new PassThrough());
2461+
const response = await axios.get(audio, { responseType: 'stream' });
2462+
inputStream = response.data;
24692463
} else {
24702464
const audioBuffer = Buffer.from(audio, 'base64');
2471-
inputAudioStream = new PassThrough();
2472-
inputAudioStream.end(audioBuffer);
2473-
}
2474-
2475-
return new Promise((resolve, reject) => {
2476-
const outputAudioStream = new PassThrough();
2477-
const chunks: Buffer[] = [];
2465+
inputStream = new PassThrough();
2466+
inputStream.end(audioBuffer);
2467+
}
2468+
2469+
return new Promise<Buffer>((resolve, reject) => {
2470+
const ffmpegProcess = spawn(ffmpegPath.path, [
2471+
'-i',
2472+
'pipe:0',
2473+
'-vn',
2474+
'-ab',
2475+
'128k',
2476+
'-ar',
2477+
'44100',
2478+
'-f',
2479+
'mp4',
2480+
'-movflags',
2481+
'frag_keyframe+empty_moov',
2482+
'pipe:1',
2483+
]);
2484+
2485+
const outputChunks: Buffer[] = [];
2486+
let stderrData = '';
2487+
2488+
ffmpegProcess.stdout.on('data', (chunk) => {
2489+
outputChunks.push(chunk);
2490+
});
24782491

2479-
outputAudioStream.on('data', (chunk) => chunks.push(chunk));
2480-
outputAudioStream.on('end', () => {
2481-
const outputBuffer = Buffer.concat(chunks);
2482-
resolve(outputBuffer);
2492+
ffmpegProcess.stderr.on('data', (data) => {
2493+
stderrData += data.toString();
2494+
this.logger.verbose(`ffmpeg stderr: ${data}`);
24832495
});
24842496

2485-
outputAudioStream.on('error', (error) => {
2486-
console.log('error', error);
2497+
ffmpegProcess.on('error', (error) => {
2498+
console.error('Error in ffmpeg process', error);
24872499
reject(error);
24882500
});
24892501

2490-
ffmpeg.setFfmpegPath(ffmpegPath.path);
2502+
ffmpegProcess.on('close', (code) => {
2503+
if (code === 0) {
2504+
this.logger.verbose('Audio converted to mp4');
2505+
const outputBuffer = Buffer.concat(outputChunks);
2506+
resolve(outputBuffer);
2507+
} else {
2508+
this.logger.error(`ffmpeg exited with code ${code}`);
2509+
this.logger.error(`ffmpeg stderr: ${stderrData}`);
2510+
reject(new Error(`ffmpeg exited with code ${code}: ${stderrData}`));
2511+
}
2512+
});
24912513

2492-
ffmpeg(inputAudioStream)
2493-
.outputFormat('mp4')
2494-
.noVideo()
2495-
.audioCodec('aac')
2496-
.audioBitrate('128k')
2497-
.audioFrequency(44100)
2498-
.addOutputOptions('-f ipod')
2499-
.pipe(outputAudioStream, { end: true })
2500-
.on('error', function (error) {
2501-
console.log('error', error);
2502-
reject(error);
2503-
});
2514+
inputStream.pipe(ffmpegProcess.stdin);
2515+
2516+
inputStream.on('error', (err) => {
2517+
console.error('Error in inputStream', err);
2518+
ffmpegProcess.stdin.end();
2519+
reject(err);
2520+
});
25042521
});
25052522
}
25062523

@@ -2995,28 +3012,33 @@ export class BaileysStartupService extends ChannelStartupService {
29953012
const typeMessage = getContentType(msg.message);
29963013

29973014
const ext = mime.getExtension(mediaMessage?.['mimetype']);
2998-
29993015
const fileName = mediaMessage?.['fileName'] || `${msg.key.id}.${ext}` || `${v4()}.${ext}`;
30003016

30013017
if (convertToMp4 && typeMessage === 'audioMessage') {
3002-
const convert = await this.processAudioMp4(buffer.toString('base64'));
3003-
3004-
if (Buffer.isBuffer(convert)) {
3005-
const result = {
3006-
mediaType,
3007-
fileName,
3008-
caption: mediaMessage['caption'],
3009-
size: {
3010-
fileLength: mediaMessage['fileLength'],
3011-
height: mediaMessage['height'],
3012-
width: mediaMessage['width'],
3013-
},
3014-
mimetype: 'audio/mp4',
3015-
base64: convert,
3016-
buffer: getBuffer ? convert : null,
3017-
};
3018+
try {
3019+
const convert = await this.processAudioMp4(buffer.toString('base64'));
3020+
3021+
if (Buffer.isBuffer(convert)) {
3022+
const result = {
3023+
mediaType,
3024+
fileName,
3025+
caption: mediaMessage['caption'],
3026+
size: {
3027+
fileLength: mediaMessage['fileLength'],
3028+
height: mediaMessage['height'],
3029+
width: mediaMessage['width'],
3030+
},
3031+
mimetype: 'audio/mp4',
3032+
base64: convert.toString('base64'),
3033+
buffer: getBuffer ? convert : null,
3034+
};
30183035

3019-
return result;
3036+
return result;
3037+
}
3038+
} catch (error) {
3039+
this.logger.error('Error converting audio to mp4:');
3040+
this.logger.error(error);
3041+
throw new BadRequestException('Failed to convert audio to MP4');
30203042
}
30213043
}
30223044

@@ -3034,6 +3056,7 @@ export class BaileysStartupService extends ChannelStartupService {
30343056
buffer: getBuffer ? buffer : null,
30353057
};
30363058
} catch (error) {
3059+
this.logger.error('Error processing media message:');
30373060
this.logger.error(error);
30383061
throw new BadRequestException(error.toString());
30393062
}

0 commit comments

Comments
 (0)