async def record_and_send_opus_and_stop(gc: GroupCall):
    chat_id = int(f'-100{gc.full_chat.id}')
    chat_info = await gc.client.get_chat(chat_id)

    status_msg = await gc.client.send_message(chat_id, '1/3 Recording...')

    utcnow_unix, utcnow_readable = get_utcnow()
    record_raw_filename, record_opus_filename = f'vcrec-{utcnow_unix}.raw', f'vcrec-{utcnow_unix}.opus'
    gc.output_filename = record_raw_filename

    await asyncio.sleep(SECONDS_TO_RECORD)
    gc.stop_output()

    await status_msg.edit_text('2/3 Transcoding...')
    ffmpeg.input(record_raw_filename,
                 format='s16le',
                 acodec='pcm_s16le',
                 ac=2,
                 ar='48k',
                 loglevel='error').output(
                     record_opus_filename).overwrite_output().run()

    record_probe = ffmpeg.probe(record_opus_filename, pretty=None)

    stream = record_probe['streams'][0]
    time_base = [int(x) for x in stream['time_base'].split('/')]
    duration = round(time_base[0] / time_base[1] * int(stream['duration_ts']))

    caption = [
        f'- Format: `{stream["codec_name"]}`',
        f'- Channel(s): `{stream["channels"]}`',
        f'- Sampling rate: `{stream["sample_rate"]}`',
        f'- Bit rate: `{record_probe["format"]["bit_rate"]}`',
        f'- File size: `{record_probe["format"]["size"]}`',
    ]

    performer = chat_info.title
    if chat_info.username:
        performer = f'@{chat_info.username}'

    title = f'[VCREC] {utcnow_readable}'
    thumb_file = await gc.client.download_media(chat_info.photo.big_file_id)

    await status_msg.edit_text('3/3 Uploading...')
    await gc.client.send_audio(chat_id,
                               record_opus_filename,
                               caption='\n'.join(caption),
                               duration=duration,
                               performer=performer,
                               title=title,
                               thumb=thumb_file)
    await status_msg.delete()

    await gc.stop()
    [
        os.remove(f)
        for f in (record_raw_filename, record_opus_filename, thumb_file)
    ]
Пример #2
0
async def record_audio(client, message: Message):
    download_dir = os.path.join(client.workdir, DEFAULT_DOWNLOAD_DIR)
    Path(download_dir).mkdir(parents=True, exist_ok=True)
    record_raw = os.path.join(download_dir, "output.raw")
    if message.reply_to_message:
        duration = 60
    else:
        duration = 15
    chat = message.chat
    if not VOICE_CHATS or chat.id not in VOICE_CHATS:
        group_call = GroupCall(client)
        await group_call.start(chat.id, False)
        VOICE_CHATS[chat.id] = group_call
        status = (
            "\n- Joined the Voice Chat, send the command again to record")
        await update_userbot_message(message, message.text, status)
        return
    status = ("\n- recording...")
    await update_userbot_message(message, message.text, status)
    group_call = VOICE_CHATS[chat.id]
    group_call.output_filename = record_raw
    time_record = datetime.utcnow()
    task = asyncio.create_task(asyncio.sleep(duration))
    time_spent = 0
    while not task.done():
        await asyncio.sleep(10)
        time_spent += 10
        await update_userbot_message(message, message.text,
                                     f"{status} **{time_spent}/{duration}**")
    group_call.stop_output()
    status += "\n- transcoding..."
    record_opus = os.path.join(download_dir,
                               f"vcrec-{time_record.strftime('%s')}.opus")
    await update_userbot_message(message, message.text, status)
    ffmpeg.input(record_raw,
                 format='s16le',
                 acodec='pcm_s16le',
                 ac=2,
                 ar='48k').output(record_opus).overwrite_output().run()
    # ffmpeg -y -f s16le -ac 2 -ar 48000 -acodec pcm_s16le \
    # -i output.raw record.opus
    duration = int(float(ffmpeg.probe(record_opus)['format']['duration']))
    # sox {record_opus} -t raw -r 44100 -e float -c 1 - | bpm -f '%0.0f'
    # sox -t raw -r 48000 -e signed -b 16 -c 2 \
    # output.raw -t raw -r 44100 -e float -c 1 - | bpm -f '%0.0f'
    bpm = subprocess.getoutput(
        f"opusdec --quiet --rate 44100 --float {record_opus} - "
        "| bpm -f '%0.0f'")
    probe = ffmpeg.probe(record_opus, pretty=None)
    time_record_readable = time_record.strftime('%Y-%m-%d %H:%M:%S')
    title = f"[VCREC] {time_record_readable}"
    caption = (f"- BPM: `{bpm}`\n"
               f"- Format: `{probe['streams'][0]['codec_name']}`\n"
               f"- Channel(s): `{str(probe['streams'][0]['channels'])}`\n"
               f"- Sampling rate: `{probe['streams'][0]['sample_rate']}`\n"
               f"- Bit rate: `{probe['format']['bit_rate']}`\n"
               f"- File size: `{probe['format']['size']}`")
    status += "\n- uploading..."
    await update_userbot_message(message, message.text, status)
    thumb = await client.download_media(chat.photo.big_file_id)
    performer = (f"@{chat.username}" if chat.username else chat.title)
    await message.reply_audio(record_opus,
                              quote=False,
                              caption=caption,
                              duration=duration,
                              performer=performer,
                              title=title,
                              thumb=thumb)
    for f in [record_opus, thumb]:
        os.remove(f)
    open(record_raw, 'w').close()