Created
November 15, 2024 20:24
-
-
Save abrorbekuz/76e434335b4bf20448a1a583cf91d8fb to your computer and use it in GitHub Desktop.
wo&man
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import telebot | |
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton | |
import os | |
from pydub import AudioSegment | |
import librosa | |
import soundfile as sf | |
import tempfile | |
import time | |
API_TOKEN = "<TOKEN>" | |
bot = telebot.TeleBot(API_TOKEN) | |
TEMP_DIR = "temp_audio" | |
os.makedirs(TEMP_DIR, exist_ok=True) | |
def process_audio(file_path, pitch_steps, progress_message): | |
progress_message("Processing: Converting to WAV...", 10) | |
audio = AudioSegment.from_file(file_path) | |
wav_file = os.path.join(TEMP_DIR, "temp_audio.wav") | |
audio.export(wav_file, format="wav") | |
progress_message("WAV Conversion Complete!", 20) | |
audio_data, sample_rate = librosa.load(wav_file) | |
progress_message("Processing: Shifting pitch...", 50) | |
shifted_audio = librosa.effects.pitch_shift(audio_data, sr=sample_rate, n_steps=pitch_steps) | |
progress_message("Pitch Shift Complete!", 70) | |
shifted_wav = os.path.join(TEMP_DIR, "shifted_audio.wav") | |
sf.write(shifted_wav, shifted_audio, sample_rate) | |
progress_message("Processing: Converting back to MP3...", 90) | |
processed_file = os.path.join(TEMP_DIR, "processed_audio.mp3") | |
output_audio = AudioSegment.from_wav(shifted_wav) | |
output_audio.export(processed_file, format="mp3") | |
os.remove(wav_file) | |
os.remove(shifted_wav) | |
progress_message("Processing complete!", 100) | |
return processed_file | |
@bot.message_handler(commands=["start"]) | |
def start_message(message): | |
bot.reply_to(message, "Hi! Upload an audio file, and then select pitch adjustment:\n" | |
"1. Choose Masculine or Feminine.\n" | |
"2. Select a zoom range.\n" | |
"3. Pick the exact pitch value.") | |
@bot.message_handler(content_types=["audio", "voice", "document"]) | |
def handle_audio(message): | |
file_info = bot.get_file(message.audio.file_id if message.content_type == "audio" else message.document.file_id) | |
downloaded_file = bot.download_file(file_info.file_path) | |
file_path = os.path.join(TEMP_DIR, f"{message.id}_input_audio") | |
with open(file_path, "wb") as f: | |
f.write(downloaded_file) | |
bot.reply_to(message, "Audio received! Now select Masculine or Feminine:", | |
reply_markup=create_gender_keyboard(message.message_id)) | |
def create_gender_keyboard(message_id): | |
markup = InlineKeyboardMarkup() | |
markup.row( | |
InlineKeyboardButton("Masculine", callback_data=f"gender_masculine_{message_id}"), | |
InlineKeyboardButton("Feminine", callback_data=f"gender_feminine_{message_id}") | |
) | |
return markup | |
@bot.callback_query_handler(func=lambda call: call.data.startswith("gender_")) | |
def handle_gender_selection(call): | |
gender, message_id = call.data.split("_")[1], call.data.split("_")[2] | |
bot.answer_callback_query(call.id, f"Selected: {gender.capitalize()}") | |
bot.edit_message_text("Select a zoom range:", chat_id=call.message.chat.id, message_id=call.message.id, | |
reply_markup=create_zoom_range_keyboard(gender, message_id)) | |
def create_zoom_range_keyboard(gender, message_id): | |
markup = InlineKeyboardMarkup() | |
ranges = [("2–4", "2_4"), ("4–6", "4_6"), ("6–8", "6_8")] | |
if len(ranges) <= 4: | |
markup.row(*[InlineKeyboardButton(label, callback_data=f"zoom_{gender}_{data}_{message_id}") for label, data in ranges]) | |
else: | |
for label, data in ranges: | |
markup.add(InlineKeyboardButton(label, callback_data=f"zoom_{gender}_{data}_{message_id}")) | |
return markup | |
@bot.callback_query_handler(func=lambda call: call.data.startswith("zoom_")) | |
def handle_zoom_range_selection(call): | |
_, gender, start, end, message_id = call.data.split("_") | |
start, end = int(start), int(end) | |
precise_values = [round(x, 1) for x in frange(start, end, 0.3)] | |
bot.edit_message_text("Select a precise pitch value:", chat_id=call.message.chat.id, message_id=call.message.id, | |
reply_markup=create_precise_pitch_keyboard(gender, precise_values, message_id)) | |
def create_precise_pitch_keyboard(gender, values, message_id): | |
markup = InlineKeyboardMarkup() | |
if len(values) <= 4: | |
markup.row(*[InlineKeyboardButton(str(value), callback_data=f"pitch_{gender}_{value}_{message_id}") for value in values]) | |
else: | |
for value in values: | |
markup.add(InlineKeyboardButton(str(value), callback_data=f"pitch_{gender}_{value}_{message_id}")) | |
return markup | |
@bot.callback_query_handler(func=lambda call: call.data.startswith("pitch_")) | |
def handle_precise_pitch_selection(call): | |
_, gender, pitch_value, message_id = call.data.split("_") | |
pitch_value = float(pitch_value) | |
if gender == "masculine": | |
pitch_value = -pitch_value | |
input_file_path = os.path.join(TEMP_DIR, f"{message_id}_input_audio") | |
if not os.path.exists(input_file_path): | |
bot.answer_callback_query(call.id, "File not found! Please upload a file first.") | |
return | |
def progress_message(status, percentage): | |
bot.edit_message_text(f"{status}\nProgress: {percentage}%", chat_id=call.message.chat.id, | |
message_id=call.message.id) | |
processed_file = process_audio(input_file_path, pitch_value, progress_message) | |
with open(processed_file, "rb") as audio: | |
bot.send_audio(call.message.chat.id, audio) | |
os.remove(input_file_path) | |
os.remove(processed_file) | |
bot.send_message(call.message.chat.id, "Here is your modified audio!") | |
def frange(start, stop, step): | |
while start <= stop: | |
yield start | |
start += step | |
print("Bot is running...") | |
bot.infinity_polling(skip_pending=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment