Automatic audio duration fetch

This commit is contained in:
Adhiraj Singh
2020-10-22 20:23:35 +05:30
parent ea91c807f4
commit a72ed7272d
6 changed files with 195 additions and 8 deletions

View File

@@ -57,14 +57,16 @@ WAConnectionTest('Messages', conn => {
})
it('should send an audio', async () => {
const content = await fs.readFile('./Media/sonata.mp3')
const message = await sendAndRetreiveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.ogg })
const message = await sendAndRetreiveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.mp4Audio })
// check duration was okay
assert.ok (message.message.audioMessage.seconds > 0)
await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud')
})
it('should send an audio as a voice note', async () => {
const content = await fs.readFile('./Media/sonata.mp3')
const message = await sendAndRetreiveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.ogg, ptt: true })
const message = await sendAndRetreiveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.mp4Audio, ptt: true })
assert.ok (message.message.audioMessage.seconds > 0)
assert.equal (message.message?.audioMessage?.ptt, true)
await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud')
})

View File

@@ -11,7 +11,7 @@ import {
WATextMessage,
WAMessageContent, WAMetric, WAFlag, WAMessage, BaileysError, WA_MESSAGE_STATUS_TYPE, WAMessageProto, MediaConnInfo, MessageTypeProto, URL_REGEX, WAUrlInfo
} from './Constants'
import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes, generateThumbnail, getMediaKeys, decodeMediaMessageBuffer, extensionForMediaMessage, whatsappID, unixTimestampSeconds } from './Utils'
import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes, generateThumbnail, getMediaKeys, decodeMediaMessageBuffer, extensionForMediaMessage, whatsappID, unixTimestampSeconds, getAudioDuration } from './Utils'
import { Mutex } from './Mutex'
export class WAConnection extends Base {
@@ -117,8 +117,14 @@ export class WAConnection extends Base {
.replace(/\//g, '_')
.replace(/\=+$/, '')
)
await generateThumbnail(buffer, mediaType, options)
if (mediaType === MessageType.audio && !options.duration) {
try {
options.duration = await getAudioDuration (buffer)
} catch (error) {
this.logger.debug ({ error }, 'failed to obtain audio duration: ' + error.message)
}
}
// send a query JSON to obtain the url & auth token to upload our media
let json = await this.refreshMediaConn (options.forceNewMediaOptions)
@@ -154,6 +160,7 @@ export class WAConnection extends Base {
fileEncSha256: fileEncSha256,
fileSha256: fileSha256,
fileLength: buffer.length,
seconds: options.duration,
fileName: options.filename || 'file',
gifPlayback: isGIF || undefined,
caption: options.caption,

View File

@@ -333,6 +333,8 @@ export interface MessageOptions {
uploadAgent?: Agent
/** If set to true (default), automatically detects if you're sending a link & attaches the preview*/
detectLinks?: boolean
/** Optionally specify the duration of the media (audio/video) in seconds */
duration?: number
/** Fetches new media options for every media file */
forceNewMediaOptions?: boolean
}

View File

@@ -7,9 +7,11 @@ import {platform, release} from 'os'
import HttpsProxyAgent from 'https-proxy-agent'
import { URL } from 'url'
import { Agent } from 'https'
import { getAudioDurationInSeconds } from 'get-audio-duration'
import mp3Duration from 'mp3-duration'
import Decoder from '../Binary/Decoder'
import { MessageType, HKDFInfoKeys, MessageOptions, WAChat, WAMessageContent, BaileysError, WAMessageProto, TimedOutError, CancelledError, WAGenericMediaMessage, WAMessage, WAMessageKey } from './Constants'
import { Readable } from 'stream'
const platformMap = {
'aix': 'AIX',
@@ -231,6 +233,16 @@ export const mediaMessageSHA256B64 = (message: WAMessageContent) => {
const media = Object.values(message)[0] as WAGenericMediaMessage
return media?.fileSha256 && Buffer.from(media.fileSha256).toString ('base64')
}
export async function getAudioDuration (buffer: Buffer) {
let duration: number
try {
duration = await mp3Duration (buffer)
} catch {
const readable = new Readable({ read () { this.push(buffer); this.push (null) } })
duration = await getAudioDurationInSeconds (readable)
}
return duration
}
/** generates a thumbnail for a given media, if required */
export async function generateThumbnail(buffer: Buffer, mediaType: MessageType, info: MessageOptions) {