tdlib / td

Cross-platform library for building Telegram clients
https://core.telegram.org/tdlib
Boost Software License 1.0
6.91k stars 1.42k forks source link

How can I pass waveform data to voice files? #2370

Closed devhome98 closed 1 year ago

devhome98 commented 1 year ago

Hello Based on this post https://github.com/tdlib/td/issues/346, I have decoded this waveform data ("MQAAAAgCgBACCCCAAIIIIYAQQgghhBBCACCEEEIIIYQQQhAihBBECEGIEIQQQwQQAgAhiCBCACGEAEAIIYQA") and splitted it into 5 bit formats like this: [ 6, 4, 0, 0, 0, 0, 0, 8, 0, 10, 0, 1, 0, 0, 16, 8, 4, 2, 0, 0, 1, 0, 16, 8, 4, 6, 0, 1, 0, 16, 16, 8, 4, 6, 2, 1, 0, 16, 16, 0, 4, 2, 2, 1, 0, 16, 16, 8, 4, 6, 2, 1, 0, 16, 16, 16, 4, 10, 2, 1, 0, 17, 0, 8, 8, 6, 4, 1, 1, 1, 0, 16, 8, 12, 2, 1, 0, 0, 16, 0, 4, 6, 4, 2, 0, 16, 16, 0, 4, 6, 2, 0, 0, 16, 0, 8, 4, 6, 2, 0, ] and I change this array of decimal numbers into bytes and pass it to the waveform as data but it does not work.

Please someone help me, I do not know reallly what you mean by 5-bit format. There is only one method in nodejs to change data into bytes which is Buffer.from(data) and I do not know where to tell it to do in 5-bit format

levlam commented 1 year ago

In JSON interface all fields of the type bytes are base64-encoded.

devhome98 commented 1 year ago

Dear I updated the question, please help me in more detail.

levlam commented 1 year ago

You must base64-decode received string to a binary blob and then split it by 5-bit ranges to get the waveform. For the opposite conversion of the list of 0-31 heights, you must fill bits of a binary blob using values of the heights and base64-encode it before you can pass it in JSON as waveform.

devhome98 commented 1 year ago

I am doing it like this: waveform: Buffer.from( new Uint8Array([ [ 6, 4, 0, 0, 0, 0, 0, 8, 0, 10, 0, 1, 0, 0, 16, 8, 4, 2, 0, 0, 1, 0, 16, 8, 4, 6, 0, 1, 0, 16, 16, 8, 4, 6, 2, 1, 0, 16, 16, 0, 4, 2, 2, 1, 0, 16, 16, 8, 4, 6, 2, 1, 0, 16, 16, 16, 4, 10, 2, 1, 0, 17, 0, 8, 8, 6, 4, 1, 1, 1, 0, 16, 8, 12, 2, 1, 0, 0, 16, 0, 4, 6, 4, 2, 0, 16, 16, 0, 4, 6, 2, 0, 0, 16, 0, 8, 4, 6, 2, 0, 0, ], ]) ).toString("base64")

but it does not work

levlam commented 1 year ago

You need to first pack the numbers 0-31 into a binary blob in a such way that each number defines the next 5 bit of the string. new Uint8Array(...) ads 3 zero bits after each number instead.

devhome98 commented 1 year ago

Could you please write the complete code of that process? I have tried a lot but could not do it.

levlam commented 1 year ago

You can find JavaScript code for conversion of waveform to a list of numbers at https://github.com/evgeny-nadymov/telegram-react/blob/afd90f19b264895806359c23f985edccda828aca/src/Utils/Media.js#L34-L56, https://github.com/morethanwords/tweb/blob/205f5e9decc19562589d24471bfca93070aede7b/src/components/audio.ts#L51-L77, or https://github.com/Ajaxy/telegram-tt/blob/b41827d2919ae80d5853d610bcc464e1f15aedb0/src/util/waveform.ts#L4-L33.

I can't find the opposite code in the official Telegram Web apps.