Search code examples
pythontelegrampython-telegram-bot

python-telegram-bot send_voice sends empty file


I am trying to send a voice message using a local OGG file. The voice message is sent but when trying to play the file in telegram it seems empty. Any idea why ? Here is the code I'm using :

async def audio_received(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_voice(
        chat_id=update.effective_chat.id, voice=open("sample-3.ogg", "rb")
    )

if __name__ == "__main__":
    application = (
        ApplicationBuilder()
        .token("MY_TOKEN")
        .build()
    )
    audio_handler = MessageHandler(filters.VOICE, audio_received)
    application.add_handler(audio_handler)
    application.run_polling()

Thanks a lot for your help!


Solution

  • As per Telegram's documentation on sendVoice, the audio files should satisfy the following:

    • be an .ogg file,
    • be encoded with OPUS,
    • have a size below 50MB (could change), and,
    • according to this answer, have a bitrate from 32kb to 64kb.

    Since you mentioned that the encoding might have solved this issue, I will take the answer again from this answer:

    async def audio_received(update: Update, context: ContextTypes.DEFAULT_TYPE):
        # ffmpeg -i sample-3.ogg -loglevel panic \
        #        -c:a libopus -b:a 32k -vbr on \
        #        -compression_level 10 -frame_duration 60 -application voip \
        #        output.ogg
        subprocess.run([
            'ffmpeg', '-i', 'sample-3.ogg', '-loglevel', 'panic',
            '-c:a', 'libopus', '-b:a', '32k', '-vbr', 'on',
            '-compression_level', '10', '-frame_duration', '60', '-application', 'voip',
            'output.ogg', '-y' # -y confirms overriding files with the same name
        ])
        await context.bot.send_voice(
            chat_id=update.effective_chat.id, voice=open("output.ogg", "rb")
        )